Merge branch 'upstream' into merge_2

Conflicts:
	lib/Sema/SemaDeclAttr.cpp

Change-Id: If47d0d39459760017258502b4d9e859ac36a273b
diff --git a/.gitignore b/.gitignore
index ddd6638..b906ab9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,9 @@
 #==============================================================================#
 cscope.files
 cscope.out
+
+#==============================================================================#
+# Directories to ignore (do not add trailing '/'s, they skip symlinks).
+#==============================================================================#
+# Clang extra user tools, which is tracked independently (clang-tools-extra).
+tools/extra
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 29661fc..2f4fa1c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -139,6 +139,10 @@
   set(CMAKE_MODULE_LINKER_FLAGS "-Wl,-flat_namespace -Wl,-undefined -Wl,suppress")
 endif ()
 
+# libxml2 is an optional dependency, required only to run validation
+# tests on XML output.
+find_package(LibXml2)
+
 configure_file(
   ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake
   ${CLANG_BINARY_DIR}/include/clang/Config/config.h)
@@ -250,14 +254,14 @@
 
 add_subdirectory(utils/TableGen)
 
-option(CLANG_BUILD_EXAMPLES "Build CLANG example programs by default." OFF)
-add_subdirectory(examples)
-
 add_subdirectory(include)
 add_subdirectory(lib)
 add_subdirectory(tools)
 add_subdirectory(runtime)
 
+option(CLANG_BUILD_EXAMPLES "Build CLANG example programs by default." OFF)
+add_subdirectory(examples)
+
 # TODO: docs.
 add_subdirectory(test)
 
@@ -278,3 +282,4 @@
 
 set(BUG_REPORT_URL "http://llvm.org/bugs/" CACHE STRING
   "Default URL where bug reports are to be submitted.")
+
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index fc0a2a1..628ade1 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -133,6 +133,31 @@
 
 ### Structures and Utility Classes ###
 
+class CachedProperty(object):
+    """Decorator that lazy-loads the value of a property.
+
+    The first time the property is accessed, the original property function is
+    executed. The value it returns is set as the new value of that instance's
+    property, replacing the original method.
+    """
+
+    def __init__(self, wrapped):
+        self.wrapped = wrapped
+        try:
+            self.__doc__ = wrapped.__doc__
+        except:
+            pass
+
+    def __get__(self, instance, instance_type=None):
+        if instance is None:
+            return self
+
+        value = self.wrapped(instance)
+        setattr(instance, self.wrapped.__name__, value)
+
+        return value
+
+
 class _CXString(Structure):
     """Helper for transforming CXString results."""
 
@@ -1632,16 +1657,16 @@
     def __repr__(self):
         return "{'" + self.spelling + "', " + str(self.kind) + "}"
 
-    @property
+    @CachedProperty
     def spelling(self):
         return lib.clang_getCompletionChunkText(self.cs, self.key).spelling
 
-    @property
+    @CachedProperty
     def kind(self):
         res = lib.clang_getCompletionChunkKind(self.cs, self.key)
         return completionChunkKindMap[res]
 
-    @property
+    @CachedProperty
     def string(self):
         res = lib.clang_getCompletionChunkCompletionString(self.cs, self.key)
 
@@ -1700,10 +1725,14 @@
             return "<Availability: %s>" % self
 
     def __len__(self):
+        self.num_chunks
+
+    @CachedProperty
+    def num_chunks(self):
         return lib.clang_getNumCompletionChunks(self.obj)
 
     def __getitem__(self, key):
-        if len(self) <= key:
+        if self.num_chunks <= key:
             raise IndexError
         return CompletionChunk(self.obj, key)
 
@@ -1762,7 +1791,7 @@
         return self._as_parameter_
 
     def __del__(self):
-        CodeCompletionResults_dispose(self)
+        lib.clang_disposeCodeCompleteResults(self)
 
     @property
     def results(self):
diff --git a/bindings/xml/comment-xml-schema.rng b/bindings/xml/comment-xml-schema.rng
new file mode 100644
index 0000000..a0329f8
--- /dev/null
+++ b/bindings/xml/comment-xml-schema.rng
@@ -0,0 +1,434 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<grammar xmlns="http://relaxng.org/ns/structure/1.0"
+         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
+
+  <start>
+    <choice>
+      <!-- Everything else not explicitly mentioned below. -->
+      <ref name="Other" />
+
+      <ref name="Function" />
+      <ref name="Class" />
+      <ref name="Variable" />
+      <ref name="Namespace" />
+      <ref name="Typedef" />
+      <ref name="Enum" />
+    </choice>
+  </start>
+
+  <define name="Other">
+    <element name="Other">
+      <ref name="attrSourceLocation" />
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="Function">
+    <element name="Function">
+      <optional>
+        <attribute name="templateKind">
+          <choice>
+            <value>template</value>
+            <value>specialization</value>
+          </choice>
+        </attribute>
+      </optional>
+      <ref name="attrSourceLocation" />
+
+      <optional>
+        <attribute name="isInstanceMethod">
+          <data type="boolean" />
+        </attribute>
+      </optional>
+      <optional>
+        <attribute name="isClassMethod">
+          <data type="boolean" />
+        </attribute>
+      </optional>
+
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <!-- TODO: Add exception specification. -->
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="Class">
+    <element name="Class">
+      <optional>
+        <attribute name="templateKind">
+          <choice>
+            <value>template</value>
+            <value>specialization</value>
+            <value>partialSpecialization</value>
+          </choice>
+        </attribute>
+      </optional>
+      <ref name="attrSourceLocation" />
+
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+
+      <!-- Parameters and results don't make sense for classes, but the user
+           can specify \param or \returns in a comment anyway. -->
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="Variable">
+    <element name="Variable">
+      <ref name="attrSourceLocation" />
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+
+      <!-- Template parameters, parameters and results don't make sense for
+            variables, but the user can specify \tparam \param or \returns
+            in a comment anyway. -->
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="Namespace">
+    <element name="Namespace">
+      <ref name="attrSourceLocation" />
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+
+      <!-- Template parameters, parameters and results don't make sense for
+           namespaces, but the user can specify \tparam, \param or \returns
+           in a comment anyway. -->
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="Typedef">
+    <element name="Typedef">
+      <ref name="attrSourceLocation" />
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+
+      <!-- Parameters and results might make sense for typedefs if the type is
+           a function pointer type. -->
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="Enum">
+    <element name="Enum">
+      <ref name="attrSourceLocation" />
+      <ref name="Name" />
+      <optional>
+        <ref name="USR" />
+      </optional>
+      <optional>
+        <ref name="Abstract" />
+      </optional>
+
+      <!-- Template parameters, parameters and results don't make sense for
+            enums, but the user can specify \tparam \param or \returns in a
+            comment anyway. -->
+      <optional>
+        <ref name="TemplateParameters" />
+      </optional>
+      <optional>
+        <ref name="Parameters" />
+      </optional>
+      <optional>
+        <ref name="ResultDiscussion" />
+      </optional>
+
+      <optional>
+        <ref name="Discussion" />
+      </optional>
+    </element>
+  </define>
+
+  <define name="attrSourceLocation">
+    <optional>
+      <attribute name="file">
+        <!-- Non-empty text content. -->
+        <data type="string">
+          <param name="pattern">.*\S.*</param>
+        </data>
+      </attribute>
+    </optional>
+    <optional>
+      <attribute name="line">
+        <data type="positiveInteger" />
+      </attribute>
+      <attribute name="column">
+        <data type="positiveInteger" />
+      </attribute>
+    </optional>
+  </define>
+
+  <define name="Name">
+    <element name="Name">
+      <!-- Non-empty text content. -->
+      <data type="string">
+        <param name="pattern">.*\S.*</param>
+      </data>
+    </element>
+  </define>
+
+  <define name="USR">
+    <element name="USR">
+      <!-- Non-empty text content. -->
+      <data type="string">
+        <param name="pattern">.*\S.*</param>
+      </data>
+    </element>
+  </define>
+
+  <define name="Abstract">
+    <element name="Abstract">
+      <zeroOrMore>
+        <ref name="TextBlockContent" />
+      </zeroOrMore>
+    </element>
+  </define>
+
+  <define name="Discussion">
+    <element name="Discussion">
+      <oneOrMore>
+        <ref name="TextBlockContent" />
+      </oneOrMore>
+    </element>
+  </define>
+
+  <define name="TemplateParameters">
+    <element name="TemplateParameters">
+      <!-- Parameter elements should be sorted according to position. -->
+      <oneOrMore>
+        <element name="Parameter">
+          <element name="Name">
+            <!-- Non-empty text content. -->
+            <data type="string">
+              <param name="pattern">.*\S.*</param>
+            </data>
+          </element>
+          <optional>
+            <!-- This is index at depth 0.  libclang API can return more
+                 information about position, but we expose only essential
+                 information here, since "Parameter" elements are already
+                 sorted.
+
+                 "Position" element could be added in future if needed.  -->
+            <element name="Index">
+              <data type="nonNegativeInteger" />
+            </element>
+          </optional>
+          <!-- In general, template parameters with whitespace discussion
+               should not be emitted.  Schema might be more strict here. -->
+          <element name="Discussion">
+            <ref name="TextBlockContent" />
+          </element>
+        </element>
+      </oneOrMore>
+    </element>
+  </define>
+
+  <define name="Parameters">
+    <element name="Parameters">
+      <!-- Parameter elements should be sorted according to index. -->
+      <oneOrMore>
+        <element name="Parameter">
+          <element name="Name">
+            <!-- Non-empty text content. -->
+            <data type="string">
+              <param name="pattern">.*\S.*</param>
+            </data>
+          </element>
+          <optional>
+            <element name="Index">
+              <data type="nonNegativeInteger" />
+            </element>
+          </optional>
+          <element name="Direction">
+            <attribute name="isExplicit">
+              <data type="boolean" />
+            </attribute>
+            <choice>
+              <value>in</value>
+              <value>out</value>
+              <value>in,out</value>
+            </choice>
+          </element>
+          <!-- In general, template parameters with whitespace discussion
+               should not be emitted, unless direction is explicitly specified.
+               Schema might be more strict here. -->
+          <element name="Discussion">
+            <ref name="TextBlockContent" />
+          </element>
+        </element>
+      </oneOrMore>
+    </element>
+  </define>
+
+  <define name="ResultDiscussion">
+    <element name="ResultDiscussion">
+      <zeroOrMore>
+        <ref name="TextBlockContent" />
+      </zeroOrMore>
+    </element>
+  </define>
+
+  <define name="TextBlockContent">
+    <choice>
+      <element name="Para">
+        <zeroOrMore>
+          <ref name="TextInlineContent" />
+        </zeroOrMore>
+      </element>
+      <element name="Verbatim">
+        <attribute name="xml:space">
+          <value>preserve</value>
+        </attribute>
+        <attribute name="kind">
+          <!-- TODO: add all Doxygen verbatim kinds -->
+          <choice>
+            <value>code</value>
+            <value>verbatim</value>
+          </choice>
+        </attribute>
+        <text />
+      </element>
+    </choice>
+  </define>
+
+  <define name="TextInlineContent">
+    <choice>
+      <text />
+      <element name="bold">
+        <!-- Non-empty text content. -->
+        <data type="string">
+          <param name="pattern">.*\S.*</param>
+        </data>
+      </element>
+      <element name="monospaced">
+        <!-- Non-empty text content. -->
+        <data type="string">
+          <param name="pattern">.*\S.*</param>
+        </data>
+      </element>
+      <element name="emphasized">
+        <!-- Non-empty text content. -->
+        <data type="string">
+          <param name="pattern">.*\S.*</param>
+        </data>
+      </element>
+      <element name="rawHTML">
+        <!-- Non-empty text content. -->
+        <data type="string">
+          <param name="pattern">.*\S.*</param>
+        </data>
+      </element>
+    </choice>
+  </define>
+
+</grammar>
+
diff --git a/docs/AutomaticReferenceCounting.html b/docs/AutomaticReferenceCounting.html
index 6d50cf7..2fd82dd 100644
--- a/docs/AutomaticReferenceCounting.html
+++ b/docs/AutomaticReferenceCounting.html
@@ -313,7 +313,7 @@
 <ul>
 <li>The type system must reliably identify which objects are to be
 managed.  An <tt>int*</tt> might be a pointer to a <tt>malloc</tt>'ed
-array, or it might be a interior pointer to such an array, or it might
+array, or it might be an interior pointer to such an array, or it might
 point to some field or local variable.  In contrast, values of the
 retainable object pointer types are never interior.</li>
 <li>The type system must reliably indicate how to
@@ -888,6 +888,15 @@
 banned the synthesis in order to give ourselves exactly this
 leeway.</p></div>
 
+<p>Applying <tt>__attribute__((NSObject))</tt> to a property not of
+retainable object pointer type has the same behavior it does outside
+of ARC:  it requires the property type to be some sort of pointer and
+permits the use of modifiers other than <tt>assign</tt>.  These
+modifiers only affect the synthesized getter and setter; direct
+accesses to the ivar (even if synthesized) still have primitive
+semantics, and the value in the ivar will not be automatically
+released during deallocation.</p>
+
 </div> <!-- ownership.spelling.property -->
 
 </div> <!-- ownership.spelling -->
diff --git a/docs/ClangTools.html b/docs/ClangTools.html
new file mode 100644
index 0000000..0dfdc6a
--- /dev/null
+++ b/docs/ClangTools.html
@@ -0,0 +1,118 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Clang Tools</title>
+<link type="text/css" rel="stylesheet" href="../menu.css">
+<link type="text/css" rel="stylesheet" href="../content.css">
+</head>
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>Clang Tools</h1>
+<p>Clang Tools are standalone command line (and potentially GUI) tools design
+for use by C++ developers who are already using and enjoying Clang as their
+compiler. These tools provide developer-oriented functionality such as fast
+syntax checking, automatic formatting, refactoring, etc.</p>
+
+<p>Only a couple of the most basic and fundamental tools are kept in the primary
+Clang Subversion project. The rest of the tools are kept in a side-project so
+that developers who don't want or need to build them don't. If you want to get
+access to the extra Clang Tools repository, simply check it out into the tools
+tree of your Clang checkout and follow the usual process for building and
+working with a combined LLVM/Clang checkout:</p>
+<ul>
+  <li>With Subversion:
+  <ul>
+    <li><tt>cd llvm/tools/clang/tools</tt></li>
+    <li><tt>svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk
+      extra</tt></li>
+  </ul>
+  </li>
+  <li>Or with Git:
+  <ul>
+    <li><tt>cd llvm/tools/clang/tools</tt></li>
+    <li><tt>git clone http://llvm.org/git/clang-tools-extra.git extra</tt></li>
+  </ul>
+  </li>
+</ul>
+
+<p>This document describes a high-level overview of the organization of Clang
+Tools within the project as well as giving an introduction to some of the more
+important tools. However, it should be noted that this document is currently
+focused on Clang and Clang Tool developers, not on end users of these tools.</p>
+
+<!-- ======================================================================= -->
+<h2 id="org">Clang Tools Organization</h2>
+<!-- ======================================================================= -->
+
+<p>Clang Tools are CLI or GUI programs that are intended to be directly used by
+C++ developers. That is they are <em>not</em> primarily for use by Clang
+developers, although they are hopefully useful to C++ developers who happen to
+work on Clang, and we try to actively dogfood their functionality. They are
+developed in three components: the underlying infrastructure for building
+a standalone tool based on Clang, core shared logic used by many different tools
+in the form of refactoring and rewriting libraries, and the tools
+themselves.</p>
+
+<p>The underlying infrastructure for Clang Tools is the
+<a href="LibTooling.html">LibTooling</a> platform. See its documentation for
+much more detailed information about how this infrastructure works. The common
+refactoring and rewriting toolkit-style library is also part of LibTooling
+organizationally.</p>
+
+<p>A few Clang Tools are developed along side the core Clang libraries as
+examples and test cases of fundamental functionality. However, most of the tools
+are developed in a side repository to provide easy separation from the core
+libraries. We intentionally do not support public libraries in the side
+repository, as we want to carefully review and find good APIs for libraries as
+they are lifted out of a few tools and into the core Clang library set.</p>
+
+<p>Regardless of which repository Clang Tools' code resides in, the development
+process and practices for all Clang Tools are exactly those of Clang itself.
+They are entirely within the Clang <em>project</em>, regardless of the version
+control scheme.</p>
+
+
+<!-- ======================================================================= -->
+<h2 id="coretools">Core Clang Tools</h2>
+<!-- ======================================================================= -->
+
+<p>The core set of Clang tools that are within the main repository are tools
+that very specifically compliment, and allow use and testing of <em>Clang</em>
+specific functionality.</p>
+
+<h3 id="clang-check"><tt>clang-check</tt></h3>
+<p>This tool combines the LibTooling framework for running a Clang tool with the
+basic Clang diagnostics by syntax checking specific files in a fast, command line
+interface. It can also accept flags to re-display the diagnostics in different
+formats with different flags, suitable for use driving an IDE or editor.</p>
+
+<p>FIXME: Link to user-oriented clang-check documentation.</p>
+
+<h3 id="clang-fixit"><tt>clang-fixit</tt> (Not yet implemented!)</h3>
+<p>A tool which specifically applies the Clang fix-it hint diagnostic technology
+on top of a dedicated tool. It is designed to explore alternative interfaces for
+applying fix-it hints, including automatic application, prompting users with
+options for different fixes, etc.</p>
+
+<p><b>NB:</b> The clang-fixit tool is planned, but not yet implemented.</p>
+
+<p>FIXME: Link to user-oriented clang-fixit documentation.</p>
+
+<!-- ======================================================================= -->
+<h2 id="registerplugin">Extra Clang Tools</h2>
+<!-- ======================================================================= -->
+
+<p>As various categories of Clang Tools are added to the extra repository,
+they'll be tracked here. The focus of this documentation is on the scope and
+features of the tools for other tool developers; each tool should provide its
+own user-focused documentation.</p>
+
+</div>
+</body>
+</html>
+
diff --git a/docs/HowToSetupToolingForLLVM.html b/docs/HowToSetupToolingForLLVM.html
index b9f2583..493c882 100644
--- a/docs/HowToSetupToolingForLLVM.html
+++ b/docs/HowToSetupToolingForLLVM.html
@@ -84,6 +84,42 @@
 <p>When editing C++ code, hit F5 to reparse the current buffer. The output will
 go into the error window, which you can enable with <code>:cope</code>.</p>
 
+<p>Other <code>clang-check</code> options that can be useful when working with
+clang AST:</p>
+<ul>
+  <li><code>-ast-print</code> - Build ASTs and then pretty-print them.</li>
+  <li><code>-ast-dump</code> - Build ASTs and then debug dump them.</li>
+  <li><code>-ast-dump-filter=&lt;string&gt;</code> - Use with
+    <code>-ast-dump</code> or <code>-ast-print</code> to dump/print
+    only AST declaration nodes having a certain substring in a qualified name.
+    Use <code>-ast-list</code> to list all filterable declaration node
+    names.</li>
+  <li><code>-ast-list</code> - Build ASTs and print the list of declaration
+    node qualified names.</li>
+</ul>
+<p>Examples:</p>
+<pre>
+<b>$ clang-check tools/clang/tools/clang-check/ClangCheck.cpp -ast-dump -ast-dump-filter ActionFactory::newASTConsumer</b>
+Processing: tools/clang/tools/clang-check/ClangCheck.cpp.
+Dumping <anonymous namespace>::ActionFactory::newASTConsumer:
+clang::ASTConsumer *newASTConsumer() (CompoundStmt 0x44da290 &lt;/home/alexfh/local/llvm/tools/clang/tools/clang-check/ClangCheck.cpp:64:40, line:72:3&gt;
+  (IfStmt 0x44d97c8 &lt;line:65:5, line:66:45&gt;
+    &lt;&lt;&lt;NULL&gt;&gt;&gt;
+      (ImplicitCastExpr 0x44d96d0 &lt;line:65:9&gt; '_Bool':'_Bool' &lt;UserDefinedConversion&gt;
+...
+<b>$ clang-check tools/clang/tools/clang-check/ClangCheck.cpp -ast-print -ast-dump-filter ActionFactory::newASTConsumer</b>
+Processing: tools/clang/tools/clang-check/ClangCheck.cpp.
+Printing &lt;anonymous namespace&gt;::ActionFactory::newASTConsumer:
+clang::ASTConsumer *newASTConsumer() {
+    if (this-&gt;ASTList.operator _Bool())
+        return clang::CreateASTDeclNodeLister();
+    if (this-&gt;ASTDump.operator _Bool())
+        return clang::CreateASTDumper(this-&gt;ASTDumpFilter);
+    if (this-&gt;ASTPrint.operator _Bool())
+        return clang::CreateASTPrinter(&amp;llvm::outs(), this-&gt;ASTDumpFilter);
+    return new clang::ASTConsumer();
+}
+</pre>
 
 <!-- ======================================================================= -->
 <h2><a name="using-ninja">(Experimental) Using Ninja Build System</a></h2>
diff --git a/docs/InternalsManual.html b/docs/InternalsManual.html
index c6df19c..3f3e124 100644
--- a/docs/InternalsManual.html
+++ b/docs/InternalsManual.html
@@ -1704,7 +1704,7 @@
 <li><b><tt>__extension__</tt></b>: The expression form of this extension causes
     any evaluatable subexpression to be accepted as an integer constant
     expression.</li>
-<li><b><tt>__builtin_constant_p</tt></b>: This returns true (as a integer
+<li><b><tt>__builtin_constant_p</tt></b>: This returns true (as an integer
     constant expression) if the operand evaluates to either a numeric value
     (that is, not a pointer cast to integral type) of integral, enumeration,
     floating or complex type, or if it evaluates to the address of the first
diff --git a/docs/IntroductionToTheClangAST.html b/docs/IntroductionToTheClangAST.html
new file mode 100644
index 0000000..28175dd
--- /dev/null
+++ b/docs/IntroductionToTheClangAST.html
@@ -0,0 +1,139 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Introduction to the Clang AST</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>Introduction to the Clang AST</h1>
+<p>This document gives a gentle introduction to the mysteries of the Clang AST.
+It is targeted at developers who either want to contribute to Clang, or use
+tools that work based on Clang's AST, like the AST matchers.</p>
+<!-- FIXME: Add link once we have an AST matcher document -->
+
+<!-- ======================================================================= -->
+<h2 id="intro">Introduction</h2>
+<!-- ======================================================================= -->
+
+<p>Clang's AST is different from ASTs produced by some other compilers in that it closely
+resembles both the written C++ code and the C++ standard. For example,
+parenthesis expressions and compile time constants are available in an unreduced
+form in the AST. This makes Clang's AST a good fit for refactoring tools.</p>
+
+<p>Documentation for all Clang AST nodes is available via the generated
+<a href="http://clang.llvm.org/doxygen">Doxygen</a>. The doxygen online
+documentation is also indexed by your favorite search engine, which will make
+a search for clang and the AST node's class name usually turn up the doxygen
+of the class you're looking for (for example, search for: clang ParenExpr).</p>
+
+<!-- ======================================================================= -->
+<h2 id="examine">Examining the AST</h2>
+<!-- ======================================================================= -->
+
+<p>A good way to familarize yourself with the Clang AST is to actually look
+at it on some simple example code. Clang has a builtin AST-dump modes, which
+can be enabled with the flags -ast-dump and -ast-dump-xml. Note that -ast-dump-xml
+currently only works with debug-builds of clang.</p>
+
+<p>Let's look at a simple example AST:</p>
+<pre>
+# cat test.cc
+int f(int x) {
+  int result = (x / 42);
+  return result;
+}
+
+# Clang by default is a frontend for many tools; -cc1 tells it to directly
+# use the C++ compiler mode. -undef leaves out some internal declarations.
+$ clang -cc1 -undef -ast-dump-xml test.cc
+... cutting out internal declarations of clang ...
+&lt;TranslationUnit ptr="0x4871160">
+ &lt;Function ptr="0x48a5800" name="f" prototype="true">
+  &lt;FunctionProtoType ptr="0x4871de0" canonical="0x4871de0">
+   &lt;BuiltinType ptr="0x4871250" canonical="0x4871250"/>
+   &lt;parameters>
+    &lt;BuiltinType ptr="0x4871250" canonical="0x4871250"/>
+   &lt;/parameters>
+  &lt;/FunctionProtoType>
+  &lt;ParmVar ptr="0x4871d80" name="x" initstyle="c">
+   &lt;BuiltinType ptr="0x4871250" canonical="0x4871250"/>
+  &lt;/ParmVar>
+  &lt;Stmt>
+(CompoundStmt 0x48a5a38 &lt;t2.cc:1:14, line:4:1>
+  (DeclStmt 0x48a59c0 &lt;line:2:3, col:24>
+    0x48a58c0 "int result =
+      (ParenExpr 0x48a59a0 &lt;col:16, col:23> 'int'
+        (BinaryOperator 0x48a5978 &lt;col:17, col:21> 'int' '/'
+          (ImplicitCastExpr 0x48a5960 &lt;col:17> 'int' &lt;LValueToRValue>
+            (DeclRefExpr 0x48a5918 &lt;col:17> 'int' lvalue ParmVar 0x4871d80 'x' 'int'))
+          (IntegerLiteral 0x48a5940 &lt;col:21> 'int' 42)))")
+  (ReturnStmt 0x48a5a18 &lt;line:3:3, col:10>
+    (ImplicitCastExpr 0x48a5a00 &lt;col:10> 'int' &lt;LValueToRValue>
+      (DeclRefExpr 0x48a59d8 &lt;col:10> 'int' lvalue Var 0x48a58c0 'result' 'int'))))
+
+  &lt;/Stmt>
+ &lt;/Function>
+&lt;/TranslationUnit>
+</pre>
+<p>In general, -ast-dump-xml dumps declarations in an XML-style format and
+statements in an S-expression-style format.
+The toplevel declaration in a translation unit is always the
+<a href="http://clang.llvm.org/doxygen/classclang_1_1TranslationUnitDecl.html">translation unit declaration</a>.
+In this example, our first user written declaration is the
+<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">function declaration</a>
+of 'f'. The body of 'f' is a <a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">compound statement</a>,
+whose child nodes are a <a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">declaration statement</a>
+that declares our result variable, and the
+<a href="http://clang.llvm.org/doxygen/classclang_1_1ReturnStmt.html">return statement</a>.</p>
+
+<!-- ======================================================================= -->
+<h2 id="context">AST Context</h2>
+<!-- ======================================================================= -->
+
+<p>All information about the AST for a translation unit is bundled up in the class
+<a href="http://clang.llvm.org/doxygen/classclang_1_1ASTContext.html">ASTContext</a>.
+It allows traversal of the whole translation unit starting from
+<a href="http://clang.llvm.org/doxygen/classclang_1_1ASTContext.html#abd909fb01ef10cfd0244832a67b1dd64">getTranslationUnitDecl</a>,
+or to access Clang's <a href="http://clang.llvm.org/doxygen/classclang_1_1ASTContext.html#a4f95adb9958e22fbe55212ae6482feb4">table of identifiers</a>
+for the parsed translation unit.</p>
+
+<!-- ======================================================================= -->
+<h2 id="nodes">AST Nodes</h2>
+<!-- ======================================================================= -->
+
+<p>Clang's AST nodes are modeled on a class hierarchy that does not have a common
+ancestor. Instead, there are multiple larger hierarchies for basic node types like
+<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a> and
+<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>. Many
+important AST nodes derive from <a href="http://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>,
+<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>,
+<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclContext.html">DeclContext</a> or
+<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>,
+with some classes deriving from both Decl and DeclContext.</p>
+<p>There are also a multitude of nodes in the AST that are not part of a
+larger hierarchy, and are only reachable from specific other nodes,
+like <a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBaseSpecifier.html">CXXBaseSpecifier</a>.
+</p>
+
+<p>Thus, to traverse the full AST, one starts from the <a href="http://clang.llvm.org/doxygen/classclang_1_1TranslationUnitDecl.html">TranslationUnitDecl</a>
+and then recursively traverses everything that can be reached from that node
+- this information has to be encoded for each specific node type. This algorithm
+is encoded in the <a href="http://clang.llvm.org/doxygen/classclang_1_1RecursiveASTVisitor.html">RecursiveASTVisitor</a>.
+See the <a href="http://clang.llvm.org/docs/RAVFrontendAction.html">RecursiveASTVisitor tutorial</a>.</p>
+
+<p>The two most basic nodes in the Clang AST are statements (<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>)
+and declarations (<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>).
+Note that expressions (<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>)
+are also statements in Clang's AST.</p>
+
+</div>
+</body>
+</html>
+
diff --git a/docs/LanguageExtensions.html b/docs/LanguageExtensions.html
index 0b99263..40477b8 100644
--- a/docs/LanguageExtensions.html
+++ b/docs/LanguageExtensions.html
@@ -98,6 +98,7 @@
 <li><a href="#complex-list-init">Initializer lists for complex numbers in C</a></li>
 <li><a href="#builtins">Builtin Functions</a>
   <ul>
+  <li><a href="#__builtin_readcyclecounter">__builtin_readcyclecounter</a></li>
   <li><a href="#__builtin_shufflevector">__builtin_shufflevector</a></li>
   <li><a href="#__builtin_unreachable">__builtin_unreachable</a></li>
   <li><a href="#__sync_swap">__sync_swap</a></li>
@@ -141,6 +142,13 @@
     <li><a href="#ts_slr"><tt>shared_locks_required(...)</tt></a></li>   
     </ul>
 </li>
+<li><a href="#type_safety">Type Safety Checking</a>
+  <ul>
+  <li><a href="#argument_with_type_tag"><tt>argument_with_type_tag(...)</tt></a></li>
+  <li><a href="#pointer_with_type_tag"><tt>pointer_with_type_tag(...)</tt></a></li>
+  <li><a href="#type_tag_for_datatype"><tt>type_tag_for_datatype(...)</tt></a></li>
+  </ul>
+</li>
 </ul>
 
 <!-- ======================================================================= -->
@@ -1367,6 +1375,42 @@
 builtins that we need to implement.</p>
 
 <!-- ======================================================================= -->
+<h3><a name="__builtin_readcyclecounter">__builtin_readcyclecounter</a></h3>
+<!-- ======================================================================= -->
+
+<p><tt>__builtin_readcyclecounter</tt> is used to access the cycle counter
+register (or a similar low-latency, high-accuracy clock) on those targets that
+support it.
+</p>
+
+<p><b>Syntax:</b></p>
+
+<pre>
+__builtin_readcyclecounter()
+</pre>
+
+<p><b>Example of Use:</b></p>
+
+<pre>
+unsigned long long t0 = __builtin_readcyclecounter();
+do_something();
+unsigned long long t1 = __builtin_readcyclecounter();
+unsigned long long cycles_to_do_something = t1 - t0; // assuming no overflow
+</pre>
+
+<p><b>Description:</b></p>
+
+<p>The __builtin_readcyclecounter() builtin returns the cycle counter value,
+which may be either global or process/thread-specific depending on the target.
+As the backing counters often overflow quickly (on the order of
+seconds) this should only be used for timing small intervals. When not
+supported by the target, the return value is always zero. This builtin
+takes no arguments and produces an unsigned long long result.
+</p>
+
+<p>Query for this feature with __has_builtin(__builtin_readcyclecounter).</p>
+
+<!-- ======================================================================= -->
 <h3><a name="__builtin_shufflevector">__builtin_shufflevector</a></h3>
 <!-- ======================================================================= -->
 
@@ -1876,6 +1920,161 @@
 shared locks. Arguments must be lockable type, and there must be at 
 least one argument.</p> 
 
+<!-- ======================================================================= -->
+<h2 id="type_safety">Type Safety Checking</h2>
+<!-- ======================================================================= -->
+
+<p>Clang supports additional attributes to enable checking type safety
+properties that can't be enforced by C type system.  Usecases include:</p>
+<ul>
+<li>MPI library implementations, where these attributes enable checking that
+    buffer type matches the passed <tt>MPI_Datatype</tt>;</li>
+<li>for HDF5 library there is a similar usecase as MPI;</li>
+<li>checking types of variadic functions' arguments for functions like
+    <tt>fcntl()</tt> and <tt>ioctl()</tt>.</li>
+</ul>
+
+<p>You can detect support for these attributes with __has_attribute().  For
+example:</p>
+
+<blockquote>
+<pre>
+#if defined(__has_attribute)
+#  if __has_attribute(argument_with_type_tag) &amp;&amp; \
+      __has_attribute(pointer_with_type_tag) &amp;&amp; \
+      __has_attribute(type_tag_for_datatype)
+#    define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx)))
+/* ... other macros ... */
+#  endif
+#endif
+
+#if !defined(ATTR_MPI_PWT)
+#define ATTR_MPI_PWT(buffer_idx, type_idx)
+#endif
+
+int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+    ATTR_MPI_PWT(1,3);
+</pre>
+</blockquote>
+
+<h3 id="argument_with_type_tag"><tt>argument_with_type_tag(...)</tt></h3>
+
+<p>Use <tt>__attribute__((argument_with_type_tag(arg_kind, arg_idx,
+type_tag_idx)))</tt> on a function declaration to specify that the function
+accepts a type tag that determines the type of some other argument.
+<tt>arg_kind</tt> is an identifier that should be used when annotating all
+applicable type tags.</p>
+
+<p>This attribute is primarily useful for checking arguments of variadic
+functions (<tt>pointer_with_type_tag</tt> can be used in most of non-variadic
+cases).</p>
+
+<p>For example:</p>
+<blockquote>
+<pre>
+int fcntl(int fd, int cmd, ...)
+      __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+</pre>
+</blockquote>
+
+<h3 id="pointer_with_type_tag"><tt>pointer_with_type_tag(...)</tt></h3>
+
+<p>Use <tt>__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx,
+type_tag_idx)))</tt> on a function declaration to specify that the
+function a type tag that determines the pointee type of some other pointer
+argument.</p>
+
+<p>For example:</p>
+<blockquote>
+<pre>
+int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */)
+    __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+</pre>
+</blockquote>
+
+<h3 id="type_tag_for_datatype"><tt>type_tag_for_datatype(...)</tt></h3>
+
+<p>Clang supports annotating type tags of two forms.</p>
+
+<ul>
+<li><b>Type tag that is an expression containing a reference to some declared
+identifier.</b> Use <tt>__attribute__((type_tag_for_datatype(kind, type)))</tt>
+on a declaration with that identifier:
+
+<blockquote>
+<pre>
+extern struct mpi_datatype mpi_datatype_int
+    __attribute__(( type_tag_for_datatype(mpi,int) ));
+#define MPI_INT ((MPI_Datatype) &amp;mpi_datatype_int)
+</pre>
+</blockquote></li>
+
+<li><b>Type tag that is an integral literal.</b>  Introduce a <tt>static
+const</tt> variable with a corresponding initializer value and attach
+<tt>__attribute__((type_tag_for_datatype(kind, type)))</tt> on that
+declaration, for example:
+
+<blockquote>
+<pre>
+#define MPI_INT ((MPI_Datatype) 42)
+static const MPI_Datatype mpi_datatype_int
+    __attribute__(( type_tag_for_datatype(mpi,int) )) = 42
+</pre>
+</blockquote></li>
+</ul>
+
+<p>The attribute also accepts an optional third argument that determines how
+the expression is compared to the type tag.  There are two supported flags:</p>
+
+<ul><li><tt>layout_compatible</tt> will cause types to be compared according to
+layout-compatibility rules (C++11 [class.mem] p&nbsp;17, 18).  This is
+implemented to support annotating types like <tt>MPI_DOUBLE_INT</tt>.
+
+<p>For example:</p>
+<blockquote>
+<pre>
+/* In mpi.h */
+struct internal_mpi_double_int { double d; int i; };
+extern struct mpi_datatype mpi_datatype_double_int
+    __attribute__(( type_tag_for_datatype(mpi, struct internal_mpi_double_int,
+                                          layout_compatible) ));
+
+#define MPI_DOUBLE_INT ((MPI_Datatype) &amp;mpi_datatype_double_int)
+
+/* In user code */
+struct my_pair { double a; int b; };
+struct my_pair *buffer;
+MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning
+
+struct my_int_pair { int a; int b; }
+struct my_int_pair *buffer2;
+MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning: actual buffer element
+                                                 // type 'struct my_int_pair'
+                                                 // doesn't match specified MPI_Datatype
+</pre>
+</blockquote>
+</li>
+
+<li><tt>must_be_null</tt> specifies that the expression should be a null
+pointer constant, for example:
+
+<blockquote>
+<pre>
+/* In mpi.h */
+extern struct mpi_datatype mpi_datatype_null
+    __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) ));
+
+#define MPI_DATATYPE_NULL ((MPI_Datatype) &amp;mpi_datatype_null)
+
+/* In user code */
+MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL
+                                                   // was specified but buffer
+                                                   // is not a null pointer
+</pre>
+</blockquote>
+</li>
+</ul>
+
 </div>
 </body>
 </html>
diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html
new file mode 100644
index 0000000..a371b3b
--- /dev/null
+++ b/docs/LibASTMatchersReference.html
@@ -0,0 +1,1899 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>AST Matcher Reference</title>
+<link type="text/css" rel="stylesheet" href="../menu.css" />
+<link type="text/css" rel="stylesheet" href="../content.css" />
+<style type="text/css">
+td {
+  padding: .33em;
+}
+td.doc {
+  display: none;
+  border-bottom: 1px solid black;
+}
+td.name:hover {
+  color: blue;
+  cursor: pointer;
+}
+</style>
+<script type="text/javascript">
+function toggle(id) {
+  row = document.getElementById(id);
+  if (row.style.display != 'table-cell')
+    row.style.display = 'table-cell';
+  else
+    row.style.display = 'none';
+}
+</script>
+</head>
+<body>
+
+<!--#include virtual="../menu.html.incl"-->
+
+<div id="content">
+
+<h1>AST Matcher Reference</h1>
+
+<p>This document shows all currently implemented matchers. The matchers are grouped
+by category and node type they match. You can click on matcher names to show the
+matcher's source documentation.</p>
+
+<p>There are three different basic categories of matchers:
+<ul>
+<li><a href="#decl-matchers">Node Matchers:</a> Matchers that match a specific type of AST node.</li>
+<li><a href="#narrowing-matchers">Narrowing Matchers:</a> Matchers that match attributes on AST nodes.</li>
+<li><a href="#traversal-matchers">Traversal Matchers:</a> Matchers that allow traversal between AST nodes.</li>
+</ul>
+</p>
+
+<p>Within each category the matchers are ordered by node type they match on.
+Note that if a matcher can match multiple node types, it will it will appear
+multiple times. This means that by searching for Matcher&lt;Stmt&gt; you can
+find all matchers that can be used to match on Stmt nodes.</p>
+
+<p>The exception to that rule are matchers that can match on any node. Those
+are marked with a * and are listed in the beginning of each category.</p>
+
+<!-- ======================================================================= -->
+<h2 id="decl-matchers">Node Matchers</h2>
+<!-- ======================================================================= -->
+
+<p>Node matchers are at the core of matcher expressions - they specify the type
+of node that is expected. Every match expression starts with a node matcher,
+which can then be further refined with a narrowing or traversal matcher. All
+traversal matchers take node matchers as their arguments.</p>
+
+<p>For convenience, all node matchers take an arbitrary number of arguments
+and implicitly act as allOf matchers.</p>
+
+<p>Node matchers are the only matchers that support the bind("id") call to
+bind the matched node to the given string, to be later retrieved from the
+match callback.</p>
+
+<table>
+<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr>
+<!-- START_DECL_MATCHERS -->
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('classTemplate0')">classTemplate</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateDecl.html">ClassTemplateDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="classTemplate0"><pre>Matches C++ class template declarations.
+
+Example matches Z
+  template&lt;class T&gt; class Z {};
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('classTemplateSpecialization0')">classTemplateSpecialization</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="classTemplateSpecialization0"><pre>Matches C++ class template specializations.
+
+Given
+  template&lt;typename T&gt; class A {};
+  template&lt;&gt; class A&lt;double&gt; {};
+  A&lt;int&gt; a;
+classTemplateSpecialization()
+  matches the specializations A&lt;int&gt; and A&lt;double&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('constructor0')">constructor</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="constructor0"><pre>Matches C++ constructor declarations.
+
+Example matches Foo::Foo() and Foo::Foo(int)
+  class Foo {
+   public:
+    Foo();
+    Foo(int);
+    int DoSomething();
+  };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('decl0')">decl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="decl0"><pre>Matches declarations.
+
+Examples matches X, C, and the friend declaration inside C;
+  void X();
+  class C {
+    friend X;
+  };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('destructor0')">destructor</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDestructorDecl.html">CXXDestructorDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="destructor0"><pre>Matches explicit C++ destructor declarations.
+
+Example matches Foo::~Foo()
+  class Foo {
+   public:
+    virtual ~Foo();
+  };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('enumConstant0')">enumConstant</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumConstantDecl.html">EnumConstantDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="enumConstant0"><pre>Matches enum constants.
+
+Example matches A, B, C
+  enum X {
+    A, B, C
+  };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('enumDecl0')">enumDecl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1EnumDecl.html">EnumDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="enumDecl0"><pre>Matches enum declarations.
+
+Example matches X
+  enum X {
+    A, B, C
+  };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('field0')">field</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="field0"><pre>Matches field declarations.
+
+Given
+  class X { int m; };
+field()
+  matches 'm'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('function0')">function</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="function0"><pre>Matches function declarations.
+
+Example matches f
+  void f();
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('functionTemplate0')">functionTemplate</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionTemplateDecl.html">FunctionTemplateDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="functionTemplate0"><pre>Matches C++ function template declarations.
+
+Example matches f
+  template&lt;class T&gt; void f(T t) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('method0')">method</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="method0"><pre>Matches method declarations.
+
+Example matches y
+  class X { void y() };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('nameableDeclaration0')">nameableDeclaration</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="nameableDeclaration0"><pre>Matches a declaration of anything that could have a name.
+
+Example matches X, S, the anonymous union type, i, and U;
+  typedef int X;
+  struct S {
+    union {
+      int i;
+    } U;
+  };
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('record0')">record</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="record0"><pre>Matches C++ class declarations.
+
+Example matches X, Z
+  class X;
+  template&lt;class T&gt; class Z {};
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('usingDecl0')">usingDecl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDecl.html">UsingDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="usingDecl0"><pre>Matches using declarations.
+
+Given
+  namespace X { int x; }
+  using X::x;
+usingDecl()
+  matches using X::x </pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('variable0')">variable</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="variable0"><pre>Matches variable declarations.
+
+Note: this does not match declarations of member variables, which are
+"field" declarations in Clang parlance.
+
+Example matches a
+  int a;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('boolLiteral0')">boolLiteral</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBoolLiteralExpr.html">CXXBoolLiteralExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="boolLiteral0"><pre>Matches bool literals.
+
+Example matches true
+  true
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('castExpr0')">castExpr</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="castExpr0"><pre>Matches any cast nodes of Clang's AST.
+
+Example: castExpr() matches each of the following:
+  (int) 3;
+  const_cast&lt;Expr *&gt;(SubExpr);
+  char c = 0;
+but does not match
+  int i = (0);
+  int k = 0;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('characterLiteral0')">characterLiteral</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="characterLiteral0"><pre>Matches character literals (also matches wchar_t).
+
+Not matching Hex-encoded chars (e.g. 0x1234, which is a IntegerLiteral),
+though.
+
+Example matches 'a', L'a'
+  char ch = 'a'; wchar_t chw = L'a';
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('constCast0')">constCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstCastExpr.html">CXXConstCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="constCast0"><pre>Matches a const_cast expression.
+
+Example: Matches const_cast&lt;int*&gt;(&amp;r) in
+  int n = 42;
+  const int &amp;r(n);
+  int* p = const_cast&lt;int*&gt;(&amp;r);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('dynamicCast0')">dynamicCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDynamicCastExpr.html">CXXDynamicCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="dynamicCast0"><pre>Matches a dynamic_cast expression.
+
+Example:
+  dynamicCast()
+matches
+  dynamic_cast&lt;D*&gt;(&amp;b);
+in
+  struct B { virtual ~B() {} }; struct D : B {};
+  B b;
+  D* p = dynamic_cast&lt;D*&gt;(&amp;b);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('explicitCast0')">explicitCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="explicitCast0"><pre>Matches explicit cast expressions.
+
+Matches any cast expression written in user code, whether it be a
+C-style cast, a functional-style cast, or a keyword cast.
+
+Does not match implicit conversions.
+
+Note: the name "explicitCast" is chosen to match Clang's terminology, as
+Clang uses the term "cast" to apply to implicit conversions as well as to
+actual cast expressions.
+
+hasDestinationType.
+
+Example: matches all five of the casts in
+  int((int)(reinterpret_cast&lt;int&gt;(static_cast&lt;int&gt;(const_cast&lt;int&gt;(42)))))
+but does not match the implicit conversion in
+  long ell = 42;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('functionalCast0')">functionalCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="functionalCast0"><pre>Matches functional cast expressions
+
+Example: Matches Foo(bar);
+  Foo f = bar;
+  Foo g = (Foo) bar;
+  Foo h = Foo(bar);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('implicitCast0')">implicitCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ImplicitCastExpr.html">ImplicitCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="implicitCast0"><pre>Matches the implicit cast nodes of Clang's AST.
+
+This matches many different places, including function call return value
+eliding, as well as any type conversions.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('integerLiteral0')">integerLiteral</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="integerLiteral0"><pre>Matches integer literals of all sizes encodings.
+
+Not matching character-encoded integers such as L'a'.
+
+Example matches 1, 1L, 0x1, 1U
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('reinterpretCast0')">reinterpretCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXReinterpretCastExpr.html">CXXReinterpretCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="reinterpretCast0"><pre>Matches a reinterpret_cast expression.
+
+Either the source expression or the destination type can be matched
+using has(), but hasDestinationType() is more specific and can be
+more readable.
+
+Example matches reinterpret_cast&lt;char*&gt;(&amp;p) in
+  void* p = reinterpret_cast&lt;char*&gt;(&amp;p);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('staticCast0')">staticCast</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXStaticCastExpr.html">CXXStaticCastExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="staticCast0"><pre>Matches a C++ static_cast expression.
+
+hasDestinationType
+reinterpretCast
+
+Example:
+  staticCast()
+matches
+  static_cast&lt;long&gt;(8)
+in
+  long eight(static_cast&lt;long&gt;(8));
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('stringLiteral0')">stringLiteral</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1StringLiteral.html">StringLiteral</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="stringLiteral0"><pre>Matches string literals (also matches wide string literals).
+
+Example matches "abcd", L"abcd"
+  char *s = "abcd"; wchar_t *ws = L"abcd"
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('arraySubscriptExpr0')">arraySubscriptExpr</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="arraySubscriptExpr0"><pre>Matches array subscript expressions.
+
+Given
+  int i = a[1];
+arraySubscriptExpr()
+  matches "a[1]"
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('binaryOperator0')">binaryOperator</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="binaryOperator0"><pre>Matches binary operator expressions.
+
+Example matches a || b
+  !(a || b)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('bindTemporaryExpression0')">bindTemporaryExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXBindTemporaryExpr.html">CXXBindTemporaryExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="bindTemporaryExpression0"><pre>Matches nodes where temporaries are created.
+
+Example matches FunctionTakesString(GetStringByValue())
+    (matcher = bindTemporaryExpression())
+  FunctionTakesString(GetStringByValue());
+  FunctionTakesStringByPointer(GetStringPointer());
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('call0')">call</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="call0"><pre>Matches call expressions.
+
+Example matches x.y() and y()
+  X x;
+  x.y();
+  y();
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('compoundStatement0')">compoundStatement</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">CompoundStmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="compoundStatement0"><pre>Matches compound statements.
+
+Example matches '{}' and '{{}}'in 'for (;;) {{}}'
+  for (;;) {{}}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('conditionalOperator0')">conditionalOperator</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="conditionalOperator0"><pre>Matches conditional operator expressions.
+
+Example matches a ? b : c
+  (a ? b : c) + 42
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('constructorCall0')">constructorCall</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="constructorCall0"><pre>Matches constructor call expressions (including implicit ones).
+
+Example matches string(ptr, n) and ptr within arguments of f
+    (matcher = constructorCall())
+  void f(const string &amp;a, const string &amp;b);
+  char *ptr;
+  int n;
+  f(string(ptr, n), ptr);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('declarationReference0')">declarationReference</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="declarationReference0"><pre>Matches expressions that refer to declarations.
+
+Example matches x in if (x)
+  bool x;
+  if (x) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('declarationStatement0')">declarationStatement</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="declarationStatement0"><pre>Matches declaration statements.
+
+Given
+  int a;
+declarationStatement()
+  matches 'int a'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('defaultArgument0')">defaultArgument</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDefaultArgExpr.html">CXXDefaultArgExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="defaultArgument0"><pre>Matches the value of a default argument at the call site.
+
+Example matches the CXXDefaultArgExpr placeholder inserted for the
+    default value of the second parameter in the call expression f(42)
+    (matcher = defaultArgument())
+  void f(int x, int y = 0);
+  f(42);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('deleteExpression0')">deleteExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXDeleteExpr.html">CXXDeleteExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="deleteExpression0"><pre>Matches delete expressions.
+
+Given
+  delete X;
+deleteExpression()
+  matches 'delete X'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('doStmt0')">doStmt</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="doStmt0"><pre>Matches do statements.
+
+Given
+  do {} while (true);
+doStmt()
+  matches 'do {} while(true)'
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('expression0')">expression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="expression0"><pre>Matches expressions.
+
+Example matches x()
+  void f() { x(); }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('forStmt0')">forStmt</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="forStmt0"><pre>Matches for statements.
+
+Example matches 'for (;;) {}'
+  for (;;) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('ifStmt0')">ifStmt</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="ifStmt0"><pre>Matches if statements.
+
+Example matches 'if (x) {}'
+  if (x) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('initListExpr0')">initListExpr</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1InitListExpr.html">InitListExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="initListExpr0"><pre>Matches init list expressions.
+
+Given
+  int a[] = { 1, 2 };
+  struct B { int x, y; };
+  B b = { 5, 6 };
+initList()
+  matches "{ 1, 2 }" and "{ 5, 6 }"
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('memberCall0')">memberCall</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="memberCall0"><pre>Matches member call expressions.
+
+Example matches x.y()
+  X x;
+  x.y();
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('memberExpression0')">memberExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="memberExpression0"><pre>Matches member expressions.
+
+Given
+  class Y {
+    void x() { this-&gt;x(); x(); Y y; y.x(); a; this-&gt;b; Y::b; }
+    int a; static int b;
+  };
+memberExpression()
+  matches this-&gt;x, x, y.x, a, this-&gt;b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('newExpression0')">newExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="newExpression0"><pre>Matches new expressions.
+
+Given
+  new X;
+newExpression()
+  matches 'new X'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('overloadedOperatorCall0')">overloadedOperatorCall</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="overloadedOperatorCall0"><pre>Matches overloaded operator calls.
+
+Note that if an operator isn't overloaded, it won't match. Instead, use
+binaryOperator matcher.
+Currently it does not match operators such as new delete.
+FIXME: figure out why these do not match?
+
+Example matches both operator&lt;&lt;((o &lt;&lt; b), c) and operator&lt;&lt;(o, b)
+    (matcher = overloadedOperatorCall())
+  ostream &amp;operator&lt;&lt; (ostream &amp;out, int i) { };
+  ostream &amp;o; int b = 1, c = 1;
+  o &lt;&lt; b &lt;&lt; c;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('statement0')">statement</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="statement0"><pre>Matches statements.
+
+Given
+  { ++a; }
+statement()
+  matches both the compound statement '{ ++a; }' and '++a'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('switchCase0')">switchCase</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1SwitchCase.html">SwitchCase</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="switchCase0"><pre>Matches case and default statements inside switch statements.
+
+Given
+  switch(a) { case 42: break; default: break; }
+switchCase()
+  matches 'case 42: break;' and 'default: break;'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('unaryExprOrTypeTraitExpr0')">unaryExprOrTypeTraitExpr</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="unaryExprOrTypeTraitExpr0"><pre>Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
+
+Given
+  Foo x = bar;
+  int y = sizeof(x) + alignof(x);
+unaryExprOrTypeTraitExpr()
+  matches sizeof(x) and alignof(x)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('unaryOperator0')">unaryOperator</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html">UnaryOperator</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="unaryOperator0"><pre>Matches unary operator expressions.
+
+Example matches !a
+  !a || b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('whileStmt0')">whileStmt</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>&gt;...</td></tr>
+<tr><td colspan="4" class="doc" id="whileStmt0"><pre>Matches while statements.
+
+Given
+  while (true) {}
+whileStmt()
+  matches 'while (true) {}'.
+</pre></td></tr>
+
+<!--END_DECL_MATCHERS -->
+</table>
+
+<!-- ======================================================================= -->
+<h2 id="narrowing-matchers">Narrowing Matchers</h2>
+<!-- ======================================================================= -->
+
+<p>Narrowing matchers match certain attributes on the current node, thus
+narrowing down the set of nodes of the current type to match on.</p>
+
+<p>There are special logical narrowing matchers (allOf, anyOf, anything and unless)
+which allow users to create more powerful match expressions.</p>
+
+<table>
+<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr>
+<!-- START_NARROWING_MATCHERS -->
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('allOf0')">allOf</td><td>Matcher&lt;*&gt;  P1, Matcher&lt;*&gt;  P2</td></tr>
+<tr><td colspan="4" class="doc" id="allOf0"><pre>Matches if all given matchers match.
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('anyOf0')">anyOf</td><td>Matcher&lt;*&gt;  P1, Matcher&lt;*&gt;  P2</td></tr>
+<tr><td colspan="4" class="doc" id="anyOf0"><pre>Matches if any of the given matchers matches.
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('anything0')">anything</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="anything0"><pre>Matches any node.
+
+Useful when another matcher requires a child matcher, but there's no
+additional constraint. This will often be used with an explicit conversion
+to an internal::Matcher&lt;&gt; type such as TypeMatcher.
+
+Example: DeclarationMatcher(anything()) matches all declarations, e.g.,
+"int* p" and "void f()" in
+  int* p;
+  void f();
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('unless0')">unless</td><td>Matcher&lt;*&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="unless0"><pre>Matches if the provided matcher does not match.
+
+Example matches Y (matcher = record(unless(hasName("X"))))
+  class X {};
+  class Y {};
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasOperatorName0')">hasOperatorName</td><td>std::string Name</td></tr>
+<tr><td colspan="4" class="doc" id="hasOperatorName0"><pre>Matches the operator Name of operator expressions (binary or
+unary).
+
+Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+  !(a || b)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;CXXBoolLiteral&gt;</td><td class="name" onclick="toggle('equals2')">equals</td><td>ValueT  Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals2"><pre>Matches literals that are equal to the given value.
+
+Example matches true (matcher = boolLiteral(equals(true)))
+  true
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;, Matcher&lt;CXXBoolLiteral&gt;,
+           Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('isImplicit0')">isImplicit</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isImplicit0"><pre>Matches a constructor declaration that has been implicitly added
+by the compiler (eg. implicit defaultcopy constructors).
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>&gt;</td><td class="name" onclick="toggle('isWritten0')">isWritten</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isWritten0"><pre>Matches a contructor initializer if it is explicitly written in
+code (as opposed to implicitly added by the compiler).
+
+Given
+  struct Foo {
+    Foo() { }
+    Foo(int) : foo_("A") { }
+    string foo_;
+  };
+constructor(hasAnyConstructorInitializer(isWritten()))
+  will match Foo(int), but not Foo()
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXOperatorCallExpr.html">CXXOperatorCallExpr</a>&gt;</td><td class="name" onclick="toggle('hasOverloadedOperatorName0')">hasOverloadedOperatorName</td><td>std::string Name</td></tr>
+<tr><td colspan="4" class="doc" id="hasOverloadedOperatorName0"><pre>Matches overloaded operator names.
+
+Matches overloaded operator names specified in strings without the
+"operator" prefix, such as "&lt;&lt;", for OverloadedOperatorCall's.
+
+Example matches a &lt;&lt; b
+    (matcher == overloadedOperatorCall(hasOverloadedOperatorName("&lt;&lt;")))
+  a &lt;&lt; b;
+  c &amp;&amp; d;  assuming both operator&lt;&lt;
+           and operator&amp;&amp; are overloaded somewhere.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;</td><td class="name" onclick="toggle('isDerivedFrom1')">isDerivedFrom</td><td>StringRef BaseName</td></tr>
+<tr><td colspan="4" class="doc" id="isDerivedFrom1"><pre>Overloaded method as shortcut for isDerivedFrom(hasName(...)).
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicitTemplateSpecialization0')">isExplicitTemplateSpecialization</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization0"><pre>Matches explicit template specializations of function, class, or
+static member variable template instantiations.
+
+Given
+  template&lt;typename T&gt; void A(T t) { }
+  template&lt;&gt; void A(int N) { }
+function(isExplicitSpecialization())
+  matches the specialization A&lt;int&gt;().
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;</td><td class="name" onclick="toggle('isTemplateInstantiation0')">isTemplateInstantiation</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isTemplateInstantiation0"><pre>Matches template instantiations of function, class, or static
+member variable template instantiations.
+
+Given
+  template &lt;typename T&gt; class X {}; class A {}; X&lt;A&gt; x;
+or
+  template &lt;typename T&gt; class X {}; class A {}; template class X&lt;A&gt;;
+record(hasName("::X"), isTemplateInstantiation())
+  matches the template instantiation of X&lt;A&gt;.
+
+But given
+  template &lt;typename T&gt;  class X {}; class A {};
+  template &lt;&gt; class X&lt;A&gt; {}; X&lt;A&gt; x;
+record(hasName("::X"), isTemplateInstantiation())
+  does not match, as X&lt;A&gt; is an explicit template specialization.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('argumentCountIs0')">argumentCountIs</td><td>unsigned N</td></tr>
+<tr><td colspan="4" class="doc" id="argumentCountIs0"><pre>Checks that a call expression or a constructor call expression has
+a specific number of arguments (including absent default arguments).
+
+Example matches f(0, 0) (matcher = call(argumentCountIs(2)))
+  void f(int x, int y);
+  f(0, 0);
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;</td><td class="name" onclick="toggle('equals3')">equals</td><td>ValueT  Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals3"><pre>Matches literals that are equal to the given value.
+
+Example matches true (matcher = boolLiteral(equals(true)))
+  true
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;, Matcher&lt;CXXBoolLiteral&gt;,
+           Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">CompoundStmt</a>&gt;</td><td class="name" onclick="toggle('statementCountIs0')">statementCountIs</td><td>unsigned N</td></tr>
+<tr><td colspan="4" class="doc" id="statementCountIs0"><pre>Checks that a compound statement contains a specific number of
+child statements.
+
+Example: Given
+  { for (;;) {} }
+compoundStatement(statementCountIs(0)))
+  matches '{}'
+  but does not match the outer compound statement.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>&gt;</td><td class="name" onclick="toggle('declCountIs0')">declCountIs</td><td>unsigned N</td></tr>
+<tr><td colspan="4" class="doc" id="declCountIs0"><pre>Matches declaration statements that contain a specific number of
+declarations.
+
+Example: Given
+  int a, b;
+  int c;
+  int d = 2, e;
+declCountIs(2)
+  matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;</td><td class="name" onclick="toggle('equals1')">equals</td><td>ValueT  Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value.
+
+Example matches true (matcher = boolLiteral(equals(true)))
+  true
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;, Matcher&lt;CXXBoolLiteral&gt;,
+           Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition0')">isDefinition</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isDefinition0"><pre>Matches if a declaration has a body attached.
+
+Example matches A, va, fa
+  class A {};
+  class B;  Doesn't match, as it has no body.
+  int va;
+  extern int vb;  Doesn't match, as it doesn't define the variable.
+  void fa() {}
+  void fb();  Doesn't match, as it has no body.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicitTemplateSpecialization2')">isExplicitTemplateSpecialization</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization2"><pre>Matches explicit template specializations of function, class, or
+static member variable template instantiations.
+
+Given
+  template&lt;typename T&gt; void A(T t) { }
+  template&lt;&gt; void A(int N) { }
+function(isExplicitSpecialization())
+  matches the specialization A&lt;int&gt;().
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isExternC0')">isExternC</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExternC0"><pre>Matches extern "C" function declarations.
+
+Given:
+  extern "C" void f() {}
+  extern "C" { void g() {} }
+  void h() {}
+function(isExternC())
+  matches the declaration of f and g, but not the declaration h
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('isTemplateInstantiation2')">isTemplateInstantiation</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isTemplateInstantiation2"><pre>Matches template instantiations of function, class, or static
+member variable template instantiations.
+
+Given
+  template &lt;typename T&gt; class X {}; class A {}; X&lt;A&gt; x;
+or
+  template &lt;typename T&gt; class X {}; class A {}; template class X&lt;A&gt;;
+record(hasName("::X"), isTemplateInstantiation())
+  matches the template instantiation of X&lt;A&gt;.
+
+But given
+  template &lt;typename T&gt;  class X {}; class A {};
+  template &lt;&gt; class X&lt;A&gt; {}; X&lt;A&gt; x;
+record(hasName("::X"), isTemplateInstantiation())
+  does not match, as X&lt;A&gt; is an explicit template specialization.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;</td><td class="name" onclick="toggle('equals0')">equals</td><td>ValueT  Value</td></tr>
+<tr><td colspan="4" class="doc" id="equals0"><pre>Matches literals that are equal to the given value.
+
+Example matches true (matcher = boolLiteral(equals(true)))
+  true
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CharacterLiteral.html">CharacterLiteral</a>&gt;, Matcher&lt;CXXBoolLiteral&gt;,
+           Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IntegerLiteral.html">IntegerLiteral</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>&gt;</td><td class="name" onclick="toggle('isArrow0')">isArrow</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isArrow0"><pre>Matches member expressions that are called with '-&gt;' as opposed
+to '.'.
+
+Member calls on the implicit this pointer match as called with '-&gt;'.
+
+Given
+  class Y {
+    void x() { this-&gt;x(); x(); Y y; y.x(); a; this-&gt;b; Y::b; }
+    int a;
+    static int b;
+  };
+memberExpression(isArrow())
+  matches this-&gt;x, x, y.x, a, this-&gt;b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt;</td><td class="name" onclick="toggle('hasName0')">hasName</td><td>std::string Name</td></tr>
+<tr><td colspan="4" class="doc" id="hasName0"><pre>Matches NamedDecl nodes that have the specified name.
+
+Supports specifying enclosing namespaces or classes by prefixing the name
+with '&lt;enclosing&gt;::'.
+Does not match typedefs of an underlying type with the given name.
+
+Example matches X (Name == "X")
+  class X;
+
+Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
+  namespace a { namespace b { class X; } }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt;</td><td class="name" onclick="toggle('matchesName0')">matchesName</td><td>std::string RegExp</td></tr>
+<tr><td colspan="4" class="doc" id="matchesName0"><pre>Matches NamedDecl nodes whose full names partially match the
+given RegExp.
+
+Supports specifying enclosing namespaces or classes by
+prefixing the name with '&lt;enclosing&gt;::'.  Does not match typedefs
+of an underlying type with the given name.
+
+Example matches X (regexp == "::X")
+  class X;
+
+Example matches X (regexp is one of "::X", "^foo::.*X", among others)
+  namespace foo { namespace bar { class X; } }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('asString0')">asString</td><td>std::string Name</td></tr>
+<tr><td colspan="4" class="doc" id="asString0"><pre>Matches if the matched type is represented by the given string.
+
+Given
+  class Y { public: void x(); };
+  void z() { Y* y; y-&gt;x(); }
+call(on(hasType(asString("class Y *"))))
+  matches y-&gt;x()
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('isConstQualified0')">isConstQualified</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isConstQualified0"><pre>Matches QualType nodes that are const-qualified, i.e., that
+include "top-level" const.
+
+Given
+  void a(int);
+  void b(int const);
+  void c(const int);
+  void d(const int*);
+  void e(int const) {};
+function(hasAnyParameter(hasType(isConstQualified())))
+  matches "void b(int const)", "void c(const int)" and
+  "void e(int const) {}". It does not match d as there
+  is no top-level const on the parameter type "const int *".
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('isInteger0')">isInteger</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isInteger0"><pre>Matches QualType nodes that are of integer type.
+
+Given
+  void a(int);
+  void b(long);
+  void c(double);
+function(hasAnyParameter(hasType(isInteger())))
+matches "a(int)", "b(long)", but not "c(double)".
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition2')">isDefinition</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isDefinition2"><pre>Matches if a declaration has a body attached.
+
+Example matches A, va, fa
+  class A {};
+  class B;  Doesn't match, as it has no body.
+  int va;
+  extern int vb;  Doesn't match, as it doesn't define the variable.
+  void fa() {}
+  void fb();  Doesn't match, as it has no body.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>&gt;</td><td class="name" onclick="toggle('ofKind0')">ofKind</td><td>UnaryExprOrTypeTrait Kind</td></tr>
+<tr><td colspan="4" class="doc" id="ofKind0"><pre>Matches unary expressions of a certain kind.
+
+Given
+  int x;
+  int s = sizeof(x) + alignof(x)
+unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
+  matches sizeof(x)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html">UnaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasOperatorName1')">hasOperatorName</td><td>std::string Name</td></tr>
+<tr><td colspan="4" class="doc" id="hasOperatorName1"><pre>Matches the operator Name of operator expressions (binary or
+unary).
+
+Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+  !(a || b)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('isDefinition1')">isDefinition</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isDefinition1"><pre>Matches if a declaration has a body attached.
+
+Example matches A, va, fa
+  class A {};
+  class B;  Doesn't match, as it has no body.
+  int va;
+  extern int vb;  Doesn't match, as it doesn't define the variable.
+  void fa() {}
+  void fb();  Doesn't match, as it has no body.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('isExplicitTemplateSpecialization1')">isExplicitTemplateSpecialization</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isExplicitTemplateSpecialization1"><pre>Matches explicit template specializations of function, class, or
+static member variable template instantiations.
+
+Given
+  template&lt;typename T&gt; void A(T t) { }
+  template&lt;&gt; void A(int N) { }
+function(isExplicitSpecialization())
+  matches the specialization A&lt;int&gt;().
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('isTemplateInstantiation1')">isTemplateInstantiation</td><td></td></tr>
+<tr><td colspan="4" class="doc" id="isTemplateInstantiation1"><pre>Matches template instantiations of function, class, or static
+member variable template instantiations.
+
+Given
+  template &lt;typename T&gt; class X {}; class A {}; X&lt;A&gt; x;
+or
+  template &lt;typename T&gt; class X {}; class A {}; template class X&lt;A&gt;;
+record(hasName("::X"), isTemplateInstantiation())
+  matches the template instantiation of X&lt;A&gt;.
+
+But given
+  template &lt;typename T&gt;  class X {}; class A {};
+  template &lt;&gt; class X&lt;A&gt; {}; X&lt;A&gt; x;
+record(hasName("::X"), isTemplateInstantiation())
+  does not match, as X&lt;A&gt; is an explicit template specialization.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;
+</pre></td></tr>
+
+<!--END_NARROWING_MATCHERS -->
+</table>
+
+<!-- ======================================================================= -->
+<h2 id="traversal-matchers">AST Traversal Matchers</h2>
+<!-- ======================================================================= -->
+
+<p>Traversal matchers specify the relationship to other nodes that are
+reachable from the current node.</p>
+
+<p>Note that there are special traversal matchers (has, hasDescendant, forEach and
+forEachDescendant) which work on all nodes and allow users to write more generic
+match expressions.</p>
+
+<table>
+<tr style="text-align:left"><th>Return type</th><th>Name</th><th>Parameters</th></tr>
+<!-- START_TRAVERSAL_MATCHERS -->
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('forEach0')">forEach</td><td>Matcher&lt;ChildT&gt;  ChildMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="forEach0"><pre>Matches AST nodes that have child AST nodes that match the
+provided matcher.
+
+Example matches X, Y (matcher = record(forEach(record(hasName("X")))
+  class X {};  Matches X, because X::X is a class of name X inside X.
+  class Y { class X {}; };
+  class Z { class Y { class X {}; }; };  Does not match Z.
+
+ChildT must be an AST base type.
+
+As opposed to 'has', 'forEach' will cause a match for each result that
+matches instead of only on the first one.
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('forEachDescendant0')">forEachDescendant</td><td>Matcher&lt;DescendantT&gt;  DescendantMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="forEachDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the
+provided matcher.
+
+Example matches X, A, B, C
+    (matcher = record(forEachDescendant(record(hasName("X")))))
+  class X {};  Matches X, because X::X is a class of name X inside X.
+  class A { class X {}; };
+  class B { class C { class X {}; }; };
+
+DescendantT must be an AST base type.
+
+As opposed to 'hasDescendant', 'forEachDescendant' will cause a match for
+each result that matches instead of only on the first one.
+
+Note: Recursively combined ForEachDescendant can cause many matches:
+  record(forEachDescendant(record(forEachDescendant(record()))))
+will match 10 times (plus injected class name matches) on:
+  class A { class B { class C { class D { class E {}; }; }; }; };
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('has0')">has</td><td>Matcher&lt;ChildT&gt;  ChildMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="has0"><pre>Matches AST nodes that have child AST nodes that match the
+provided matcher.
+
+Example matches X, Y (matcher = record(has(record(hasName("X")))
+  class X {};  Matches X, because X::X is a class of name X inside X.
+  class Y { class X {}; };
+  class Z { class Y { class X {}; }; };  Does not match Z.
+
+ChildT must be an AST base type.
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt;*&gt;</td><td class="name" onclick="toggle('hasDescendant0')">hasDescendant</td><td>Matcher&lt;DescendantT&gt;  DescendantMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDescendant0"><pre>Matches AST nodes that have descendant AST nodes that match the
+provided matcher.
+
+Example matches X, Y, Z
+    (matcher = record(hasDescendant(record(hasName("X")))))
+  class X {};  Matches X, because X::X is a class of name X inside X.
+  class Y { class X {}; };
+  class Z { class Y { class X {}; }; };
+
+DescendantT must be an AST base type.
+
+Usable as: Any Matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>&gt;</td><td class="name" onclick="toggle('hasBase0')">hasBase</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasBase0"><pre>Matches the base expression of an array subscript expression.
+
+Given
+  int i[5];
+  void f() { i[1] = 42; }
+arraySubscriptExpression(hasBase(implicitCast(
+    hasSourceExpression(declarationReference()))))
+  matches i[1] with the declarationReference() matching i
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ArraySubscriptExpr.html">ArraySubscriptExpr</a>&gt;</td><td class="name" onclick="toggle('hasIndex0')">hasIndex</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasIndex0"><pre>Matches the index expression of an array subscript expression.
+
+Given
+  int i[5];
+  void f() { i[1] = 42; }
+arraySubscriptExpression(hasIndex(integerLiteral()))
+  matches i[1] with the integerLiteral() matching 1
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasEitherOperand0')">hasEitherOperand</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasEitherOperand0"><pre>Matches if either the left hand side or the right hand side of a
+binary operator matches.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasLHS0')">hasLHS</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasLHS0"><pre>Matches the left hand side of binary operator expressions.
+
+Example matches a (matcher = binaryOperator(hasLHS()))
+  a || b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1BinaryOperator.html">BinaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasRHS0')">hasRHS</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasRHS0"><pre>Matches the right hand side of binary operator expressions.
+
+Example matches b (matcher = binaryOperator(hasRHS()))
+  a || b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration0')">hasDeclaration</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a type if the declaration of the type matches the given
+matcher.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructorDecl.html">CXXConstructorDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyConstructorInitializer0')">hasAnyConstructorInitializer</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyConstructorInitializer0"><pre>Matches a constructor initializer.
+
+Given
+  struct Foo {
+    Foo() : foo_(1) { }
+    int foo_;
+  };
+record(has(constructor(hasAnyConstructorInitializer(anything()))))
+  record matches Foo, hasAnyConstructorInitializer matches foo_(1)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>&gt;</td><td class="name" onclick="toggle('forField0')">forField</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FieldDecl.html">FieldDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="forField0"><pre>Matches the field declaration of a constructor initializer.
+
+Given
+  struct Foo {
+    Foo() : foo_(1) { }
+    int foo_;
+  };
+record(has(constructor(hasAnyConstructorInitializer(
+    forField(hasName("foo_"))))))
+  matches Foo
+with forField matching foo_
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>&gt;</td><td class="name" onclick="toggle('withInitializer0')">withInitializer</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="withInitializer0"><pre>Matches the initializer expression of a constructor initializer.
+
+Given
+  struct Foo {
+    Foo() : foo_(1) { }
+    int foo_;
+  };
+record(has(constructor(hasAnyConstructorInitializer(
+    withInitializer(integerLiteral(equals(1)))))))
+  matches Foo
+with withInitializer matching (1)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('on0')">on</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="on0"><pre>Matches on the implicit object argument of a member call expression.
+
+Example matches y.x() (matcher = call(on(hasType(record(hasName("Y"))))))
+  class Y { public: void x(); };
+  void z() { Y y; y.x(); }",
+
+FIXME: Overload to allow directly matching types?
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('onImplicitObjectArgument0')">onImplicitObjectArgument</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="onImplicitObjectArgument0"><pre></pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMemberCallExpr.html">CXXMemberCallExpr</a>&gt;</td><td class="name" onclick="toggle('thisPointerType1')">thisPointerType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="thisPointerType1"><pre>Overloaded to match the type's declaration.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>&gt;</td><td class="name" onclick="toggle('ofClass0')">ofClass</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="ofClass0"><pre>Matches the class declaration that the given method declaration
+belongs to.
+
+FIXME: Generalize this for other kinds of declarations.
+FIXME: What other kind of declarations would we need to generalize
+this to?
+
+Example matches A() in the last line
+    (matcher = constructorCall(hasDeclaration(method(
+        ofClass(hasName("A"))))))
+  class A {
+   public:
+    A();
+  };
+  A a = A();
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>&gt;</td><td class="name" onclick="toggle('isDerivedFrom0')">isDerivedFrom</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt; Base</td></tr>
+<tr><td colspan="4" class="doc" id="isDerivedFrom0"><pre>Matches C++ classes that are directly or indirectly derived from
+a class matching Base.
+
+Note that a class is considered to be also derived from itself.
+
+Example matches X, Y, Z, C (Base == hasName("X"))
+  class X;                A class is considered to be derived from itself
+  class Y : public X {};  directly derived
+  class Z : public Y {};  indirectly derived
+  typedef X A;
+  typedef A B;
+  class C : public B {};  derived from a typedef of X
+
+In the following example, Bar matches isDerivedFrom(hasName("X")):
+  class Foo;
+  typedef Foo X;
+  class Bar : public Foo {};  derived from a type that X is a typedef of
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('callee1')">callee</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="callee1"><pre>Matches if the call expression's callee's declaration matches the
+given matcher.
+
+Example matches y.x() (matcher = call(callee(method(hasName("x")))))
+  class Y { public: void x(); };
+  void z() { Y y; y.x();
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('hasAnyArgument0')">hasAnyArgument</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyArgument0"><pre>Matches any argument of a call expression or a constructor call
+expression.
+
+Given
+  void x(int, int, int) { int y; x(1, y, 42); }
+call(hasAnyArgument(declarationReference()))
+  matches x(1, y, 42)
+with hasAnyArgument(...)
+  matching y
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('hasArgument0')">hasArgument</td><td>unsigned N, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasArgument0"><pre>Matches the n'th argument of a call expression or a constructor
+call expression.
+
+Example matches y in x(y)
+    (matcher = call(hasArgument(0, declarationReference())))
+  void x(int) { int y; x(y); }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration1')">hasDeclaration</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a type if the declaration of the type matches the given
+matcher.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CastExpr.html">CastExpr</a>&gt;</td><td class="name" onclick="toggle('hasSourceExpression0')">hasSourceExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasSourceExpression0"><pre>Matches if the cast's source expression matches the given matcher.
+
+Example: matches "a string" (matcher =
+                                 hasSourceExpression(constructorCall()))
+class URL { URL(string); };
+URL url = "a string";
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyTemplateArgument0')">hasAnyTemplateArgument</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument0"><pre>Matches classTemplateSpecializations that have at least one
+TemplateArgument matching the given InnerMatcher.
+
+Given
+  template&lt;typename T&gt; class A {};
+  template&lt;&gt; class A&lt;double&gt; {};
+  A&lt;int&gt; a;
+classTemplateSpecialization(hasAnyTemplateArgument(
+    refersToType(asString("int"))))
+  matches the specialization A&lt;int&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>&gt;</td><td class="name" onclick="toggle('hasTemplateArgument0')">hasTemplateArgument</td><td>unsigned N, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasTemplateArgument0"><pre>Matches classTemplateSpecializations where the n'th TemplateArgument
+matches the given InnerMatcher.
+
+Given
+  template&lt;typename T, typename U&gt; class A {};
+  A&lt;bool, int&gt; b;
+  A&lt;int, bool&gt; c;
+classTemplateSpecialization(hasTemplateArgument(
+    1, refersToType(asString("int"))))
+  matches the specialization A&lt;bool, int&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CompoundStmt.html">CompoundStmt</a>&gt;</td><td class="name" onclick="toggle('hasAnySubstatement0')">hasAnySubstatement</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnySubstatement0"><pre>Matches compound statements where at least one substatement matches
+a given matcher.
+
+Given
+  { {}; 1+2; }
+hasAnySubstatement(compoundStatement())
+  matches '{ {}; 1+2; }'
+with compoundStatement()
+  matching '{}'
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>&gt;</td><td class="name" onclick="toggle('hasCondition4')">hasCondition</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasCondition4"><pre>Matches the condition expression of an if statement, for loop,
+or conditional operator.
+
+Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+  if (true) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>&gt;</td><td class="name" onclick="toggle('hasFalseExpression0')">hasFalseExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasFalseExpression0"><pre>Matches the false branch expression of a conditional operator.
+
+Example matches b
+  condition ? a : b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ConditionalOperator.html">ConditionalOperator</a>&gt;</td><td class="name" onclick="toggle('hasTrueExpression0')">hasTrueExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasTrueExpression0"><pre>Matches the true branch expression of a conditional operator.
+
+Example matches a
+  condition ? a : b
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;</td><td class="name" onclick="toggle('throughUsingDecl0')">throughUsingDecl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="throughUsingDecl0"><pre>Matches a DeclRefExpr that refers to a declaration through a
+specific using shadow declaration.
+
+FIXME: This currently only works for functions. Fix.
+
+Given
+  namespace a { void f() {} }
+  using a::f;
+  void g() {
+    f();     Matches this ..
+    a::f();  .. but not this.
+  }
+declarationReference(throughUsingDeclaration(anything()))
+  matches f()
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>&gt;</td><td class="name" onclick="toggle('to0')">to</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="to0"><pre>Matches a DeclRefExpr that refers to a declaration that matches the
+specified matcher.
+
+Example matches x in if(x)
+    (matcher = declarationReference(to(variable(hasName("x")))))
+  bool x;
+  if (x) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>&gt;</td><td class="name" onclick="toggle('containsDeclaration0')">containsDeclaration</td><td>unsigned N, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="containsDeclaration0"><pre>Matches the n'th declaration of a declaration statement.
+
+Note that this does not work for global declarations because the AST
+breaks up multiple-declaration DeclStmt's into multiple single-declaration
+DeclStmt's.
+Example: Given non-global declarations
+  int a, b = 0;
+  int c;
+  int d = 2, e;
+declarationStatement(containsDeclaration(
+      0, variable(hasInitializer(anything()))))
+  matches only 'int d = 2, e;', and
+declarationStatement(containsDeclaration(1, variable()))
+  matches 'int a, b = 0' as well as 'int d = 2, e;'
+  but 'int c;' is not matched.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>&gt;</td><td class="name" onclick="toggle('hasSingleDecl0')">hasSingleDecl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasSingleDecl0"><pre>Matches the Decl of a DeclStmt which has a single declaration.
+
+Given
+  int a, b;
+  int c;
+declarationStatement(hasSingleDecl(anything()))
+  matches 'int c;' but not 'int a, b;'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody0')">hasBody</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasBody0"><pre>Matches a 'for', 'while', or 'do while' statement that has
+a given body.
+
+Given
+  for (;;) {}
+hasBody(compoundStatement())
+  matches 'for (;;) {}'
+with compoundStatement()
+  matching '{}'
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>&gt;</td><td class="name" onclick="toggle('hasCondition3')">hasCondition</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasCondition3"><pre>Matches the condition expression of an if statement, for loop,
+or conditional operator.
+
+Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+  if (true) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>&gt;</td><td class="name" onclick="toggle('hasDestinationType0')">hasDestinationType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDestinationType0"><pre>Matches casts whose destination type matches a given matcher.
+
+(Note: Clang's AST refers to other conversions as "casts" too, and calls
+actual casts "explicit" casts.)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('hasType3')">hasType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasType3"><pre>Overloaded to match the declaration of the expression's or value
+declaration's type.
+
+In case of a value declaration (for example a variable declaration),
+this resolves one layer of indirection. For example, in the value
+declaration "X x;", record(hasName("X")) matches the declaration of X,
+while variable(hasType(record(hasName("X")))) matches the declaration
+of x."
+
+Example matches x (matcher = expression(hasType(record(hasName("X")))))
+            and z (matcher = variable(hasType(record(hasName("X")))))
+ class X {};
+ void y(X &amp;x) { x; X z; }
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('ignoringImpCasts0')">ignoringImpCasts</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="ignoringImpCasts0"><pre>Matches expressions that match InnerMatcher after any implicit casts
+are stripped off.
+
+Parentheses and explicit casts are not discarded.
+Given
+  int arr[5];
+  int a = 0;
+  char b = 0;
+  const int c = a;
+  int *d = arr;
+  long e = (long) 0l;
+The matchers
+   variable(hasInitializer(ignoringImpCasts(integerLiteral())))
+   variable(hasInitializer(ignoringImpCasts(declarationReference())))
+would match the declarations for a, b, c, and d, but not e.
+While
+   variable(hasInitializer(integerLiteral()))
+   variable(hasInitializer(declarationReference()))
+only match the declarations for b, c, and d.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('ignoringParenCasts0')">ignoringParenCasts</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="ignoringParenCasts0"><pre>Matches expressions that match InnerMatcher after parentheses and
+casts are stripped off.
+
+Implicit and non-C Style casts are also discarded.
+Given
+  int a = 0;
+  char b = (0);
+  void* c = reinterpret_cast&lt;char*&gt;(0);
+  char d = char(0);
+The matcher
+   variable(hasInitializer(ignoringParenCasts(integerLiteral())))
+would match the declarations for a, b, c, and d.
+while
+   variable(hasInitializer(integerLiteral()))
+only match the declaration for a.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;</td><td class="name" onclick="toggle('ignoringParenImpCasts0')">ignoringParenImpCasts</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="ignoringParenImpCasts0"><pre>Matches expressions that match InnerMatcher after implicit casts and
+parentheses are stripped off.
+
+Explicit casts are not discarded.
+Given
+  int arr[5];
+  int a = 0;
+  char b = (0);
+  const int c = a;
+  int *d = (arr);
+  long e = ((long) 0l);
+The matchers
+   variable(hasInitializer(ignoringParenImpCasts(
+      integerLiteral())))
+   variable(hasInitializer(ignoringParenImpCasts(
+      declarationReference())))
+would match the declarations for a, b, c, and d, but not e.
+while
+   variable(hasInitializer(integerLiteral()))
+   variable(hasInitializer(declarationReference()))
+would only match the declaration for a.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody1')">hasBody</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasBody1"><pre>Matches a 'for', 'while', or 'do while' statement that has
+a given body.
+
+Given
+  for (;;) {}
+hasBody(compoundStatement())
+  matches 'for (;;) {}'
+with compoundStatement()
+  matching '{}'
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>&gt;</td><td class="name" onclick="toggle('hasCondition1')">hasCondition</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasCondition1"><pre>Matches the condition expression of an if statement, for loop,
+or conditional operator.
+
+Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+  if (true) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>&gt;</td><td class="name" onclick="toggle('hasIncrement0')">hasIncrement</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasIncrement0"><pre>Matches the increment statement of a for loop.
+
+Example:
+    forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
+matches '++x' in
+    for (x; x &lt; N; ++x) { }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>&gt;</td><td class="name" onclick="toggle('hasLoopInit0')">hasLoopInit</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasLoopInit0"><pre>Matches the initialization statement of a for loop.
+
+Example:
+    forStmt(hasLoopInit(declarationStatement()))
+matches 'int x = 0' in
+    for (int x = 0; x &lt; N; ++x) { }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyParameter0')">hasAnyParameter</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyParameter0"><pre>Matches any parameter of a function declaration.
+
+Does not match the 'this' parameter of a method.
+
+Given
+  class X { void f(int x, int y, int z) {} };
+method(hasAnyParameter(hasName("y")))
+  matches f(int x, int y, int z) {}
+with hasAnyParameter(...)
+  matching int y
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('hasParameter0')">hasParameter</td><td>unsigned N, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ParmVarDecl.html">ParmVarDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasParameter0"><pre>Matches the n'th parameter of a function declaration.
+
+Given
+  class X { void f(int x) {} };
+method(hasParameter(0, hasType(variable())))
+  matches f(int x) {}
+with hasParameter(...)
+  matching int x
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>&gt;</td><td class="name" onclick="toggle('returns0')">returns</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="returns0"><pre>Matches the return type of a function declaration.
+
+Given:
+  class X { int f() { return 1; } };
+method(returns(asString("int")))
+  matches int f() { return 1; }
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>&gt;</td><td class="name" onclick="toggle('hasCondition0')">hasCondition</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasCondition0"><pre>Matches the condition expression of an if statement, for loop,
+or conditional operator.
+
+Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+  if (true) {}
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>&gt;</td><td class="name" onclick="toggle('hasConditionVariableStatement0')">hasConditionVariableStatement</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasConditionVariableStatement0"><pre>Matches the condition variable statement in an if statement.
+
+Given
+  if (A* a = GetAPointer()) {}
+hasConditionVariableStatment(...)
+  matches 'A* a = GetAPointer()'.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ImplicitCastExpr.html">ImplicitCastExpr</a>&gt;</td><td class="name" onclick="toggle('hasImplicitDestinationType0')">hasImplicitDestinationType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasImplicitDestinationType0"><pre>Matches implicit casts whose destination type matches a given
+matcher.
+
+FIXME: Unit test this matcher
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>&gt;</td><td class="name" onclick="toggle('hasObjectExpression0')">hasObjectExpression</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasObjectExpression0"><pre>Matches a member expression where the object expression is
+matched by a given matcher.
+
+Given
+  struct X { int m; };
+  void f(X x) { x.m; m; }
+memberExpression(hasObjectExpression(hasType(record(hasName("X")))))))
+  matches "x.m" and "m"
+with hasObjectExpression(...)
+  matching "x" and the implicit object expression of "m" which has type X*.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>&gt;</td><td class="name" onclick="toggle('member0')">member</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="member0"><pre>Matches a member expression where the member is matched by a
+given matcher.
+
+Given
+  struct { int first, second; } first, second;
+  int i(second.first);
+  int j(first.second);
+memberExpression(member(hasName("first")))
+  matches second.first
+  but not first.second (because the member name there is "second").
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('hasDeclaration2')">hasDeclaration</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a type if the declaration of the type matches the given
+matcher.
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('pointsTo1')">pointsTo</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="pointsTo1"><pre>Overloaded to match the pointee type's declaration.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt;</td><td class="name" onclick="toggle('references1')">references</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="references1"><pre>Overloaded to match the referenced type's declaration.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('alignOfExpr0')">alignOfExpr</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="alignOfExpr0"><pre>Same as unaryExprOrTypeTraitExpr, but only matching
+alignof.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('sizeOfExpr0')">sizeOfExpr</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="sizeOfExpr0"><pre>Same as unaryExprOrTypeTraitExpr, but only matching
+sizeof.
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('refersToDeclaration0')">refersToDeclaration</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="refersToDeclaration0"><pre>Matches a TemplateArgument that refers to a certain declaration.
+
+Given
+  template&lt;typename T&gt; struct A {};
+  struct B { B* next; };
+  A&lt;&amp;B::next&gt; a;
+classTemplateSpecialization(hasAnyTemplateArgument(
+    refersToDeclaration(field(hasName("next"))))
+  matches the specialization A&lt;&amp;B::next&gt; with field(...) matching
+    B::next
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>&gt;</td><td class="name" onclick="toggle('refersToType0')">refersToType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="refersToType0"><pre>Matches a TemplateArgument that refers to a certain type.
+
+Given
+  struct X {};
+  template&lt;typename T&gt; struct A {};
+  A&lt;X&gt; a;
+classTemplateSpecialization(hasAnyTemplateArgument(
+    refersToType(class(hasName("X")))))
+  matches the specialization A&lt;X&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>&gt;</td><td class="name" onclick="toggle('hasArgumentOfType0')">hasArgumentOfType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasArgumentOfType0"><pre>Matches unary expressions that have a specific type of argument.
+
+Given
+  int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
+unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
+  matches sizeof(a) and alignof(c)
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryOperator.html">UnaryOperator</a>&gt;</td><td class="name" onclick="toggle('hasUnaryOperand0')">hasUnaryOperand</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasUnaryOperand0"><pre>Matches if the operand of a unary operator matches.
+
+Example matches true (matcher = hasOperand(boolLiteral(equals(true))))
+  !true
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingDecl.html">UsingDecl</a>&gt;</td><td class="name" onclick="toggle('hasAnyUsingShadowDecl0')">hasAnyUsingShadowDecl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasAnyUsingShadowDecl0"><pre>Matches any using shadow declaration.
+
+Given
+  namespace X { void b(); }
+  using X::b;
+usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
+  matches using X::b </pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>&gt;</td><td class="name" onclick="toggle('hasTargetDecl0')">hasTargetDecl</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1NamedDecl.html">NamedDecl</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasTargetDecl0"><pre>Matches a using shadow declaration where the target declaration is
+matched by the given matcher.
+
+Given
+  namespace X { int a; void b(); }
+  using X::a;
+  using X::b;
+usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function())))
+  matches using X::b but not using X::a </pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;</td><td class="name" onclick="toggle('hasType2')">hasType</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;  InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasType2"><pre>Overloaded to match the declaration of the expression's or value
+declaration's type.
+
+In case of a value declaration (for example a variable declaration),
+this resolves one layer of indirection. For example, in the value
+declaration "X x;", record(hasName("X")) matches the declaration of X,
+while variable(hasType(record(hasName("X")))) matches the declaration
+of x."
+
+Example matches x (matcher = expression(hasType(record(hasName("X")))))
+            and z (matcher = variable(hasType(record(hasName("X")))))
+ class X {};
+ void y(X &amp;x) { x; X z; }
+
+Usable as: Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt;, Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>&gt;
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1VarDecl.html">VarDecl</a>&gt;</td><td class="name" onclick="toggle('hasInitializer0')">hasInitializer</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasInitializer0"><pre>Matches a variable declaration that has an initializer expression
+that matches the given matcher.
+
+Example matches x (matcher = variable(hasInitializer(call())))
+  bool y() { return true; }
+  bool x = y();
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>&gt;</td><td class="name" onclick="toggle('hasBody2')">hasBody</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasBody2"><pre>Matches a 'for', 'while', or 'do while' statement that has
+a given body.
+
+Given
+  for (;;) {}
+hasBody(compoundStatement())
+  matches 'for (;;) {}'
+with compoundStatement()
+  matching '{}'
+</pre></td></tr>
+
+
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>&gt;</td><td class="name" onclick="toggle('hasCondition2')">hasCondition</td><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>&gt; InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="hasCondition2"><pre>Matches the condition expression of an if statement, for loop,
+or conditional operator.
+
+Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+  if (true) {}
+</pre></td></tr>
+
+<!--END_TRAVERSAL_MATCHERS -->
+</table>
+
+</div>
+</body>
+</html>
+
+
diff --git a/docs/LibTooling.html b/docs/LibTooling.html
index 560d115..ed0ad45 100644
--- a/docs/LibTooling.html
+++ b/docs/LibTooling.html
@@ -141,13 +141,11 @@
   cl::ParseCommandLineOptions(argc, argv);
   if (!Compilations) {
     std::string ErrorMessage;
-    if (!BuildPath.empty()) {
-      Compilations.reset(
-         CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage));
-    } else {
-      Compilations.reset(CompilationDatabase::autoDetectFromSource(
-          SourcePaths[0], ErrorMessage));
-    }
+    Compilations.reset(
+      !BuildPath.empty() ?
+        CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage) :
+        CompilationDatabase::autoDetectFromSource(SourcePaths[0], ErrorMessage)
+      );
     if (!Compilations)
       llvm::report_fatal_error(ErrorMessage);
   }
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index 2108909..7a6a508 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -186,6 +186,25 @@
 model can be used.
 </p>
 
+<h4>Type safety attributes</h4>
+<p>Clang now supports type safety attributes that allow checking during compile
+time that 'void *' function arguments and arguments for variadic functions are
+of a particular type which is determined by some other argument to the same
+function call.</p>
+
+<p>Usecases include:</p>
+<ul>
+<li>MPI library implementations, where these attributes enable checking that
+  buffer type matches the passed <code>MPI_Datatype</code>;</li>
+<li> HDF5 library -- similar usecase as for MPI;</li>
+<li> checking types of variadic functions' arguments for functions like
+<code>fcntl()</code> and <code>ioctl()</code>.</li>
+</ul>
+
+<p>See entries for <code>argument_with_type_tag</code>,
+<code>pointer_with_type_tag</code> and <code>type_tag_for_datatype</code>
+attributes in Clang language extensions documentation.</p>
+
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
 <h3 id="newflags">New Compiler Flags</h3>
 <!-- = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = -->
diff --git a/docs/Tooling.html b/docs/Tooling.html
index 4adaf16..74837f4 100644
--- a/docs/Tooling.html
+++ b/docs/Tooling.html
@@ -97,6 +97,23 @@
   <li>do not want to write your tools in C++</li>
 </ul>
 
+<!-- ======================================================================= -->
+<h2 id="clang-tools"><a href="ClangTools.html">Clang Tools</a></h2>
+<!-- ======================================================================= -->
+
+<p>These are a collection of specific developer tools built on top of the
+LibTooling infrastructure as part of the Clang project. They are targeted at
+automating and improving core development activities of C/C++ developers.</p>
+<p>Examples of tools we are building or planning as part of the Clang
+project:</p>
+<ul>
+  <li>Syntax checking (clang-check)</li>
+  <li>Automatic fixing of compile errors (clangc-fixit)</li>
+  <li>Automatic code formatting</li>
+  <li>Migration tools for new features in new language standards</li>
+  <li>Core refactoring tools</li>
+</ul>
+
 </div>
 </body>
 </html>
diff --git a/docs/UsersManual.html b/docs/UsersManual.html
index 629d9b2..69f916c 100644
--- a/docs/UsersManual.html
+++ b/docs/UsersManual.html
@@ -757,7 +757,7 @@
 
 <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. See the avaliable 
+by the user via changes to the source code. See the available 
 <a href = "http://clang-analyzer.llvm.org/annotations.html" >annotations</a> and 
 the analyzer's 
 <a href= "http://clang-analyzer.llvm.org/faq.html#exclude_code" >FAQ page</a> for 
diff --git a/docs/analyzer/IPA.txt b/docs/analyzer/IPA.txt
new file mode 100644
index 0000000..c52b17a
--- /dev/null
+++ b/docs/analyzer/IPA.txt
@@ -0,0 +1,97 @@
+Inlining
+========
+
+Inlining Modes
+-----------------------
+-analyzer-ipa=none - All inlining is disabled. This is the only mode available in LLVM 3.1 and earlier and in Xcode 4.3 and earlier.
+-analyzer-ipa=basic-inlining - Turns on inlining for C functions, C++ static member functions, and blocks -- essentially, the calls that behave like simple C function calls. This is essentially the mode used in Xcode 4.4.
+-analyzer-ipa=inlining - Turns on inlining when we can confidently find the function/method body corresponding to the call. (C functions, static functions, devirtualized C++ methods, ObjC class methods, ObjC instance methods when we are confident about the dynamic type of the instance).
+-analyzer-ipa=dynamic - Inline instance methods for which the type is determined at runtime and we are not 100% sure that our type info is correct. For virtual calls, inline the most plausible definition.
+-analyzer-ipa=dynamic-bifurcate - Same as -analyzer-ipa=dynamic, but the path is split. We inline on one branch and do not inline on the other. This mode does not drop the coverage in cases when the parent class has code that is only exercised when some of its methods are overriden.
+
+Currently, -analyzer-ipa=basic-inlining is the default mode.
+
+Basics of Implementation
+-----------------------
+
+The low-level mechanism of inlining a function is handled in ExprEngine::inlineCall and ExprEngine::processCallExit. If the conditions are right for inlining, a CallEnter node is created and added to the analysis work list. The CallEnter node marks the change to a new LocationContext representing the called function, and its state includes the contents of the new stack frame. When the CallEnter node is actually processed, its single successor will be a edge to the first CFG block in the function.
+
+Exiting an inlined function is a bit more work, fortunately broken up into reasonable steps:
+1. The CoreEngine realizes we're at the end of an inlined call and generates a CallExitBegin node.
+2. ExprEngine takes over (in processCallExit) and finds the return value of the function, if it has one. This is bound to the expression that triggered the call. (In the case of calls without origin expressions, such as destructors, this step is skipped.)
+3. Dead symbols and bindings are cleaned out from the state, including any local bindings.
+4. A CallExitEnd node is generated, which marks the transition back to the caller's LocationContext.
+5. Custom post-call checks are processed and the final nodes are pushed back onto the work list, so that evaluation of the caller can continue.
+
+Retry Without Inlining
+-----------------------
+
+In some cases, we would like to retry analyzes without inlining the particular call. Currently, we use this technique to recover the coverage in case we stop analyzing a path due to exceeding the maximum block count inside an inlined function. When this situation is detected, we walk up the path to find the first node before inlining was started and enqueue it on the WorkList with a special ReplayWithoutInlining bit added to it (ExprEngine::replayWithoutInlining).
+
+Deciding when to inline
+-----------------------
+In general, we try to inline as much as possible, since it provides a better summary of what actually happens in the program. However, there are some cases where we choose not to inline:
+- if there is no definition available (of course)
+- if we can't create a CFG or compute variable liveness for the function
+- if we reach a cutoff of maximum stack depth (to avoid infinite recursion)
+- if the function is variadic
+- in C++, we don't inline constructors unless we know the destructor will be inlined as well
+- in C++, we don't inline allocators (custom operator new implementations), since we don't properly handle deallocators (at the time of this writing)
+- "Dynamic" calls are handled specially; see below.
+- Engine:FunctionSummaries map stores additional information about declarations, some of which is collected at runtime based on previous analyzes of the function. We do not inline functions which were not profitable to inline in a different context (for example, if the maximum block count was exceeded, see Retry Without Inlining).
+
+
+Dynamic calls and devirtualization
+----------------------------------
+"Dynamic" calls are those that are resolved at runtime, such as C++ virtual method calls and Objective-C message sends. Due to the path-sensitive nature of the analyzer, we may be able to figure out the dynamic type of the object whose method is being called and thus "devirtualize" the call, i.e. find the actual method that will be called at runtime. (Obviously this is not always possible.) This is handled by CallEvent's getRuntimeDefinition method.
+
+Type information is tracked as DynamicTypeInfo, stored within the program state. If no DynamicTypeInfo has been explicitly set for a region, it will be inferred from the region's type or associated symbol. Information from symbolic regions is weaker than from true typed regions; a C++ object declared "A obj" is known to have the class 'A', but a reference "A &ref" may dynamically be a subclass of 'A'. The DynamicTypePropagation checker gathers and propagates the type information.
+
+(Warning: not all of the existing analyzer code has been retrofitted to use DynamicTypeInfo, nor is it universally appropriate. In particular, DynamicTypeInfo always applies to a region with all casts stripped off, but sometimes the information provided by casts can be useful.)
+
+When asked to provide a definition, the CallEvents for dynamic calls will use the type info in their state to provide the best definition of the method to be called. In some cases this devirtualization can be perfect or near-perfect, and we can inline the definition as usual. In others we can make a guess, but report that our guess may not be the method actually called at runtime.
+
+The -analyzer-ipa option has five different modes: none, basic-inlining, inlining, dynamic, and dynamic-bifurcate. Under -analyzer-ipa=dynamic, all dynamic calls are inlined, whether we are certain or not that this will actually be the definition used at runtime. Under -analyzer-ipa=inlining, only "near-perfect" devirtualized calls are inlined*, and other dynamic calls are evaluated conservatively (as if no definition were available). Under -analyzer-ipa=basic-inlining, only simple calls (C functions and a few others) are inlined, and no devirtualization is performed.
+
+* Currently, no Objective-C messages are not inlined under -analyzer-ipa=inlining, even if we are reasonably confident of the type of the receiver. We plan to enable this once we have tested our heuristics more thoroughly.
+
+The last option, -analyzer-ipa=dynamic-bifurcate, behaves similarly to "dynamic", but performs a conservative invalidation in the general virtual case in /addition/ to inlining. The details of this are discussed below.
+
+
+Bifurcation
+-----------
+ExprEngine::BifurcateCall implements the -analyzer-ipa=dynamic-bifurcate mode. When a call is made on a region with dynamic type information, we bifurcate the path and add the region's processing mode to the GDM. Currently, there are 2 modes: DynamicDispatchModeInlined and DynamicDispatchModeConservative. Going forward, we consult the state of the region to make decisions on whether the calls should be inlined or not, which ensures that we have at most one split per region. The modes model the cases when the dynamic type information is perfectly correct and when the info is not correct (i.e. where the region is a subclass of the type we store in DynamicTypeInfo).
+
+Bifurcation mode allows for increased coverage in cases where the parent method contains code which is only executed when the class is subclassed. The disadvantages of this mode are a (considerable?) performance hit and the possibility of false positives on the path where the conservative mode is used.
+
+
+Objective-C Message Heuristics
+------------------------------
+We rely on a set of heuristics to partition the set of ObjC method calls into ones that require bifurcation and ones that do not (can or cannot be a subclass). Below are the cases when we consider that the dynamic type of the object is precise (cannot be a subclass):
+ - If the object was created with +alloc or +new and initialized with an -init method.
+ - If the calls are property accesses using dot syntax. This is based on the assumption that children rarely override properties, or do so in an essentially compatible way.
+ - If the class interface is declared inside the main source file. In this case it is unlikely that it will be subclassed.
+ - If the method is not declared outside of main source file, either by the receiver's class or by any superclasses.
+
+
+C++ Inlining Caveats
+--------------------
+C++11 [class.cdtor]p4 describes how the vtable of an object is modified as it is being constructed or destructed; that is, the type of the object depends on which base constructors have been completed. This is tracked using dynamic type info in the DynamicTypePropagation checker.
+
+Temporaries are poorly modelled right now because we're not confident in the placement
+
+'new' is poorly modelled due to some nasty CFG/design issues (elaborated in PR12014). 'delete' is essentially not modelled at all.
+
+Arrays of objects are modeled very poorly right now. We run only the first constructor and first destructor. Because of this, we don't inline any constructors or destructors for arrays.
+
+
+CallEvent
+=========
+
+A CallEvent represents a specific call to a function, method, or other body of code. It is path-sensitive, containing both the current state (ProgramStateRef) and stack space (LocationContext), and provides uniform access to the argument values and return type of a call, no matter how the call is written in the source or what sort of code body is being invoked.
+
+(For those familiar with Cocoa, CallEvent is roughly equivalent to NSInvocation.)
+
+CallEvent should be used whenever there is logic dealing with function calls that does not care how the call occurred. Examples include checking that arguments satisfy preconditions (such as __attribute__((nonnull))), and attempting to inline a call.
+
+CallEvents are reference-counted objects managed by a CallEventManager. While there is no inherent issue with persisting them (say, in the state's GDM), they are intended for short-lived use, and can be recreated from CFGElements or StackFrameContexts fairly easily.
diff --git a/examples/PrintFunctionNames/CMakeLists.txt b/examples/PrintFunctionNames/CMakeLists.txt
index a31a8f6..ba6a350 100644
--- a/examples/PrintFunctionNames/CMakeLists.txt
+++ b/examples/PrintFunctionNames/CMakeLists.txt
@@ -4,6 +4,15 @@
 
 add_clang_library(PrintFunctionNames PrintFunctionNames.cpp)
 
+add_dependencies(PrintFunctionNames
+  ClangAttrClasses
+  ClangAttrList
+  ClangCommentNodes
+  ClangDeclNodes
+  ClangDiagnosticCommon
+  ClangStmtNodes
+  )
+
 target_link_libraries(PrintFunctionNames
   clangFrontend
   clangAST
diff --git a/examples/analyzer-plugin/CMakeLists.txt b/examples/analyzer-plugin/CMakeLists.txt
index 9ad5cac..ba73030 100644
--- a/examples/analyzer-plugin/CMakeLists.txt
+++ b/examples/analyzer-plugin/CMakeLists.txt
@@ -4,6 +4,15 @@
 
 add_clang_library(SampleAnalyzerPlugin MainCallChecker.cpp)
 
+add_dependencies(SampleAnalyzerPlugin
+  ClangAttrClasses
+  ClangAttrList
+  ClangCommentNodes
+  ClangDeclNodes
+  ClangDiagnosticCommon
+  ClangStmtNodes
+  )
+
 target_link_libraries(SampleAnalyzerPlugin
   clangStaticAnalyzerCore
   )
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index c21dafd..edd3cbb 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3277,6 +3277,14 @@
   CXComment_ParamCommand = 7,
 
   /**
+   * \brief A \\tparam command that describes a template parameter (name and
+   * description).
+   *
+   * \brief For example: \\tparam T description.
+   */
+  CXComment_TParamCommand = 8,
+
+  /**
    * \brief A verbatim block command (e. g., preformatted code).  Verbatim
    * block has an opening and a closing command and contains multiple lines of
    * text (\c CXComment_VerbatimBlockLine child nodes).
@@ -3286,25 +3294,25 @@
    * aaa
    * \\endverbatim
    */
-  CXComment_VerbatimBlockCommand = 8,
+  CXComment_VerbatimBlockCommand = 9,
 
   /**
    * \brief A line of text that is contained within a
    * CXComment_VerbatimBlockCommand node.
    */
-  CXComment_VerbatimBlockLine = 9,
+  CXComment_VerbatimBlockLine = 10,
 
   /**
    * \brief A verbatim line command.  Verbatim line has an opening command,
    * a single line of text (up to the newline after the opening command) and
    * has no closing command.
    */
-  CXComment_VerbatimLine = 10,
+  CXComment_VerbatimLine = 11,
 
   /**
    * \brief A full comment attached to a declaration, contains block content.
    */
-  CXComment_FullComment = 11
+  CXComment_FullComment = 12
 };
 
 /**
@@ -3564,6 +3572,63 @@
                                                             CXComment Comment);
 
 /**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns template parameter name.
+ */
+CINDEX_LINKAGE
+CXString clang_TParamCommandComment_getParamName(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns non-zero if the parameter that this AST node represents was found
+ * in the template parameter list and
+ * \c clang_TParamCommandComment_getDepth and
+ * \c clang_TParamCommandComment_getIndex functions will return a meaningful
+ * value.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based nesting depth of this parameter in the template parameter list.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0,
+ * for T nesting depth is 1.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getDepth(CXComment Comment);
+
+/**
+ * \param Comment a \c CXComment_TParamCommand AST node.
+ *
+ * \returns zero-based parameter index in the template parameter list at a
+ * given nesting depth.
+ *
+ * For example,
+ * \verbatim
+ *     template<typename C, template<typename T> class TT>
+ *     void test(TT<int> aaa);
+ * \endverbatim
+ * for C and TT nesting depth is 0, so we can ask for index at depth 0:
+ * at depth 0 C's index is 0, TT's index is 1.
+ *
+ * For T nesting depth is 1, so we can ask for index at depth 0 and 1:
+ * at depth 0 T's index is 1 (same as TT's),
+ * at depth 1 T's index is 0.
+ */
+CINDEX_LINKAGE
+unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);
+
+/**
  * \param Comment a \c CXComment_VerbatimBlockLine AST node.
  *
  * \returns text contained in the AST node.
@@ -3606,6 +3671,15 @@
  * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if
  * parameter index is invalid.
  *
+ * Template parameter documentation is rendered as a \<dl\> list with
+ * parameters sorted in template parameter list order.  CSS classes used:
+ * \li "tparam-name-index-NUMBER" for parameter name (\<dt\>);
+ * \li "tparam-descr-index-NUMBER" for parameter description (\<dd\>);
+ * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for
+ * names inside template template parameters;
+ * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if
+ * parameter position is invalid.
+ *
  * \param Comment a \c CXComment_FullComment AST node.
  *
  * \returns string containing an HTML fragment.
@@ -3613,6 +3687,21 @@
 CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
 
 /**
+ * \brief Convert a given full parsed comment to an XML document.
+ *
+ * A Relax NG schema for the XML can be found in comment-xml-schema.rng file
+ * inside clang source tree.
+ *
+ * \param TU the translation unit \c Comment belongs to.
+ *
+ * \param Comment a \c CXComment_FullComment AST node.
+ *
+ * \returns string containing an XML document.
+ */
+CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXTranslationUnit TU,
+                                                   CXComment Comment);
+
+/**
  * @}
  */
 
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index a8b00a7..47827e9 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -20,7 +20,6 @@
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/VersionTuple.h"
-#include "clang/AST/Comment.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/LambdaMangleContext.h"
 #include "clang/AST/NestedNameSpecifier.h"
@@ -81,6 +80,10 @@
 
   namespace Builtin { class Context; }
 
+  namespace comments {
+    class FullComment;
+  }
+
 /// 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 : public RefCountedBase<ASTContext> {
@@ -430,14 +433,70 @@
   /// \brief True if comments are already loaded from ExternalASTSource.
   mutable bool CommentsLoaded;
 
-  typedef std::pair<const RawComment *, comments::FullComment *>
-      RawAndParsedComment;
+  class RawCommentAndCacheFlags {
+  public:
+    enum Kind {
+      /// We searched for a comment attached to the particular declaration, but
+      /// didn't find any.
+      ///
+      /// getRaw() == 0.
+      NoCommentInDecl = 0,
 
-  /// \brief Mapping from declarations to their comments.
+      /// We have found a comment attached to this particular declaration.
+      ///
+      /// getRaw() != 0.
+      FromDecl,
+
+      /// This declaration does not have an attached comment, and we have
+      /// searched the redeclaration chain.
+      ///
+      /// If getRaw() == 0, the whole redeclaration chain does not have any
+      /// comments.
+      ///
+      /// If getRaw() != 0, it is a comment propagated from other
+      /// redeclaration.
+      FromRedecl
+    };
+
+    Kind getKind() const LLVM_READONLY {
+      return Data.getInt();
+    }
+
+    void setKind(Kind K) {
+      Data.setInt(K);
+    }
+
+    const RawComment *getRaw() const LLVM_READONLY {
+      return Data.getPointer();
+    }
+
+    void setRaw(const RawComment *RC) {
+      Data.setPointer(RC);
+    }
+
+    const Decl *getOriginalDecl() const LLVM_READONLY {
+      return OriginalDecl;
+    }
+
+    void setOriginalDecl(const Decl *Orig) {
+      OriginalDecl = Orig;
+    }
+
+  private:
+    llvm::PointerIntPair<const RawComment *, 2, Kind> Data;
+    const Decl *OriginalDecl;
+  };
+
+  /// \brief Mapping from declarations to comments attached to any
+  /// redeclaration.
   ///
   /// Raw comments are owned by Comments list.  This mapping is populated
   /// lazily.
-  mutable llvm::DenseMap<const Decl *, RawAndParsedComment> DeclComments;
+  mutable llvm::DenseMap<const Decl *, RawCommentAndCacheFlags> RedeclComments;
+
+  /// \brief Mapping from declarations to parsed comments attached to any
+  /// redeclaration.
+  mutable llvm::DenseMap<const Decl *, comments::FullComment *> ParsedComments;
 
   /// \brief Return the documentation comment attached to a given declaration,
   /// without looking into cache.
@@ -454,7 +513,12 @@
 
   /// \brief Return the documentation comment attached to a given declaration.
   /// Returns NULL if no comment is attached.
-  const RawComment *getRawCommentForDecl(const Decl *D) const;
+  ///
+  /// \param OriginalDecl if not NULL, is set to declaration AST node that had
+  /// the comment, if the comment we found comes from a redeclaration.
+  const RawComment *getRawCommentForAnyRedecl(
+                                      const Decl *D,
+                                      const Decl **OriginalDecl = NULL) const;
 
   /// Return parsed documentation comment attached to a given declaration.
   /// Returns NULL if no comment is attached.
@@ -1363,6 +1427,10 @@
   /// characters. This method does not work on incomplete types.
   CharUnits getTypeAlignInChars(QualType T) const;
   CharUnits getTypeAlignInChars(const Type *T) const;
+  
+  // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the
+  // type is a record, its data size is returned.
+  std::pair<CharUnits, CharUnits> getTypeInfoDataSizeInChars(QualType T) const;
 
   std::pair<CharUnits, CharUnits> getTypeInfoInChars(const Type *T) const;
   std::pair<CharUnits, CharUnits> getTypeInfoInChars(QualType T) const;
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 27b44d4..b17bd48 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -105,7 +105,8 @@
   virtual bool isLateParsed() const { return false; }
 
   // Pretty print this attribute.
-  virtual void printPretty(llvm::raw_ostream &OS, ASTContext &C) const = 0;
+  virtual void printPretty(llvm::raw_ostream &OS,
+                           const PrintingPolicy &Policy) const = 0;
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Attr *) { return true; }
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 55cb081..01aaac3 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -15,10 +15,15 @@
 #define LLVM_CLANG_AST_COMMENT_H
 
 #include "clang/Basic/SourceLocation.h"
+#include "clang/AST/Type.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace clang {
+class Decl;
+class ParmVarDecl;
+class TemplateParameterList;
+
 namespace comments {
 
 /// Any part of the comment.
@@ -713,6 +718,7 @@
   }
 
   unsigned getParamIndex() const LLVM_READONLY {
+    assert(isParamIndexValid());
     return ParamIndex;
   }
 
@@ -722,6 +728,68 @@
   }
 };
 
+/// Doxygen \\tparam command, describes a template parameter.
+class TParamCommandComment : public BlockCommandComment {
+private:
+  /// If this template parameter name was resolved (found in template parameter
+  /// list), then this stores a list of position indexes in all template
+  /// parameter lists.
+  ///
+  /// For example:
+  /// \verbatim
+  ///     template<typename C, template<typename T> class TT>
+  ///     void test(TT<int> aaa);
+  /// \endverbatim
+  /// For C:  Position = { 0 }
+  /// For TT: Position = { 1 }
+  /// For T:  Position = { 1, 0 }
+  llvm::ArrayRef<unsigned> Position;
+
+public:
+  TParamCommandComment(SourceLocation LocBegin,
+                       SourceLocation LocEnd,
+                       StringRef Name) :
+      BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, Name)
+  { }
+
+  static bool classof(const Comment *C) {
+    return C->getCommentKind() == TParamCommandCommentKind;
+  }
+
+  static bool classof(const TParamCommandComment *) { return true; }
+
+  bool hasParamName() const {
+    return getNumArgs() > 0;
+  }
+
+  StringRef getParamName() const {
+    return Args[0].Text;
+  }
+
+  SourceRange getParamNameRange() const {
+    return Args[0].Range;
+  }
+
+  bool isPositionValid() const LLVM_READONLY {
+    return !Position.empty();
+  }
+
+  unsigned getDepth() const {
+    assert(isPositionValid());
+    return Position.size();
+  }
+
+  unsigned getIndex(unsigned Depth) const {
+    assert(isPositionValid());
+    return Position[Depth];
+  }
+
+  void setPosition(ArrayRef<unsigned> NewPosition) {
+    Position = NewPosition;
+    assert(isPositionValid());
+  }
+};
+
 /// A line of text contained in a verbatim block.
 class VerbatimBlockLineComment : public Comment {
   StringRef Text;
@@ -843,14 +911,114 @@
   }
 };
 
+/// Information about the declaration, useful to clients of FullComment.
+struct DeclInfo {
+  /// Declaration the comment is attached to.  Should not be NULL.
+  const Decl *ThisDecl;
+
+  /// Parameters that can be referenced by \\param if \c ThisDecl is something
+  /// that we consider a "function".
+  ArrayRef<const ParmVarDecl *> ParamVars;
+
+  /// Function result type if \c ThisDecl is something that we consider
+  /// a "function".
+  QualType ResultType;
+
+  /// Template parameters that can be referenced by \\tparam if \c ThisDecl is
+  /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
+  /// true).
+  const TemplateParameterList *TemplateParameters;
+
+  /// A simplified description of \c ThisDecl kind that should be good enough
+  /// for documentation rendering purposes.
+  enum DeclKind {
+    /// Everything else not explicitly mentioned below.
+    OtherKind,
+
+    /// Something that we consider a "function":
+    /// \li function,
+    /// \li function template,
+    /// \li function template specialization,
+    /// \li member function,
+    /// \li member function template,
+    /// \li member function template specialization,
+    /// \li ObjC method.
+    FunctionKind,
+
+    /// Something that we consider a "class":
+    /// \li class/struct,
+    /// \li class template,
+    /// \li class template (partial) specialization.
+    ClassKind,
+
+    /// Something that we consider a "variable":
+    /// \li namespace scope variables;
+    /// \li static and non-static class data members;
+    /// \li enumerators.
+    VariableKind,
+
+    /// A C++ namespace.
+    NamespaceKind,
+
+    /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
+    /// see \c TypedefNameDecl.
+    TypedefKind,
+
+    /// An enumeration or scoped enumeration.
+    EnumKind
+  };
+
+  /// What kind of template specialization \c ThisDecl is.
+  enum TemplateDeclKind {
+    NotTemplate,
+    Template,
+    TemplateSpecialization,
+    TemplatePartialSpecialization
+  };
+
+  /// If false, only \c ThisDecl is valid.
+  unsigned IsFilled : 1;
+
+  /// Simplified kind of \c ThisDecl, see\c DeclKind enum.
+  unsigned Kind : 3;
+
+  /// Is \c ThisDecl a template declaration.
+  unsigned TemplateKind : 2;
+
+  /// Is \c ThisDecl an ObjCMethodDecl.
+  unsigned IsObjCMethod : 1;
+
+  /// Is \c ThisDecl a non-static member function of C++ class or
+  /// instance method of ObjC class.
+  /// Can be true only if \c IsFunctionDecl is true.
+  unsigned IsInstanceMethod : 1;
+
+  /// Is \c ThisDecl a static member function of C++ class or
+  /// class method of ObjC class.
+  /// Can be true only if \c IsFunctionDecl is true.
+  unsigned IsClassMethod : 1;
+
+  void fill();
+
+  DeclKind getKind() const LLVM_READONLY {
+    return static_cast<DeclKind>(Kind);
+  }
+
+  TemplateDeclKind getTemplateKind() const LLVM_READONLY {
+    return static_cast<TemplateDeclKind>(TemplateKind);
+  }
+};
+
 /// A full comment attached to a declaration, contains block content.
 class FullComment : public Comment {
   llvm::ArrayRef<BlockContentComment *> Blocks;
 
+  DeclInfo *ThisDeclInfo;
+
 public:
-  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks) :
+  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
       Comment(FullCommentKind, SourceLocation(), SourceLocation()),
-      Blocks(Blocks) {
+      Blocks(Blocks), ThisDeclInfo(D) {
     if (Blocks.empty())
       return;
 
@@ -872,6 +1040,16 @@
   child_iterator child_end() const {
     return reinterpret_cast<child_iterator>(Blocks.end());
   }
+
+  const Decl *getDecl() const LLVM_READONLY {
+    return ThisDeclInfo->ThisDecl;
+  }
+
+  const DeclInfo *getDeclInfo() const LLVM_READONLY {
+    if (!ThisDeclInfo->IsFilled)
+      ThisDeclInfo->fill();
+    return ThisDeclInfo;
+  }
 };
 
 } // end namespace comments
diff --git a/include/clang/AST/CommentBriefParser.h b/include/clang/AST/CommentBriefParser.h
index 62fdf6b..5d50886 100644
--- a/include/clang/AST/CommentBriefParser.h
+++ b/include/clang/AST/CommentBriefParser.h
@@ -30,6 +30,8 @@
 class BriefParser {
   Lexer &L;
 
+  const CommandTraits &Traits;
+
   /// Current lookahead token.
   Token Tok;
 
@@ -40,10 +42,9 @@
   }
 
 public:
-  BriefParser(Lexer &L);
+  BriefParser(Lexer &L, const CommandTraits &Traits);
 
-  /// Return \\brief paragraph, if it exists; otherwise return the first
-  /// paragraph.
+  /// Return the best "brief description" we can find.
   std::string Parse();
 };
 
diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h
new file mode 100644
index 0000000..5f0269a
--- /dev/null
+++ b/include/clang/AST/CommentCommandTraits.h
@@ -0,0 +1,156 @@
+//===--- CommentCommandTraits.h - Comment command properties ----*- C++ -*-===//
+//
+//                     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 class that provides information about comment
+//  commands.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+#define LLVM_CLANG_AST_COMMENT_COMMAND_TRAITS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace clang {
+namespace comments {
+
+/// This class provides informaiton about commands that can be used
+/// in comments.
+class CommandTraits {
+public:
+  CommandTraits() { }
+
+  /// \brief Check if a given command is a verbatim-like block command.
+  ///
+  /// A verbatim-like block command eats every character (except line starting
+  /// decorations) until matching end command is seen or comment end is hit.
+  ///
+  /// \param StartName name of the command that starts the verbatim block.
+  /// \param [out] EndName name of the command that ends the verbatim block.
+  ///
+  /// \returns true if a given command is a verbatim block command.
+  bool isVerbatimBlockCommand(StringRef StartName, StringRef &EndName) const;
+
+  /// \brief Register a new verbatim block command.
+  void addVerbatimBlockCommand(StringRef StartName, StringRef EndName);
+
+  /// \brief Check if a given command is a verbatim line command.
+  ///
+  /// A verbatim-like line command eats everything until a newline is seen or
+  /// comment end is hit.
+  bool isVerbatimLineCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is a command that contains a declaration
+  /// for the entity being documented.
+  ///
+  /// For example:
+  /// \code
+  ///   \fn void f(int a);
+  /// \endcode
+  bool isDeclarationCommand(StringRef Name) const;
+
+  /// \brief Register a new verbatim line command.
+  void addVerbatimLineCommand(StringRef Name);
+
+  /// \brief Check if a given command is a block command (of any kind).
+  bool isBlockCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is introducing documentation for
+  /// a function parameter (\\param or an alias).
+  bool isParamCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is introducing documentation for
+  /// a template parameter (\\tparam or an alias).
+  bool isTParamCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is introducing a brief documentation
+  /// paragraph (\\brief or an alias).
+  bool isBriefCommand(StringRef Name) const;
+
+  /// \brief Check if a given command is \\brief or an alias.
+  bool isReturnsCommand(StringRef Name) const;
+
+  /// \returns the number of word-like arguments for a given block command,
+  /// except for \\param and \\tparam commands -- these have special argument
+  /// parsers.
+  unsigned getBlockCommandNumArgs(StringRef Name) const;
+
+  /// \brief Check if a given command is a inline command (of any kind).
+  bool isInlineCommand(StringRef Name) const;
+
+private:
+  struct VerbatimBlockCommand {
+    StringRef StartName;
+    StringRef EndName;
+  };
+
+  typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector;
+
+  /// Registered additional verbatim-like block commands.
+  VerbatimBlockCommandVector VerbatimBlockCommands;
+
+  struct VerbatimLineCommand {
+    StringRef Name;
+  };
+
+  typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector;
+
+  /// Registered verbatim-like line commands.
+  VerbatimLineCommandVector VerbatimLineCommands;
+};
+
+inline bool CommandTraits::isBlockCommand(StringRef Name) const {
+  return isBriefCommand(Name) || isReturnsCommand(Name) ||
+      isParamCommand(Name) || isTParamCommand(Name) ||
+      llvm::StringSwitch<bool>(Name)
+      .Case("author", true)
+      .Case("authors", true)
+      .Case("pre", true)
+      .Case("post", true)
+      .Default(false);
+}
+
+inline bool CommandTraits::isParamCommand(StringRef Name) const {
+  return Name == "param";
+}
+
+inline bool CommandTraits::isTParamCommand(StringRef Name) const {
+  return Name == "tparam" || // Doxygen
+         Name == "templatefield"; // HeaderDoc
+}
+
+inline bool CommandTraits::isBriefCommand(StringRef Name) const {
+  return Name == "brief" || Name == "short";
+}
+
+inline bool CommandTraits::isReturnsCommand(StringRef Name) const {
+  return Name == "returns" || Name == "return" || Name == "result";
+}
+
+inline unsigned CommandTraits::getBlockCommandNumArgs(StringRef Name) const {
+  return 0;
+}
+
+inline bool CommandTraits::isInlineCommand(StringRef Name) const {
+  return llvm::StringSwitch<bool>(Name)
+      .Case("b", true)
+      .Cases("c", "p", true)
+      .Cases("a", "e", "em", true)
+      .Default(false);
+}
+
+} // end namespace comments
+} // end namespace clang
+
+#endif
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index d5319a3..7a24b11 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -26,6 +26,7 @@
 
 class Lexer;
 class TextTokenRetokenizer;
+class CommandTraits;
 
 namespace tok {
 enum TokenKind {
@@ -211,6 +212,12 @@
   Lexer(const Lexer&);          // DO NOT IMPLEMENT
   void operator=(const Lexer&); // DO NOT IMPLEMENT
 
+  /// Allocator for strings that are semantic values of tokens and have to be
+  /// computed (for example, resolved decimal character references).
+  llvm::BumpPtrAllocator &Allocator;
+
+  const CommandTraits &Traits;
+
   const char *const BufferStart;
   const char *const BufferEnd;
   SourceLocation FileLoc;
@@ -258,36 +265,19 @@
   /// Current lexing mode.
   LexerState State;
 
-  /// A verbatim-like block command eats every character (except line starting
-  /// decorations) until matching end command is seen or comment end is hit.
-  struct VerbatimBlockCommand {
-    StringRef BeginName;
-    StringRef EndName;
-  };
-
-  typedef SmallVector<VerbatimBlockCommand, 4> VerbatimBlockCommandVector;
-
-  /// Registered verbatim-like block commands.
-  VerbatimBlockCommandVector VerbatimBlockCommands;
-
   /// If State is LS_VerbatimBlock, contains the name of verbatim end
   /// command, including command marker.
   SmallString<16> VerbatimBlockEndCommandName;
 
-  bool isVerbatimBlockCommand(StringRef BeginName, StringRef &EndName) const;
+  /// Given a character reference name (e.g., "lt"), return the character that
+  /// it stands for (e.g., "<").
+  StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
 
-  /// A verbatim-like line command eats everything until a newline is seen or
-  /// comment end is hit.
-  struct VerbatimLineCommand {
-    StringRef Name;
-  };
+  /// Given a Unicode codepoint as base-10 integer, return the character.
+  StringRef resolveHTMLDecimalCharacterReference(StringRef Name) const;
 
-  typedef SmallVector<VerbatimLineCommand, 4> VerbatimLineCommandVector;
-
-  /// Registered verbatim-like line commands.
-  VerbatimLineCommandVector VerbatimLineCommands;
-
-  bool isVerbatimLineCommand(StringRef Name) const;
+  /// Given a Unicode codepoint as base-16 integer, return the character.
+  StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
 
   void formTokenWithChars(Token &Result, const char *TokEnd,
                           tok::TokenKind Kind) {
@@ -302,6 +292,12 @@
     BufferPtr = TokEnd;
   }
 
+  void formTextToken(Token &Result, const char *TokEnd) {
+    StringRef Text(BufferPtr, TokEnd - BufferPtr);
+    formTokenWithChars(Result, TokEnd, tok::text);
+    Result.setText(Text);
+  }
+
   SourceLocation getSourceLocation(const char *Loc) const {
     assert(Loc >= BufferStart && Loc <= BufferEnd &&
            "Location out of range for this buffer!");
@@ -328,6 +324,8 @@
 
   void lexVerbatimLineText(Token &T);
 
+  void lexHTMLCharacterReference(Token &T);
+
   void setupAndLexHTMLStartTag(Token &T);
 
   void lexHTMLStartTag(Token &T);
@@ -337,7 +335,8 @@
   void lexHTMLEndTag(Token &T);
 
 public:
-  Lexer(SourceLocation FileLoc, const CommentOptions &CommOpts,
+  Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
+        SourceLocation FileLoc, const CommentOptions &CommOpts,
         const char *BufferStart, const char *BufferEnd);
 
   void lex(Token &T);
@@ -345,215 +344,6 @@
   StringRef getSpelling(const Token &Tok,
                         const SourceManager &SourceMgr,
                         bool *Invalid = NULL) const;
-
-  /// \brief Register a new verbatim block command.
-  void addVerbatimBlockCommand(StringRef BeginName, StringRef EndName);
-
-  /// \brief Register a new verbatim line command.
-  void addVerbatimLineCommand(StringRef Name);
-};
-
-/// Re-lexes a sequence of tok::text tokens.
-class TextTokenRetokenizer {
-  llvm::BumpPtrAllocator &Allocator;
-  static const unsigned MaxTokens = 16;
-  SmallVector<Token, MaxTokens> Toks;
-
-  struct Position {
-    unsigned CurToken;
-    const char *BufferStart;
-    const char *BufferEnd;
-    const char *BufferPtr;
-    SourceLocation BufferStartLoc;
-  };
-
-  /// Current position in Toks.
-  Position Pos;
-
-  bool isEnd() const {
-    return Pos.CurToken >= Toks.size();
-  }
-
-  /// Sets up the buffer pointers to point to current token.
-  void setupBuffer() {
-    assert(Pos.CurToken < Toks.size());
-    const Token &Tok = Toks[Pos.CurToken];
-
-    Pos.BufferStart = Tok.getText().begin();
-    Pos.BufferEnd = Tok.getText().end();
-    Pos.BufferPtr = Pos.BufferStart;
-    Pos.BufferStartLoc = Tok.getLocation();
-  }
-
-  SourceLocation getSourceLocation() const {
-    const unsigned CharNo = Pos.BufferPtr - Pos.BufferStart;
-    return Pos.BufferStartLoc.getLocWithOffset(CharNo);
-  }
-
-  char peek() const {
-    assert(!isEnd());
-    assert(Pos.BufferPtr != Pos.BufferEnd);
-    return *Pos.BufferPtr;
-  }
-
-  void consumeChar() {
-    assert(!isEnd());
-    assert(Pos.BufferPtr != Pos.BufferEnd);
-    Pos.BufferPtr++;
-    if (Pos.BufferPtr == Pos.BufferEnd) {
-      Pos.CurToken++;
-      if (Pos.CurToken < Toks.size())
-        setupBuffer();
-    }
-  }
-
-  static bool isWhitespace(char C) {
-    return C == ' ' || C == '\n' || C == '\r' ||
-           C == '\t' || C == '\f' || C == '\v';
-  }
-
-  void consumeWhitespace() {
-    while (!isEnd()) {
-      if (isWhitespace(peek()))
-        consumeChar();
-      else
-        break;
-    }
-  }
-
-  void formTokenWithChars(Token &Result,
-                          SourceLocation Loc,
-                          const char *TokBegin,
-                          unsigned TokLength,
-                          StringRef Text) {
-    Result.setLocation(Loc);
-    Result.setKind(tok::text);
-    Result.setLength(TokLength);
-#ifndef NDEBUG
-    Result.TextPtr1 = "<UNSET>";
-    Result.TextLen1 = 7;
-#endif
-    Result.setText(Text);
-  }
-
-public:
-  TextTokenRetokenizer(llvm::BumpPtrAllocator &Allocator):
-      Allocator(Allocator) {
-    Pos.CurToken = 0;
-  }
-
-  /// Add a token.
-  /// Returns true on success, false if it seems like we have enough tokens.
-  bool addToken(const Token &Tok) {
-    assert(Tok.is(tok::text));
-    if (Toks.size() >= MaxTokens)
-      return false;
-
-    Toks.push_back(Tok);
-    if (Toks.size() == 1)
-      setupBuffer();
-    return true;
-  }
-
-  /// Extract a word -- sequence of non-whitespace characters.
-  bool lexWord(Token &Tok) {
-    if (isEnd())
-      return false;
-
-    Position SavedPos = Pos;
-
-    consumeWhitespace();
-    SmallString<32> WordText;
-    const char *WordBegin = Pos.BufferPtr;
-    SourceLocation Loc = getSourceLocation();
-    while (!isEnd()) {
-      const char C = peek();
-      if (!isWhitespace(C)) {
-        WordText.push_back(C);
-        consumeChar();
-      } else
-        break;
-    }
-    const unsigned Length = WordText.size();
-    if (Length == 0) {
-      Pos = SavedPos;
-      return false;
-    }
-
-    char *TextPtr = Allocator.Allocate<char>(Length + 1);
-
-    memcpy(TextPtr, WordText.c_str(), Length + 1);
-    StringRef Text = StringRef(TextPtr, Length);
-
-    formTokenWithChars(Tok, Loc, WordBegin,
-                       Pos.BufferPtr - WordBegin, Text);
-    return true;
-  }
-
-  bool lexDelimitedSeq(Token &Tok, char OpenDelim, char CloseDelim) {
-    if (isEnd())
-      return false;
-
-    Position SavedPos = Pos;
-
-    consumeWhitespace();
-    SmallString<32> WordText;
-    const char *WordBegin = Pos.BufferPtr;
-    SourceLocation Loc = getSourceLocation();
-    bool Error = false;
-    if (!isEnd()) {
-      const char C = peek();
-      if (C == OpenDelim) {
-        WordText.push_back(C);
-        consumeChar();
-      } else
-        Error = true;
-    }
-    char C = '\0';
-    while (!Error && !isEnd()) {
-      C = peek();
-      WordText.push_back(C);
-      consumeChar();
-      if (C == CloseDelim)
-        break;
-    }
-    if (!Error && C != CloseDelim)
-      Error = true;
-
-    if (Error) {
-      Pos = SavedPos;
-      return false;
-    }
-
-    const unsigned Length = WordText.size();
-    char *TextPtr = Allocator.Allocate<char>(Length + 1);
-
-    memcpy(TextPtr, WordText.c_str(), Length + 1);
-    StringRef Text = StringRef(TextPtr, Length);
-
-    formTokenWithChars(Tok, Loc, WordBegin,
-                       Pos.BufferPtr - WordBegin, Text);
-    return true;
-  }
-
-  /// Return a text token.  Useful to take tokens back.
-  bool lexText(Token &Tok) {
-    if (isEnd())
-      return false;
-
-    if (Pos.BufferPtr != Pos.BufferStart)
-      formTokenWithChars(Tok, getSourceLocation(),
-                         Pos.BufferPtr, Pos.BufferEnd - Pos.BufferPtr,
-                         StringRef(Pos.BufferPtr,
-                                   Pos.BufferEnd - Pos.BufferPtr));
-    else
-      Tok = Toks[Pos.CurToken];
-
-    Pos.CurToken++;
-    if (Pos.CurToken < Toks.size())
-      setupBuffer();
-    return true;
-  }
 };
 
 } // end namespace comments
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h
index 47cab25..0390799 100644
--- a/include/clang/AST/CommentParser.h
+++ b/include/clang/AST/CommentParser.h
@@ -24,9 +24,15 @@
 class SourceManager;
 
 namespace comments {
+class CommandTraits;
 
 /// Doxygen comment parser.
 class Parser {
+  Parser(const Parser&);         // DO NOT IMPLEMENT
+  void operator=(const Parser&); // DO NOT IMPLEMENT
+
+  friend class TextTokenRetokenizer;
+
   Lexer &L;
 
   Sema &S;
@@ -37,23 +43,14 @@
   /// Source manager for the comment being parsed.
   const SourceManager &SourceMgr;
 
-  template<typename T>
-  ArrayRef<T> copyArray(ArrayRef<T> Source) {
-    size_t Size = Source.size();
-    if (Size != 0) {
-      T *Mem = Allocator.Allocate<T>(Size);
-      std::uninitialized_copy(Source.begin(), Source.end(), Mem);
-      return llvm::makeArrayRef(Mem, Size);
-    } else
-      return llvm::makeArrayRef(static_cast<T *>(NULL), 0);
-  }
-
   DiagnosticsEngine &Diags;
 
   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
     return Diags.Report(Loc, DiagID);
   }
 
+  const CommandTraits &Traits;
+
   /// Current lookahead token.  We can safely assume that all tokens are from
   /// a single source file.
   Token Tok;
@@ -61,15 +58,13 @@
   /// A stack of additional lookahead tokens.
   SmallVector<Token, 8> MoreLATokens;
 
-  SourceLocation consumeToken() {
-    SourceLocation Loc = Tok.getLocation();
+  void consumeToken() {
     if (MoreLATokens.empty())
       L.lex(Tok);
     else {
       Tok = MoreLATokens.back();
       MoreLATokens.pop_back();
     }
-    return Loc;
   }
 
   void putBack(const Token &OldTok) {
@@ -83,7 +78,7 @@
 
     MoreLATokens.push_back(Tok);
     for (const Token *I = &Toks.back(),
-         *B = &Toks.front() + 1;
+         *B = &Toks.front();
          I != B; --I) {
       MoreLATokens.push_back(*I);
     }
@@ -93,17 +88,20 @@
 
 public:
   Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
-         const SourceManager &SourceMgr, DiagnosticsEngine &Diags);
+         const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+         const CommandTraits &Traits);
 
   /// Parse arguments for \\param command.
-  ParamCommandComment *parseParamCommandArgs(
-                                    ParamCommandComment *PC,
-                                    TextTokenRetokenizer &Retokenizer);
+  void parseParamCommandArgs(ParamCommandComment *PC,
+                             TextTokenRetokenizer &Retokenizer);
 
-  BlockCommandComment *parseBlockCommandArgs(
-                                    BlockCommandComment *BC,
-                                    TextTokenRetokenizer &Retokenizer,
-                                    unsigned NumArgs);
+  /// Parse arguments for \\tparam command.
+  void parseTParamCommandArgs(TParamCommandComment *TPC,
+                              TextTokenRetokenizer &Retokenizer);
+
+  void parseBlockCommandArgs(BlockCommandComment *BC,
+                             TextTokenRetokenizer &Retokenizer,
+                             unsigned NumArgs);
 
   BlockCommandComment *parseBlockCommand();
   InlineCommandComment *parseInlineCommand();
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index f8b35d0..e1756ca 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -19,17 +19,20 @@
 #include "clang/AST/Comment.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Allocator.h"
 
 namespace clang {
 class Decl;
-class FunctionDecl;
-class ParmVarDecl;
 class SourceMgr;
 
 namespace comments {
+class CommandTraits;
 
 class Sema {
+  Sema(const Sema&);           // DO NOT IMPLEMENT
+  void operator=(const Sema&); // DO NOT IMPLEMENT
+
   /// Allocator for AST nodes.
   llvm::BumpPtrAllocator &Allocator;
 
@@ -38,21 +41,29 @@
 
   DiagnosticsEngine &Diags;
 
-  /// Declaration this comment is attached to.
-  const Decl *ThisDecl;
+  const CommandTraits &Traits;
 
-  /// Parameters that can be referenced by \\param if \c ThisDecl is something
-  /// that we consider a "function".
-  /// Contains a valid value if \c IsThisDeclInspected is true.
-  ArrayRef<const ParmVarDecl *> ParamVars;
+  /// Information about the declaration this comment is attached to.
+  DeclInfo *ThisDeclInfo;
 
-  /// True if we extracted all important information from \c ThisDecl into
-  /// \c Sema members.
-  unsigned IsThisDeclInspected : 1;
+  /// Comment AST nodes that correspond to \c ParamVars for which we have
+  /// found a \\param command or NULL if no documentation was found so far.
+  ///
+  /// Has correct size and contains valid values if \c DeclInfo->IsFilled is
+  /// true.
+  llvm::SmallVector<ParamCommandComment *, 8> ParamVarDocs;
 
-  /// Is \c ThisDecl something that we consider a "function".
-  /// Contains a valid value if \c IsThisDeclInspected is true.
-  unsigned IsFunctionDecl : 1;
+  /// Comment AST nodes that correspond to parameter names in
+  /// \c TemplateParameters.
+  ///
+  /// Contains a valid value if \c DeclInfo->IsFilled is true.
+  llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
+
+  /// AST node for the \\brief command and its aliases.
+  const BlockCommandComment *BriefCommand;
+
+  /// AST node for the \\returns command and its aliases.
+  const BlockCommandComment *ReturnsCommand;
 
   DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
     return Diags.Report(Loc, DiagID);
@@ -64,10 +75,22 @@
 
 public:
   Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
-       DiagnosticsEngine &Diags);
+       DiagnosticsEngine &Diags, const CommandTraits &Traits);
 
   void setDecl(const Decl *D);
 
+  /// Returns a copy of array, owned by Sema's allocator.
+  template<typename T>
+  ArrayRef<T> copyArray(ArrayRef<T> Source) {
+    size_t Size = Source.size();
+    if (Size != 0) {
+      T *Mem = Allocator.Allocate<T>(Size);
+      std::uninitialized_copy(Source.begin(), Source.end(), Mem);
+      return llvm::makeArrayRef(Mem, Size);
+    } else
+      return llvm::makeArrayRef(static_cast<T *>(NULL), 0);
+  }
+
   ParagraphComment *actOnParagraphComment(
       ArrayRef<InlineContentComment *> Content);
 
@@ -75,31 +98,40 @@
                                               SourceLocation LocEnd,
                                               StringRef Name);
 
-  BlockCommandComment *actOnBlockCommandArgs(
-                              BlockCommandComment *Command,
-                              ArrayRef<BlockCommandComment::Argument> Args);
+  void actOnBlockCommandArgs(BlockCommandComment *Command,
+                             ArrayRef<BlockCommandComment::Argument> Args);
 
-  BlockCommandComment *actOnBlockCommandFinish(BlockCommandComment *Command,
-                                               ParagraphComment *Paragraph);
+  void actOnBlockCommandFinish(BlockCommandComment *Command,
+                               ParagraphComment *Paragraph);
 
   ParamCommandComment *actOnParamCommandStart(SourceLocation LocBegin,
                                               SourceLocation LocEnd,
                                               StringRef Name);
 
-  ParamCommandComment *actOnParamCommandDirectionArg(
-                                            ParamCommandComment *Command,
-                                            SourceLocation ArgLocBegin,
-                                            SourceLocation ArgLocEnd,
-                                            StringRef Arg);
+  void actOnParamCommandDirectionArg(ParamCommandComment *Command,
+                                     SourceLocation ArgLocBegin,
+                                     SourceLocation ArgLocEnd,
+                                     StringRef Arg);
 
-  ParamCommandComment *actOnParamCommandParamNameArg(
-                                            ParamCommandComment *Command,
-                                            SourceLocation ArgLocBegin,
-                                            SourceLocation ArgLocEnd,
-                                            StringRef Arg);
+  void actOnParamCommandParamNameArg(ParamCommandComment *Command,
+                                     SourceLocation ArgLocBegin,
+                                     SourceLocation ArgLocEnd,
+                                     StringRef Arg);
 
-  ParamCommandComment *actOnParamCommandFinish(ParamCommandComment *Command,
-                                               ParagraphComment *Paragraph);
+  void actOnParamCommandFinish(ParamCommandComment *Command,
+                               ParagraphComment *Paragraph);
+
+  TParamCommandComment *actOnTParamCommandStart(SourceLocation LocBegin,
+                                                SourceLocation LocEnd,
+                                                StringRef Name);
+
+  void actOnTParamCommandParamNameArg(TParamCommandComment *Command,
+                                      SourceLocation ArgLocBegin,
+                                      SourceLocation ArgLocEnd,
+                                      StringRef Arg);
+
+  void actOnTParamCommandFinish(TParamCommandComment *Command,
+                                ParagraphComment *Paragraph);
 
   InlineCommandComment *actOnInlineCommand(SourceLocation CommandLocBegin,
                                            SourceLocation CommandLocEnd,
@@ -126,11 +158,10 @@
   VerbatimBlockLineComment *actOnVerbatimBlockLine(SourceLocation Loc,
                                                    StringRef Text);
 
-  VerbatimBlockComment *actOnVerbatimBlockFinish(
-                              VerbatimBlockComment *Block,
-                              SourceLocation CloseNameLocBegin,
-                              StringRef CloseName,
-                              ArrayRef<VerbatimBlockLineComment *> Lines);
+  void actOnVerbatimBlockFinish(VerbatimBlockComment *Block,
+                                SourceLocation CloseNameLocBegin,
+                                StringRef CloseName,
+                                ArrayRef<VerbatimBlockLineComment *> Lines);
 
   VerbatimLineComment *actOnVerbatimLine(SourceLocation LocBegin,
                                          StringRef Name,
@@ -140,11 +171,10 @@
   HTMLStartTagComment *actOnHTMLStartTagStart(SourceLocation LocBegin,
                                               StringRef TagName);
 
-  HTMLStartTagComment *actOnHTMLStartTagFinish(
-                              HTMLStartTagComment *Tag,
-                              ArrayRef<HTMLStartTagComment::Attribute> Attrs,
-                              SourceLocation GreaterLoc,
-                              bool IsSelfClosing);
+  void actOnHTMLStartTagFinish(HTMLStartTagComment *Tag,
+                               ArrayRef<HTMLStartTagComment::Attribute> Attrs,
+                               SourceLocation GreaterLoc,
+                               bool IsSelfClosing);
 
   HTMLEndTagComment *actOnHTMLEndTag(SourceLocation LocBegin,
                                      SourceLocation LocEnd,
@@ -154,11 +184,19 @@
 
   void checkBlockCommandEmptyParagraph(BlockCommandComment *Command);
 
+  void checkReturnsCommand(const BlockCommandComment *Command);
+
+  /// Emit diagnostics about duplicate block commands that should be
+  /// used only once per comment, e.g., \\brief and \\returns.
+  void checkBlockCommandDuplicate(const BlockCommandComment *Command);
+
   bool isFunctionDecl();
+  bool isTemplateOrSpecialization();
+
   ArrayRef<const ParmVarDecl *> getParamVars();
 
-  /// Extract all important semantic information from \c ThisDecl into
-  /// \c Sema members.
+  /// Extract all important semantic information from
+  /// \c ThisDeclInfo->ThisDecl into \c ThisDeclInfo members.
   void inspectThisDecl();
 
   /// Returns index of a function parameter with a given name.
@@ -170,11 +208,13 @@
   unsigned correctTypoInParmVarReference(StringRef Typo,
                                          ArrayRef<const ParmVarDecl *> ParamVars);
 
-  bool isBlockCommand(StringRef Name);
-  bool isParamCommand(StringRef Name);
-  unsigned getBlockCommandNumArgs(StringRef Name);
+  bool resolveTParamReference(StringRef Name,
+                              const TemplateParameterList *TemplateParameters,
+                              SmallVectorImpl<unsigned> *Position);
 
-  bool isInlineCommand(StringRef Name) const;
+  StringRef correctTypoInTParamReference(
+                              StringRef Typo,
+                              const TemplateParameterList *TemplateParameters);
 
   InlineCommandComment::RenderKind
   getInlineCommandRenderKind(StringRef Name) const;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index b1f9180..0f59609 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -857,7 +857,10 @@
   static void printGroup(Decl** Begin, unsigned NumDecls,
                          raw_ostream &Out, const PrintingPolicy &Policy,
                          unsigned Indentation = 0);
+  // Debuggers don't usually respect default arguments.
   LLVM_ATTRIBUTE_USED void dump() const;
+  void dump(raw_ostream &Out) const;
+  // Debuggers don't usually respect default arguments.
   LLVM_ATTRIBUTE_USED void dumpXML() const;
   void dumpXML(raw_ostream &OS) const;
 
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 0d498fe..2d95f03 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1295,7 +1295,7 @@
   ///
   /// \returns true if this class is virtually derived from Base,
   /// false otherwise.
-  bool isVirtuallyDerivedFrom(CXXRecordDecl *Base) const;
+  bool isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const;
 
   /// \brief Determine whether this class is provably not derived from
   /// the type \p Base.
@@ -1549,6 +1549,9 @@
   bool isStatic() const { return getStorageClass() == SC_Static; }
   bool isInstance() const { return !isStatic(); }
 
+  bool isConst() { return getType()->castAs<FunctionType>()->isConst(); }
+  bool isVolatile() { return getType()->castAs<FunctionType>()->isVolatile(); }
+
   bool isVirtual() const {
     CXXMethodDecl *CD =
       cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
@@ -1643,14 +1646,17 @@
   /// \brief Find the method in RD that corresponds to this one.
   ///
   /// Find if RD or one of the classes it inherits from override this method.
-  /// If so, return it. RD is assumed to be a base class of the class defining
-  /// this method (or be the class itself).
+  /// If so, return it. RD is assumed to be a subclass of the class defining
+  /// this method (or be the class itself), unless MayBeBase is set to true.
   CXXMethodDecl *
-  getCorrespondingMethodInClass(const CXXRecordDecl *RD);
+  getCorrespondingMethodInClass(const CXXRecordDecl *RD,
+                                bool MayBeBase = false);
 
   const CXXMethodDecl *
-  getCorrespondingMethodInClass(const CXXRecordDecl *RD) const {
-    return const_cast<CXXMethodDecl*>(this)->getCorrespondingMethodInClass(RD);
+  getCorrespondingMethodInClass(const CXXRecordDecl *RD,
+                                bool MayBeBase = false) const {
+    return const_cast<CXXMethodDecl *>(this)
+              ->getCorrespondingMethodInClass(RD, MayBeBase);
   }
 
   // Implement isa/cast/dyncast/etc.
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index 63cdac5..cda6ae5 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -26,7 +26,11 @@
 
 class DeclGroup {
   // FIXME: Include a TypeSpecifier object.
-  unsigned NumDecls;
+  union {
+    unsigned NumDecls;
+
+    Decl *Aligner;
+  };
 
 private:
   DeclGroup() : NumDecls(0) {}
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index b8abe97..867b465 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -67,7 +67,7 @@
 
 DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
   DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
-  if (hasExternalVisibleStorage())
+  if (Primary->hasExternalVisibleStorage())
     getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
   if (StoredDeclsMap *Map = Primary->buildLookup())
     return all_lookups_iterator(Map->begin(), Map->end());
@@ -76,7 +76,7 @@
 
 DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
   DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
-  if (hasExternalVisibleStorage())
+  if (Primary->hasExternalVisibleStorage())
     getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
   if (StoredDeclsMap *Map = Primary->buildLookup())
     return all_lookups_iterator(Map->end(), Map->end());
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 0b3e56e..6c39f2c 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -939,8 +939,13 @@
   }
   ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
 
-  // Lookup a method in the classes implementation hierarchy.
-  ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel, bool Instance=true);
+  /// \brief Lookup a method in the classes implementation hierarchy.
+  ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
+                                      bool Instance=true) const;
+
+  ObjCMethodDecl *lookupPrivateClassMethod(const Selector &Sel) {
+    return lookupPrivateMethod(Sel, false);
+  }
 
   SourceLocation getEndOfDefinitionLoc() const { 
     if (!hasDefinition())
@@ -1519,15 +1524,6 @@
     return Id ? Id->getNameStart() : "";
   }
 
-  /// getNameAsCString - Get the name of identifier for the class
-  /// interface associated with this implementation as a C string
-  /// (const char*).
-  //
-  // FIXME: Deprecated, move clients to getName().
-  const char *getNameAsCString() const {
-    return Id ? Id->getNameStart() : "";
-  }
-
   /// @brief Get the name of the class associated with this interface.
   //
   // FIXME: Deprecated, move clients to getName().
@@ -1648,15 +1644,6 @@
     return getIdentifier()->getName();
   }
 
-  /// getNameAsCString - Get the name of identifier for the class
-  /// interface associated with this implementation as a C string
-  /// (const char*).
-  //
-  // FIXME: Move to StringRef API.
-  const char *getNameAsCString() const {
-    return getName().data();
-  }
-
   /// @brief Get the name of the class associated with this interface.
   //
   // FIXME: Move to StringRef API.
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index d9cf0ad..89c003c 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -510,9 +510,8 @@
   bool isEvaluatable(const ASTContext &Ctx) const;
 
   /// HasSideEffects - This routine returns true for all those expressions
-  /// which must be evaluated each time and must not be optimized away
-  /// or evaluated at compile time. Example is a function call, volatile
-  /// variable read.
+  /// which have any effect other than producing a value. Example is a function
+  /// call, volatile variable read, or throwing an exception.
   bool HasSideEffects(const ASTContext &Ctx) const;
 
   /// \brief Determine whether this expression involves a call to any function
@@ -542,8 +541,15 @@
     /// \brief Expression is not a Null pointer constant.
     NPCK_NotNull = 0,
 
-    /// \brief Expression is a Null pointer constant built from a zero integer.
-    NPCK_ZeroInteger,
+    /// \brief Expression is a Null pointer constant built from a zero integer
+    /// expression that is not a simple, possibly parenthesized, zero literal.
+    /// C++ Core Issue 903 will classify these expressions as "not pointers"
+    /// once it is adopted.
+    /// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
+    NPCK_ZeroExpression,
+
+    /// \brief Expression is a Null pointer constant built from a literal zero.
+    NPCK_ZeroLiteral,
 
     /// \brief Expression is a C++0X nullptr.
     NPCK_CXX0X_nullptr,
@@ -596,6 +602,10 @@
     return cast<Expr>(Stmt::IgnoreImplicit());
   }
 
+  const Expr *IgnoreImplicit() const LLVM_READONLY {
+    return const_cast<Expr*>(this)->IgnoreImplicit();
+  }
+
   /// IgnoreParens - Ignore parentheses.  If this Expr is a ParenExpr, return
   ///  its subexpression.  If that subexpression is also a ParenExpr,
   ///  then this method recursively returns its subexpression, and so forth.
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 1e2e7af..a2355ca 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -499,6 +499,10 @@
       Operand = (TypeSourceInfo*)0;
   }
 
+  /// Determine whether this typeid has a type operand which is potentially
+  /// evaluated, per C++11 [expr.typeid]p3.
+  bool isPotentiallyEvaluated() const;
+
   bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
 
   /// \brief Retrieves the type operand of this typeid() expression after
@@ -1254,7 +1258,8 @@
              ArrayRef<Expr *> CaptureInits,
              ArrayRef<VarDecl *> ArrayIndexVars,
              ArrayRef<unsigned> ArrayIndexStarts,
-             SourceLocation ClosingBrace);
+             SourceLocation ClosingBrace,
+             bool ContainsUnexpandedParameterPack);
 
   /// \brief Construct an empty lambda expression.
   LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool HasArrayIndexVars)
@@ -1276,8 +1281,11 @@
   
   /// \brief Retrieve the complete set of array-index variables.
   VarDecl **getArrayIndexVars() const {
+    unsigned ArrayIndexSize =
+        llvm::RoundUpToAlignment(sizeof(unsigned) * (NumCaptures + 1),
+                                 llvm::alignOf<VarDecl*>());
     return reinterpret_cast<VarDecl **>(
-             getArrayIndexStarts() + NumCaptures + 1);
+        reinterpret_cast<char*>(getArrayIndexStarts()) + ArrayIndexSize);
   }
 
 public:
@@ -1292,7 +1300,8 @@
                             ArrayRef<Expr *> CaptureInits,
                             ArrayRef<VarDecl *> ArrayIndexVars,
                             ArrayRef<unsigned> ArrayIndexStarts,
-                            SourceLocation ClosingBrace);
+                            SourceLocation ClosingBrace,
+                            bool ContainsUnexpandedParameterPack);
 
   /// \brief Construct a new lambda expression that will be deserialized from
   /// an external source.
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 2e34dc8..e0b1d32 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -34,19 +34,19 @@
 struct PrintingPolicy {
   /// \brief Create a default printing policy for C.
   PrintingPolicy(const LangOptions &LO)
-    : Indentation(2), LangOpts(LO), SuppressSpecifiers(false),
+    : LangOpts(LO), Indentation(2), SuppressSpecifiers(false),
       SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false),
       SuppressUnwrittenScope(false), SuppressInitializers(false),
-      Dump(false), ConstantArraySizeAsWritten(false),
-      AnonymousTagLocations(true), SuppressStrongLifetime(false),
-      Bool(LO.Bool) { }
-
-  /// \brief The number of spaces to use to indent each line.
-  unsigned Indentation : 8;
+      ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
+      SuppressStrongLifetime(false), Bool(LO.Bool),
+      TerseOutput(false), DumpSourceManager(0) { }
 
   /// \brief What language we're printing.
   LangOptions LangOpts;
 
+  /// \brief The number of spaces to use to indent each line.
+  unsigned Indentation : 8;
+
   /// \brief Whether we should suppress printing of the actual specifiers for
   /// the given type or declaration.
   ///
@@ -103,12 +103,6 @@
   /// internal initializer constructed for x will not be printed.
   bool SuppressInitializers : 1;
 
-  /// \brief True when we are "dumping" rather than "pretty-printing",
-  /// where dumping involves printing the internal details of the AST
-  /// and pretty-printing involves printing something similar to
-  /// source code.
-  bool Dump : 1;
-
   /// \brief Whether we should print the sizes of constant array expressions
   /// as written in the sources.
   ///
@@ -139,6 +133,19 @@
   /// \brief Whether we can use 'bool' rather than '_Bool', even if the language
   /// doesn't actually have 'bool' (because, e.g., it is defined as a macro).
   unsigned Bool : 1;
+
+  /// \brief Provide a 'terse' output.
+  ///
+  /// For example, in this mode we don't print function bodies, class members,
+  /// declarations inside namespaces etc.  Effectively, this should print
+  /// only the requested declaration.
+  unsigned TerseOutput : 1;
+
+  /// \brief If we are "dumping" rather than "pretty-printing", this points to
+  /// a SourceManager which will be used to dump SourceLocations. Dumping
+  /// involves printing the internal details of the AST and pretty-printing
+  /// involves printing something similar to source code.
+  SourceManager *DumpSourceManager;
 };
 
 } // end namespace clang
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index 370f412..630626b 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -17,6 +17,11 @@
 
 class ASTContext;
 class ASTReader;
+class Decl;
+
+namespace comments {
+  class FullComment;
+} // end namespace comments
 
 class RawComment {
 public:
@@ -48,6 +53,7 @@
     return Kind == RCK_Merged;
   }
 
+  /// Is this comment attached to any declaration?
   bool isAttached() const LLVM_READONLY {
     return IsAttached;
   }
@@ -107,6 +113,9 @@
     return extractBriefText(Context);
   }
 
+  /// Parse the comment, assuming it is attached to decl \c D.
+  comments::FullComment *parse(const ASTContext &Context, const Decl *D) const;
+
 private:
   SourceRange Range;
 
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 2e56a48..60d7595 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2141,7 +2141,9 @@
   return true; // no child statements to loop through.
 })
 DEF_TRAVERSE_STMT(ChooseExpr, { })
-DEF_TRAVERSE_STMT(CompoundLiteralExpr, { })
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+  TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
 DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { })
 DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { })
 DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { })
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 2ac503a..fc21631 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -20,6 +20,7 @@
 #include "clang/AST/StmtIterator.h"
 #include "clang/AST/DeclGroup.h"
 #include "clang/AST/Attr.h"
+#include "clang/Lex/Token.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
@@ -372,15 +373,9 @@
 
   /// dumpPretty/printPretty - These two methods do a "pretty print" of the AST
   /// back to its original source language syntax.
-  void dumpPretty(ASTContext& Context) const;
+  void dumpPretty(ASTContext &Context) const;
   void printPretty(raw_ostream &OS, PrinterHelper *Helper,
                    const PrintingPolicy &Policy,
-                   unsigned Indentation = 0) const {
-    printPretty(OS, *(ASTContext*)0, Helper, Policy, Indentation);
-  }
-  void printPretty(raw_ostream &OS, ASTContext &Context,
-                   PrinterHelper *Helper,
-                   const PrintingPolicy &Policy,
                    unsigned Indentation = 0) const;
 
   /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
@@ -1376,7 +1371,6 @@
 
   bool IsSimple;
   bool IsVolatile;
-  bool MSAsm;
 
   unsigned NumOutputs;
   unsigned NumInputs;
@@ -1390,10 +1384,10 @@
 
 public:
   AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, bool isvolatile,
-          bool msasm, unsigned numoutputs, unsigned numinputs,
-          IdentifierInfo **names, StringLiteral **constraints,
-          Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
-          StringLiteral **clobbers, SourceLocation rparenloc);
+          unsigned numoutputs, unsigned numinputs, IdentifierInfo **names,
+          StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr,
+          unsigned numclobbers, StringLiteral **clobbers,
+          SourceLocation rparenloc);
 
   /// \brief Build an empty inline-assembly statement.
   explicit AsmStmt(EmptyShell Empty) : Stmt(AsmStmtClass, Empty),
@@ -1408,8 +1402,6 @@
   void setVolatile(bool V) { IsVolatile = V; }
   bool isSimple() const { return IsSimple; }
   void setSimple(bool V) { IsSimple = V; }
-  bool isMSAsm() const { return MSAsm; }
-  void setMSAsm(bool V) { MSAsm = V; }
 
   //===--- Asm String Analysis ---===//
 
@@ -1619,23 +1611,41 @@
 /// MSAsmStmt - This represents a MS inline-assembly statement extension.
 ///
 class MSAsmStmt : public Stmt {
-  SourceLocation AsmLoc, EndLoc;
+  SourceLocation AsmLoc, LBraceLoc, EndLoc;
   std::string AsmStr;
 
   bool IsSimple;
   bool IsVolatile;
 
+  unsigned NumAsmToks;
+  unsigned NumInputs;
+  unsigned NumOutputs;
+  unsigned NumClobbers;
+
+  Token *AsmToks;
+  IdentifierInfo **Names;
   Stmt **Exprs;
+  StringRef *Clobbers;
 
 public:
-  MSAsmStmt(ASTContext &C, SourceLocation asmloc, std::string &asmstr,
+  MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc,
+            bool issimple, bool isvolatile, ArrayRef<Token> asmtoks,
+            ArrayRef<IdentifierInfo*> inputs, ArrayRef<IdentifierInfo*> outputs,
+            StringRef asmstr, ArrayRef<StringRef> clobbers,
             SourceLocation endloc);
 
   SourceLocation getAsmLoc() const { return AsmLoc; }
   void setAsmLoc(SourceLocation L) { AsmLoc = L; }
+  SourceLocation getLBraceLoc() const { return LBraceLoc; }
+  void setLBraceLoc(SourceLocation L) { LBraceLoc = L; }
   SourceLocation getEndLoc() const { return EndLoc; }
   void setEndLoc(SourceLocation L) { EndLoc = L; }
 
+  bool hasBraces() const { return LBraceLoc.isValid(); }
+
+  unsigned getNumAsmToks() { return NumAsmToks; }
+  Token *getAsmToks() { return AsmToks; }
+
   bool isVolatile() const { return IsVolatile; }
   void setVolatile(bool V) { IsVolatile = V; }
   bool isSimple() const { return IsSimple; }
@@ -1649,6 +1659,9 @@
 
   //===--- Other ---===//
 
+  unsigned getNumClobbers() const { return NumClobbers; }
+  StringRef getClobber(unsigned i) const { return Clobbers[i]; }
+
   SourceRange getSourceRange() const LLVM_READONLY {
     return SourceRange(AsmLoc, EndLoc);
   }
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 54c9f2c..5047028 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -510,17 +510,23 @@
 /// This is safe to be used inside an AST node, in contrast with
 /// TemplateArgumentListInfo.
 struct ASTTemplateArgumentListInfo {
-  /// \brief The source location of the left angle bracket ('<');
+  /// \brief The source location of the left angle bracket ('<').
   SourceLocation LAngleLoc;
   
-  /// \brief The source location of the right angle bracket ('>');
+  /// \brief The source location of the right angle bracket ('>').
   SourceLocation RAngleLoc;
   
-  /// \brief The number of template arguments in TemplateArgs.
-  /// The actual template arguments (if any) are stored after the
-  /// ExplicitTemplateArgumentList structure.
-  unsigned NumTemplateArgs;
-  
+  union {
+    /// \brief The number of template arguments in TemplateArgs.
+    /// The actual template arguments (if any) are stored after the
+    /// ExplicitTemplateArgumentList structure.
+    unsigned NumTemplateArgs;
+
+    /// Force ASTTemplateArgumentListInfo to the right alignment
+    /// for the following array of TemplateArgumentLocs.
+    void *Aligner;
+  };
+
   /// \brief Retrieve the template arguments
   TemplateArgumentLoc *getTemplateArgs() {
     return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 4d6e917..1d6bd5c 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -378,8 +378,6 @@
     return hasConst();
   }
 
-  bool isSupersetOf(Qualifiers Other) const;
-
   /// \brief Determine whether this set of qualifiers is a strict superset of
   /// another set of qualifiers, not considering qualifier compatibility.
   bool isStrictSupersetOf(Qualifiers Other) const;
@@ -1140,8 +1138,6 @@
     unsigned TC : 8;
 
     /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]).
-    /// Note that this should stay at the end of the ivars for Type so that
-    /// subclasses can pack their bitfields into the same word.
     unsigned Dependent : 1;
 
     /// \brief Whether this type somehow involves a template parameter, even
@@ -2680,6 +2676,9 @@
   bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); }
   CallingConv getCallConv() const { return getExtInfo().getCC(); }
   ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); }
+  bool isConst() const { return getTypeQuals() & Qualifiers::Const; }
+  bool isVolatile() const { return getTypeQuals() & Qualifiers::Volatile; }
+  bool isRestrict() const { return getTypeQuals() & Qualifiers::Restrict; }
 
   /// \brief Determine the type of an expression that calls a function of
   /// this type.
@@ -2847,6 +2846,8 @@
     } else if (EPI.ExceptionSpecType == EST_Uninstantiated) {
       EPI.ExceptionSpecDecl = getExceptionSpecDecl();
       EPI.ExceptionSpecTemplate = getExceptionSpecTemplate();
+    } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
+      EPI.ExceptionSpecDecl = getExceptionSpecDecl();
     }
     if (hasAnyConsumedArgs())
       EPI.ConsumedArguments = getConsumedArgsBuffer();
@@ -2890,11 +2891,13 @@
     // NoexceptExpr sits where the arguments end.
     return *reinterpret_cast<Expr *const *>(arg_type_end());
   }
-  /// \brief If this function type has an uninstantiated exception
-  /// specification, this is the function whose exception specification
-  /// is represented by this type.
+  /// \brief If this function type has an exception specification which hasn't
+  /// been determined yet (either because it has not been evaluated or because
+  /// it has not been instantiated), this is the function whose exception
+  /// specification is represented by this type.
   FunctionDecl *getExceptionSpecDecl() const {
-    if (getExceptionSpecType() != EST_Uninstantiated)
+    if (getExceptionSpecType() != EST_Uninstantiated &&
+        getExceptionSpecType() != EST_Unevaluated)
       return 0;
     return reinterpret_cast<FunctionDecl * const *>(arg_type_end())[0];
   }
@@ -2909,7 +2912,7 @@
   }
   bool isNothrow(ASTContext &Ctx) const {
     ExceptionSpecificationType EST = getExceptionSpecType();
-    assert(EST != EST_Delayed && EST != EST_Uninstantiated);
+    assert(EST != EST_Unevaluated && EST != EST_Uninstantiated);
     if (EST == EST_DynamicNone || EST == EST_BasicNoexcept)
       return true;
     if (EST != EST_ComputedNoexcept)
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 1d1c1d1..11a878d 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1061,7 +1061,6 @@
 struct FunctionLocInfo {
   SourceLocation LocalRangeBegin;
   SourceLocation LocalRangeEnd;
-  bool TrailingReturn;
 };
 
 /// \brief Wrapper for source info for functions.
@@ -1084,13 +1083,6 @@
     getLocalData()->LocalRangeEnd = L;
   }
 
-  bool getTrailingReturn() const {
-    return getLocalData()->TrailingReturn;
-  }
-  void setTrailingReturn(bool Trailing) {
-    getLocalData()->TrailingReturn = Trailing;
-  }
-
   ArrayRef<ParmVarDecl *> getParams() const {
     return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
   }
@@ -1119,7 +1111,6 @@
   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
     setLocalRangeBegin(Loc);
     setLocalRangeEnd(Loc);
-    setTrailingReturn(false);
     for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
       setArg(i, NULL);
   }
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 61571e5..8e797c1 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -50,21 +50,22 @@
 #include "clang/ASTMatchers/ASTMatchersMacros.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Regex.h"
+#include <iterator>
 
 namespace clang {
 namespace ast_matchers {
 
 /// \brief Maps string IDs to AST nodes matched by parts of a matcher.
 ///
-/// The bound nodes are generated by adding id(...) matchers into the
-/// match expression around the matchers for the nodes we want to access later.
+/// The bound nodes are generated by calling \c bind("id") on the node matchers
+/// of the nodes we want to access later.
 ///
-/// The instances of BoundNodes are created by MatchFinder when the user's
+/// The instances of BoundNodes are created by \c MatchFinder when the user's
 /// callbacks are executed every time a match is found.
 class BoundNodes {
 public:
-  /// \brief Returns the AST node bound to 'ID'.
-  /// Returns NULL if there was no node bound to 'ID' or if there is a node but
+  /// \brief Returns the AST node bound to \c ID.
+  /// Returns NULL if there was no node bound to \c ID or if there is a node but
   /// it cannot be converted to the specified type.
   /// FIXME: We'll need one of those for every base type.
   /// @{
@@ -99,9 +100,9 @@
   friend class internal::BoundNodesTree;
 };
 
-/// \brief If the provided matcher matches a node, binds the node to 'ID'.
+/// \brief If the provided matcher matches a node, binds the node to \c ID.
 ///
-/// FIXME: Add example for accessing it.
+/// FIXME: Do we want to support this now that we have bind()?
 template <typename T>
 internal::Matcher<T> id(const std::string &ID,
                         const internal::BindableMatcher<T> &InnerMatcher) {
@@ -120,44 +121,75 @@
 ///
 /// Useful when another matcher requires a child matcher, but there's no
 /// additional constraint. This will often be used with an explicit conversion
-/// to a internal::Matcher<> type such as TypeMatcher.
+/// to an \c internal::Matcher<> type such as \c TypeMatcher.
 ///
-/// Example: DeclarationMatcher(anything()) matches all declarations, e.g.,
+/// Example: \c DeclarationMatcher(anything()) matches all declarations, e.g.,
+/// \code
 /// "int* p" and "void f()" in
 ///   int* p;
 ///   void f();
+/// \endcode
+///
+/// Usable as: Any Matcher
 inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() {
   return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>();
 }
 
+/// \brief Matches declarations.
+///
+/// Examples matches \c X, \c C, and the friend declaration inside \c C;
+/// \code
+///   void X();
+///   class C {
+///     friend X;
+///   };
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<Decl, Decl> decl;
+
 /// \brief Matches a declaration of anything that could have a name.
 ///
-/// Example matches X, S, the anonymous union type, i, and U;
+/// Example matches \c X, \c S, the anonymous union type, \c i, and \c U;
+/// \code
 ///   typedef int X;
 ///   struct S {
 ///     union {
 ///       int i;
 ///     } U;
 ///   };
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Decl,
   NamedDecl> nameableDeclaration;
 
 /// \brief Matches C++ class declarations.
 ///
-/// Example matches X, Z
+/// Example matches \c X, \c Z
+/// \code
 ///   class X;
 ///   template<class T> class Z {};
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Decl,
   CXXRecordDecl> record;
 
+/// \brief Matches C++ class template declarations.
+///
+/// Example matches \c Z
+/// \code
+///   template<class T> class Z {};
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  ClassTemplateDecl> classTemplate;
+
 /// \brief Matches C++ class template specializations.
 ///
 /// Given
+/// \code
 ///   template<typename T> class A {};
 ///   template<> class A<double> {};
 ///   A<int> a;
+/// \endcode
 /// classTemplateSpecialization()
 ///   matches the specializations \c A<int> and \c A<double>
 const internal::VariadicDynCastAllOfMatcher<
@@ -165,85 +197,174 @@
   ClassTemplateSpecializationDecl> classTemplateSpecialization;
 
 /// \brief Matches classTemplateSpecializations that have at least one
-/// TemplateArgument matching the given Matcher.
+/// TemplateArgument matching the given InnerMatcher.
 ///
 /// Given
+/// \code
 ///   template<typename T> class A {};
 ///   template<> class A<double> {};
 ///   A<int> a;
+/// \endcode
 /// classTemplateSpecialization(hasAnyTemplateArgument(
 ///     refersToType(asString("int"))))
 ///   matches the specialization \c A<int>
 AST_MATCHER_P(ClassTemplateSpecializationDecl, hasAnyTemplateArgument,
-              internal::Matcher<TemplateArgument>, Matcher) {
+              internal::Matcher<TemplateArgument>, InnerMatcher) {
   const TemplateArgumentList &List = Node.getTemplateArgs();
   for (unsigned i = 0; i < List.size(); ++i) {
-    if (Matcher.matches(List.get(i), Finder, Builder))
+    if (InnerMatcher.matches(List.get(i), Finder, Builder))
       return true;
   }
   return false;
 }
 
+/// \brief Matches expressions that match InnerMatcher after any implicit casts
+/// are stripped off.
+///
+/// Parentheses and explicit casts are not discarded.
+/// Given
+/// \code
+///   int arr[5];
+///   int a = 0;
+///   char b = 0;
+///   const int c = a;
+///   int *d = arr;
+///   long e = (long) 0l;
+/// \endcode
+/// The matchers
+/// \code
+///    variable(hasInitializer(ignoringImpCasts(integerLiteral())))
+///    variable(hasInitializer(ignoringImpCasts(declarationReference())))
+/// \endcode
+/// would match the declarations for a, b, c, and d, but not e.
+/// While
+/// \code
+///    variable(hasInitializer(integerLiteral()))
+///    variable(hasInitializer(declarationReference()))
+/// \endcode
+/// only match the declarations for b, c, and d.
+AST_MATCHER_P(Expr, ignoringImpCasts,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreImpCasts(), Finder, Builder);
+}
+
+/// \brief Matches expressions that match InnerMatcher after parentheses and
+/// casts are stripped off.
+///
+/// Implicit and non-C Style casts are also discarded.
+/// Given
+/// \code
+///   int a = 0;
+///   char b = (0);
+///   void* c = reinterpret_cast<char*>(0);
+///   char d = char(0);
+/// \endcode
+/// The matcher
+///    variable(hasInitializer(ignoringParenCasts(integerLiteral())))
+/// would match the declarations for a, b, c, and d.
+/// while
+///    variable(hasInitializer(integerLiteral()))
+/// only match the declaration for a.
+AST_MATCHER_P(Expr, ignoringParenCasts, internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreParenCasts(), Finder, Builder);
+}
+
+/// \brief Matches expressions that match InnerMatcher after implicit casts and
+/// parentheses are stripped off.
+///
+/// Explicit casts are not discarded.
+/// Given
+/// \code
+///   int arr[5];
+///   int a = 0;
+///   char b = (0);
+///   const int c = a;
+///   int *d = (arr);
+///   long e = ((long) 0l);
+/// \endcode
+/// The matchers
+///    variable(hasInitializer(ignoringParenImpCasts(
+///       integerLiteral())))
+///    variable(hasInitializer(ignoringParenImpCasts(
+///       declarationReference())))
+/// would match the declarations for a, b, c, and d, but not e.
+/// while
+///    variable(hasInitializer(integerLiteral()))
+///    variable(hasInitializer(declarationReference()))
+/// would only match the declaration for a.
+AST_MATCHER_P(Expr, ignoringParenImpCasts,
+              internal::Matcher<Expr>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder);
+}
+
 /// \brief Matches classTemplateSpecializations where the n'th TemplateArgument
-/// matches the given Matcher.
+/// matches the given InnerMatcher.
 ///
 /// Given
+/// \code
 ///   template<typename T, typename U> class A {};
 ///   A<bool, int> b;
 ///   A<int, bool> c;
+/// \endcode
 /// classTemplateSpecialization(hasTemplateArgument(
 ///     1, refersToType(asString("int"))))
 ///   matches the specialization \c A<bool, int>
 AST_MATCHER_P2(ClassTemplateSpecializationDecl, hasTemplateArgument,
-               unsigned, N, internal::Matcher<TemplateArgument>, Matcher) {
+               unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
   const TemplateArgumentList &List = Node.getTemplateArgs();
   if (List.size() <= N)
     return false;
-  return Matcher.matches(List.get(N), Finder, Builder);
+  return InnerMatcher.matches(List.get(N), Finder, Builder);
 }
 
 /// \brief Matches a TemplateArgument that refers to a certain type.
 ///
 /// Given
+/// \code
 ///   struct X {};
 ///   template<typename T> struct A {};
 ///   A<X> a;
+/// \endcode
 /// classTemplateSpecialization(hasAnyTemplateArgument(
 ///     refersToType(class(hasName("X")))))
 ///   matches the specialization \c A<X>
 AST_MATCHER_P(TemplateArgument, refersToType,
-              internal::Matcher<QualType>, Matcher) {
+              internal::Matcher<QualType>, InnerMatcher) {
   if (Node.getKind() != TemplateArgument::Type)
     return false;
-  return Matcher.matches(Node.getAsType(), Finder, Builder);
+  return InnerMatcher.matches(Node.getAsType(), Finder, Builder);
 }
 
 /// \brief Matches a TemplateArgument that refers to a certain declaration.
 ///
 /// Given
+/// \code
 ///   template<typename T> struct A {};
 ///   struct B { B* next; };
 ///   A<&B::next> a;
+/// \endcode
 /// classTemplateSpecialization(hasAnyTemplateArgument(
 ///     refersToDeclaration(field(hasName("next"))))
 ///   matches the specialization \c A<&B::next> with \c field(...) matching
 ///     \c B::next
 AST_MATCHER_P(TemplateArgument, refersToDeclaration,
-              internal::Matcher<Decl>, Matcher) {
+              internal::Matcher<Decl>, InnerMatcher) {
   if (const Decl *Declaration = Node.getAsDecl())
-    return Matcher.matches(*Declaration, Finder, Builder);
+    return InnerMatcher.matches(*Declaration, Finder, Builder);
   return false;
 }
 
 /// \brief Matches C++ constructor declarations.
 ///
 /// Example matches Foo::Foo() and Foo::Foo(int)
+/// \code
 ///   class Foo {
 ///    public:
 ///     Foo();
 ///     Foo(int);
 ///     int DoSomething();
 ///   };
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Decl,
   CXXConstructorDecl> constructor;
@@ -251,26 +372,32 @@
 /// \brief Matches explicit C++ destructor declarations.
 ///
 /// Example matches Foo::~Foo()
+/// \code
 ///   class Foo {
 ///    public:
 ///     virtual ~Foo();
 ///   };
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl> destructor;
 
 /// \brief Matches enum declarations.
 ///
 /// Example matches X
+/// \code
 ///   enum X {
 ///     A, B, C
 ///   };
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
 
 /// \brief Matches enum constants.
 ///
 /// Example matches A, B, C
+/// \code
 ///   enum X {
 ///     A, B, C
 ///   };
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Decl,
   EnumConstantDecl> enumConstant;
@@ -278,7 +405,9 @@
 /// \brief Matches method declarations.
 ///
 /// Example matches y
+/// \code
 ///   class X { void y() };
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> method;
 
 /// \brief Matches variable declarations.
@@ -287,13 +416,17 @@
 /// "field" declarations in Clang parlance.
 ///
 /// Example matches a
+/// \code
 ///   int a;
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> variable;
 
 /// \brief Matches field declarations.
 ///
 /// Given
+/// \code
 ///   class X { int m; };
+/// \endcode
 /// field()
 ///   matches 'm'.
 const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> field;
@@ -301,14 +434,27 @@
 /// \brief Matches function declarations.
 ///
 /// Example matches f
+/// \code
 ///   void f();
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> function;
 
+/// \brief Matches C++ function template declarations.
+///
+/// Example matches f
+/// \code
+///   template<class T> void f(T t) {}
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Decl,
+  FunctionTemplateDecl> functionTemplate;
 
 /// \brief Matches statements.
 ///
 /// Given
+/// \code
 ///   { ++a; }
+/// \endcode
 /// statement()
 ///   matches both the compound statement '{ ++a; }' and '++a'.
 const internal::VariadicDynCastAllOfMatcher<Stmt, Stmt> statement;
@@ -316,7 +462,9 @@
 /// \brief Matches declaration statements.
 ///
 /// Given
+/// \code
 ///   int a;
+/// \endcode
 /// declarationStatement()
 ///   matches 'int a'.
 const internal::VariadicDynCastAllOfMatcher<
@@ -326,10 +474,12 @@
 /// \brief Matches member expressions.
 ///
 /// Given
+/// \code
 ///   class Y {
 ///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
 ///     int a; static int b;
 ///   };
+/// \endcode
 /// memberExpression()
 ///   matches this->x, x, y.x, a, this->b
 const internal::VariadicDynCastAllOfMatcher<
@@ -339,24 +489,30 @@
 /// \brief Matches call expressions.
 ///
 /// Example matches x.y() and y()
+/// \code
 ///   X x;
 ///   x.y();
 ///   y();
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> call;
 
 /// \brief Matches member call expressions.
 ///
 /// Example matches x.y()
+/// \code
 ///   X x;
 ///   x.y();
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr> memberCall;
 
 /// \brief Matches init list expressions.
 ///
 /// Given
+/// \code
 ///   int a[] = { 1, 2 };
 ///   struct B { int x, y; };
 ///   B b = { 5, 6 };
+/// \endcode
 /// initList()
 ///   matches "{ 1, 2 }" and "{ 5, 6 }"
 const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
@@ -364,8 +520,10 @@
 /// \brief Matches using declarations.
 ///
 /// Given
+/// \code
 ///   namespace X { int x; }
 ///   using X::x;
+/// \endcode
 /// usingDecl()
 ///   matches \code using X::x \endcode
 const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
@@ -374,10 +532,12 @@
 ///
 /// Example matches string(ptr, n) and ptr within arguments of f
 ///     (matcher = constructorCall())
+/// \code
 ///   void f(const string &a, const string &b);
 ///   char *ptr;
 ///   int n;
 ///   f(string(ptr, n), ptr);
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   CXXConstructExpr> constructorCall;
@@ -386,8 +546,10 @@
 ///
 /// Example matches FunctionTakesString(GetStringByValue())
 ///     (matcher = bindTemporaryExpression())
+/// \code
 ///   FunctionTakesString(GetStringByValue());
 ///   FunctionTakesStringByPointer(GetStringPointer());
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   CXXBindTemporaryExpr> bindTemporaryExpression;
@@ -395,7 +557,9 @@
 /// \brief Matches new expressions.
 ///
 /// Given
+/// \code
 ///   new X;
+/// \endcode
 /// newExpression()
 ///   matches 'new X'.
 const internal::VariadicDynCastAllOfMatcher<
@@ -405,7 +569,9 @@
 /// \brief Matches delete expressions.
 ///
 /// Given
+/// \code
 ///   delete X;
+/// \endcode
 /// deleteExpression()
 ///   matches 'delete X'.
 const internal::VariadicDynCastAllOfMatcher<
@@ -415,7 +581,9 @@
 /// \brief Matches array subscript expressions.
 ///
 /// Given
+/// \code
 ///   int i = a[1];
+/// \endcode
 /// arraySubscriptExpr()
 ///   matches "a[1]"
 const internal::VariadicDynCastAllOfMatcher<
@@ -427,8 +595,10 @@
 /// Example matches the CXXDefaultArgExpr placeholder inserted for the
 ///     default value of the second parameter in the call expression f(42)
 ///     (matcher = defaultArgument())
+/// \code
 ///   void f(int x, int y = 0);
 ///   f(42);
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   CXXDefaultArgExpr> defaultArgument;
@@ -442,9 +612,11 @@
 ///
 /// Example matches both operator<<((o << b), c) and operator<<(o, b)
 ///     (matcher = overloadedOperatorCall())
+/// \code
 ///   ostream &operator<< (ostream &out, int i) { };
 ///   ostream &o; int b = 1, c = 1;
 ///   o << b << c;
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   CXXOperatorCallExpr> overloadedOperatorCall;
@@ -452,7 +624,9 @@
 /// \brief Matches expressions.
 ///
 /// Example matches x()
+/// \code
 ///   void f() { x(); }
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   Expr> expression;
@@ -460,8 +634,10 @@
 /// \brief Matches expressions that refer to declarations.
 ///
 /// Example matches x in if (x)
+/// \code
 ///   bool x;
 ///   if (x) {}
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   DeclRefExpr> declarationReference;
@@ -469,13 +645,17 @@
 /// \brief Matches if statements.
 ///
 /// Example matches 'if (x) {}'
+/// \code
 ///   if (x) {}
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
 
 /// \brief Matches for statements.
 ///
 /// Example matches 'for (;;) {}'
+/// \code
 ///   for (;;) {}
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt, ForStmt> forStmt;
 
@@ -484,7 +664,9 @@
 /// Example:
 ///     forStmt(hasIncrement(unaryOperator(hasOperatorName("++"))))
 /// matches '++x' in
+/// \code
 ///     for (x; x < N; ++x) { }
+/// \endcode
 AST_MATCHER_P(ForStmt, hasIncrement, internal::Matcher<Stmt>,
               InnerMatcher) {
   const Stmt *const Increment = Node.getInc();
@@ -497,7 +679,9 @@
 /// Example:
 ///     forStmt(hasLoopInit(declarationStatement()))
 /// matches 'int x = 0' in
+/// \code
 ///     for (int x = 0; x < N; ++x) { }
+/// \endcode
 AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>,
               InnerMatcher) {
   const Stmt *const Init = Node.getInit();
@@ -507,7 +691,9 @@
 /// \brief Matches while statements.
 ///
 /// Given
+/// \code
 ///   while (true) {}
+/// \endcode
 /// whileStmt()
 ///   matches 'while (true) {}'.
 const internal::VariadicDynCastAllOfMatcher<
@@ -517,7 +703,9 @@
 /// \brief Matches do statements.
 ///
 /// Given
+/// \code
 ///   do {} while (true);
+/// \endcode
 /// doStmt()
 ///   matches 'do {} while(true)'
 const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
@@ -525,7 +713,9 @@
 /// \brief Matches case and default statements inside switch statements.
 ///
 /// Given
+/// \code
 ///   switch(a) { case 42: break; default: break; }
+/// \endcode
 /// switchCase()
 ///   matches 'case 42: break;' and 'default: break;'.
 const internal::VariadicDynCastAllOfMatcher<
@@ -535,7 +725,9 @@
 /// \brief Matches compound statements.
 ///
 /// Example matches '{}' and '{{}}'in 'for (;;) {{}}'
+/// \code
 ///   for (;;) {{}}
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   CompoundStmt> compoundStatement;
@@ -543,7 +735,9 @@
 /// \brief Matches bool literals.
 ///
 /// Example matches true
+/// \code
 ///   true
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CXXBoolLiteralExpr> boolLiteral;
@@ -551,7 +745,9 @@
 /// \brief Matches string literals (also matches wide string literals).
 ///
 /// Example matches "abcd", L"abcd"
+/// \code
 ///   char *s = "abcd"; wchar_t *ws = L"abcd"
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   StringLiteral> stringLiteral;
@@ -562,7 +758,9 @@
 /// though.
 ///
 /// Example matches 'a', L'a'
+/// \code
 ///   char ch = 'a'; wchar_t chw = L'a';
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CharacterLiteral> characterLiteral;
@@ -579,7 +777,9 @@
 /// \brief Matches binary operator expressions.
 ///
 /// Example matches a || b
+/// \code
 ///   !(a || b)
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   BinaryOperator> binaryOperator;
@@ -587,7 +787,9 @@
 /// \brief Matches unary operator expressions.
 ///
 /// Example matches !a
+/// \code
 ///   !a || b
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   UnaryOperator> unaryOperator;
@@ -595,7 +797,9 @@
 /// \brief Matches conditional operator expressions.
 ///
 /// Example matches a ? b : c
+/// \code
 ///   (a ? b : c) + 42
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Stmt,
   ConditionalOperator> conditionalOperator;
@@ -607,7 +811,9 @@
 /// more readable.
 ///
 /// Example matches reinterpret_cast<char*>(&p) in
+/// \code
 ///   void* p = reinterpret_cast<char*>(&p);
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CXXReinterpretCastExpr> reinterpretCast;
@@ -622,7 +828,9 @@
 /// matches
 ///   static_cast<long>(8)
 /// in
+/// \code
 ///   long eight(static_cast<long>(8));
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CXXStaticCastExpr> staticCast;
@@ -634,9 +842,11 @@
 /// matches
 ///   dynamic_cast<D*>(&b);
 /// in
+/// \code
 ///   struct B { virtual ~B() {} }; struct D : B {};
 ///   B b;
 ///   D* p = dynamic_cast<D*>(&b);
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CXXDynamicCastExpr> dynamicCast;
@@ -644,9 +854,11 @@
 /// \brief Matches a const_cast expression.
 ///
 /// Example: Matches const_cast<int*>(&r) in
+/// \code
 ///   int n = 42;
-///   const int& r(n);
+///   const int &r(n);
 ///   int* p = const_cast<int*>(&r);
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CXXConstCastExpr> constCast;
@@ -665,9 +877,13 @@
 /// \see hasDestinationType.
 ///
 /// Example: matches all five of the casts in
+/// \code
 ///   int((int)(reinterpret_cast<int>(static_cast<int>(const_cast<int>(42)))))
+/// \endcode
 /// but does not match the implicit conversion in
+/// \code
 ///   long ell = 42;
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   ExplicitCastExpr> explicitCast;
@@ -680,70 +896,101 @@
   Expr,
   ImplicitCastExpr> implicitCast;
 
+/// \brief Matches any cast nodes of Clang's AST.
+///
+/// Example: castExpr() matches each of the following:
+/// \code
+///   (int) 3;
+///   const_cast<Expr *>(SubExpr);
+///   char c = 0;
+/// \endcode
+/// but does not match
+/// \code
+///   int i = (0);
+///   int k = 0;
+/// \endcode
+const internal::VariadicDynCastAllOfMatcher<
+  Expr,
+  CastExpr> castExpr;
+
 /// \brief Matches functional cast expressions
 ///
 /// Example: Matches Foo(bar);
+/// \code
 ///   Foo f = bar;
 ///   Foo g = (Foo) bar;
 ///   Foo h = Foo(bar);
+/// \endcode
 const internal::VariadicDynCastAllOfMatcher<
   Expr,
   CXXFunctionalCastExpr> functionalCast;
 
 /// \brief Various overloads for the anyOf matcher.
 /// @{
-template<typename C1, typename C2>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1, C2>
-anyOf(const C1 &P1, const C2 &P2) {
+
+/// \brief Matches if any of the given matchers matches.
+///
+/// Usable as: Any Matcher
+template<typename M1, typename M2>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1, M2>
+anyOf(const M1 &P1, const M2 &P2) {
   return internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
-                                                C1, C2 >(P1, P2);
+                                                M1, M2 >(P1, P2);
 }
-template<typename C1, typename C2, typename C3>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
-    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2, C3> >
-anyOf(const C1 &P1, const C2 &P2, const C3 &P3) {
+template<typename M1, typename M2, typename M3>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
+    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2, M3> >
+anyOf(const M1 &P1, const M2 &P2, const M3 &P3) {
   return anyOf(P1, anyOf(P2, P3));
 }
-template<typename C1, typename C2, typename C3, typename C4>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
-    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2,
+template<typename M1, typename M2, typename M3, typename M4>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
+    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2,
         internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
-                                               C3, C4> > >
-anyOf(const C1 &P1, const C2 &P2, const C3 &P3, const C4 &P4) {
+                                               M3, M4> > >
+anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) {
   return anyOf(P1, anyOf(P2, anyOf(P3, P4)));
 }
-template<typename C1, typename C2, typename C3, typename C4, typename C5>
-internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C1,
-    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C2,
-        internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, C3,
+template<typename M1, typename M2, typename M3, typename M4, typename M5>
+internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M1,
+    internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M2,
+        internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher, M3,
             internal::PolymorphicMatcherWithParam2<internal::AnyOfMatcher,
-                                                   C4, C5> > > >
-anyOf(const C1& P1, const C2& P2, const C3& P3, const C4& P4, const C5& P5) {
+                                                   M4, M5> > > >
+anyOf(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) {
   return anyOf(P1, anyOf(P2, anyOf(P3, anyOf(P4, P5))));
 }
+
 /// @}
 
 /// \brief Various overloads for the allOf matcher.
 /// @{
-template<typename C1, typename C2>
-internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1, C2>
-allOf(const C1 &P1, const C2 &P2) {
+
+/// \brief Matches if all given matchers match.
+///
+/// Usable as: Any Matcher
+template<typename M1, typename M2>
+internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1, M2>
+allOf(const M1 &P1, const M2 &P2) {
   return internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher,
-                                                C1, C2>(P1, P2);
+                                                M1, M2>(P1, P2);
 }
-template<typename C1, typename C2, typename C3>
-internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C1,
-    internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, C2, C3> >
-allOf(const C1& P1, const C2& P2, const C3& P3) {
+template<typename M1, typename M2, typename M3>
+internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M1,
+    internal::PolymorphicMatcherWithParam2<internal::AllOfMatcher, M2, M3> >
+allOf(const M1 &P1, const M2 &P2, const M3 &P3) {
   return allOf(P1, allOf(P2, P3));
 }
+
 /// @}
 
 /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL)
 ///
 /// Given
+/// \code
 ///   Foo x = bar;
 ///   int y = sizeof(x) + alignof(x);
+/// \endcode
 /// unaryExprOrTypeTraitExpr()
 ///   matches \c sizeof(x) and \c alignof(x)
 const internal::VariadicDynCastAllOfMatcher<
@@ -753,20 +1000,24 @@
 /// \brief Matches unary expressions that have a specific type of argument.
 ///
 /// Given
+/// \code
 ///   int a, c; float b; int s = sizeof(a) + sizeof(b) + alignof(c);
+/// \endcode
 /// unaryExprOrTypeTraitExpr(hasArgumentOfType(asString("int"))
 ///   matches \c sizeof(a) and \c alignof(c)
 AST_MATCHER_P(UnaryExprOrTypeTraitExpr, hasArgumentOfType,
-              internal::Matcher<QualType>, Matcher) {
+              internal::Matcher<QualType>, InnerMatcher) {
   const QualType ArgumentType = Node.getTypeOfArgument();
-  return Matcher.matches(ArgumentType, Finder, Builder);
+  return InnerMatcher.matches(ArgumentType, Finder, Builder);
 }
 
 /// \brief Matches unary expressions of a certain kind.
 ///
 /// Given
+/// \code
 ///   int x;
 ///   int s = sizeof(x) + alignof(x)
+/// \endcode
 /// unaryExprOrTypeTraitExpr(ofKind(UETT_SizeOf))
 ///   matches \c sizeof(x)
 AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) {
@@ -776,17 +1027,17 @@
 /// \brief Same as unaryExprOrTypeTraitExpr, but only matching
 /// alignof.
 inline internal::Matcher<Stmt> alignOfExpr(
-    const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
+    const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
   return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
-      ofKind(UETT_AlignOf), Matcher)));
+      ofKind(UETT_AlignOf), InnerMatcher)));
 }
 
 /// \brief Same as unaryExprOrTypeTraitExpr, but only matching
 /// sizeof.
 inline internal::Matcher<Stmt> sizeOfExpr(
-    const internal::Matcher<UnaryExprOrTypeTraitExpr> &Matcher) {
+    const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) {
   return internal::Matcher<Stmt>(unaryExprOrTypeTraitExpr(allOf(
-      ofKind(UETT_SizeOf), Matcher)));
+      ofKind(UETT_SizeOf), InnerMatcher)));
 }
 
 /// \brief Matches NamedDecl nodes that have the specified name.
@@ -796,10 +1047,14 @@
 /// Does not match typedefs of an underlying type with the given name.
 ///
 /// Example matches X (Name == "X")
+/// \code
 ///   class X;
+/// \endcode
 ///
 /// Example matches X (Name is one of "::a::b::X", "a::b::X", "b::X", "X")
-/// namespace a { namespace b { class X; } }
+/// \code
+///   namespace a { namespace b { class X; } }
+/// \endcode
 AST_MATCHER_P(NamedDecl, hasName, std::string, Name) {
   assert(!Name.empty());
   const std::string FullNameString = "::" + Node.getQualifiedNameAsString();
@@ -820,10 +1075,14 @@
 /// of an underlying type with the given name.
 ///
 /// Example matches X (regexp == "::X")
+/// \code
 ///   class X;
+/// \endcode
 ///
 /// Example matches X (regexp is one of "::X", "^foo::.*X", among others)
-/// namespace foo { namespace bar { class X; } }
+/// \code
+///   namespace foo { namespace bar { class X; } }
+/// \endcode
 AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) {
   assert(!RegExp.empty());
   std::string FullNameString = "::" + Node.getQualifiedNameAsString();
@@ -838,9 +1097,11 @@
 ///
 /// Example matches a << b
 ///     (matcher == overloadedOperatorCall(hasOverloadedOperatorName("<<")))
+/// \code
 ///   a << b;
 ///   c && d;  // assuming both operator<<
 ///            // and operator&& are overloaded somewhere.
+/// \endcode
 AST_MATCHER_P(CXXOperatorCallExpr,
               hasOverloadedOperatorName, std::string, Name) {
   return getOperatorSpelling(Node.getOperator()) == Name;
@@ -852,17 +1113,21 @@
 /// Note that a class is considered to be also derived from itself.
 ///
 /// Example matches X, Y, Z, C (Base == hasName("X"))
+/// \code
 ///   class X;                // A class is considered to be derived from itself
 ///   class Y : public X {};  // directly derived
 ///   class Z : public Y {};  // indirectly derived
 ///   typedef X A;
 ///   typedef A B;
 ///   class C : public B {};  // derived from a typedef of X
+/// \endcode
 ///
 /// In the following example, Bar matches isDerivedFrom(hasName("X")):
+/// \code
 ///   class Foo;
 ///   typedef Foo X;
 ///   class Bar : public Foo {};  // derived from a type that X is a typedef of
+/// \endcode
 AST_MATCHER_P(CXXRecordDecl, isDerivedFrom,
               internal::Matcher<NamedDecl>, Base) {
   return Finder->classIsDerivedFrom(&Node, Base, Builder);
@@ -878,11 +1143,15 @@
 /// provided matcher.
 ///
 /// Example matches X, Y (matcher = record(has(record(hasName("X")))
+/// \code
 ///   class X {};  // Matches X, because X::X is a class of name X inside X.
 ///   class Y { class X {}; };
 ///   class Z { class Y { class X {}; }; };  // Does not match Z.
+/// \endcode
 ///
 /// ChildT must be an AST base type.
+///
+/// Usable as: Any Matcher
 template <typename ChildT>
 internal::ArgumentAdaptingMatcher<internal::HasMatcher, ChildT> has(
     const internal::Matcher<ChildT> &ChildMatcher) {
@@ -895,11 +1164,15 @@
 ///
 /// Example matches X, Y, Z
 ///     (matcher = record(hasDescendant(record(hasName("X")))))
+/// \code
 ///   class X {};  // Matches X, because X::X is a class of name X inside X.
 ///   class Y { class X {}; };
 ///   class Z { class Y { class X {}; }; };
+/// \endcode
 ///
 /// DescendantT must be an AST base type.
+///
+/// Usable as: Any Matcher
 template <typename DescendantT>
 internal::ArgumentAdaptingMatcher<internal::HasDescendantMatcher, DescendantT>
 hasDescendant(const internal::Matcher<DescendantT> &DescendantMatcher) {
@@ -913,17 +1186,21 @@
 /// provided matcher.
 ///
 /// Example matches X, Y (matcher = record(forEach(record(hasName("X")))
+/// \code
 ///   class X {};  // Matches X, because X::X is a class of name X inside X.
 ///   class Y { class X {}; };
 ///   class Z { class Y { class X {}; }; };  // Does not match Z.
+/// \endcode
 ///
 /// ChildT must be an AST base type.
 ///
 /// As opposed to 'has', 'forEach' will cause a match for each result that
 /// matches instead of only on the first one.
+///
+/// Usable as: Any Matcher
 template <typename ChildT>
 internal::ArgumentAdaptingMatcher<internal::ForEachMatcher, ChildT> forEach(
-    const internal::Matcher<ChildT>& ChildMatcher) {
+    const internal::Matcher<ChildT> &ChildMatcher) {
   return internal::ArgumentAdaptingMatcher<
     internal::ForEachMatcher,
     ChildT>(ChildMatcher);
@@ -934,9 +1211,11 @@
 ///
 /// Example matches X, A, B, C
 ///     (matcher = record(forEachDescendant(record(hasName("X")))))
+/// \code
 ///   class X {};  // Matches X, because X::X is a class of name X inside X.
 ///   class A { class X {}; };
 ///   class B { class C { class X {}; }; };
+/// \endcode
 ///
 /// DescendantT must be an AST base type.
 ///
@@ -946,11 +1225,15 @@
 /// Note: Recursively combined ForEachDescendant can cause many matches:
 ///   record(forEachDescendant(record(forEachDescendant(record()))))
 /// will match 10 times (plus injected class name matches) on:
+/// \code
 ///   class A { class B { class C { class D { class E {}; }; }; }; };
+/// \endcode
+///
+/// Usable as: Any Matcher
 template <typename DescendantT>
 internal::ArgumentAdaptingMatcher<internal::ForEachDescendantMatcher, DescendantT>
 forEachDescendant(
-    const internal::Matcher<DescendantT>& DescendantMatcher) {
+    const internal::Matcher<DescendantT> &DescendantMatcher) {
   return internal::ArgumentAdaptingMatcher<
     internal::ForEachDescendantMatcher,
     DescendantT>(DescendantMatcher);
@@ -959,16 +1242,23 @@
 /// \brief Matches if the provided matcher does not match.
 ///
 /// Example matches Y (matcher = record(unless(hasName("X"))))
+/// \code
 ///   class X {};
 ///   class Y {};
+/// \endcode
+///
+/// Usable as: Any Matcher
 template <typename M>
-internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M> unless(const M &InnerMatcher) {
+internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M>
+unless(const M &InnerMatcher) {
   return internal::PolymorphicMatcherWithParam1<
     internal::NotMatcher, M>(InnerMatcher);
 }
 
 /// \brief Matches a type if the declaration of the type matches the given
 /// matcher.
+///
+/// Usable as: Matcher<QualType>, Matcher<CallExpr>, Matcher<CXXConstructExpr>
 inline internal::PolymorphicMatcherWithParam1< internal::HasDeclarationMatcher,
                                      internal::Matcher<Decl> >
     hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) {
@@ -980,8 +1270,10 @@
 /// \brief Matches on the implicit object argument of a member call expression.
 ///
 /// Example matches y.x() (matcher = call(on(hasType(record(hasName("Y"))))))
+/// \code
 ///   class Y { public: void x(); };
 ///   void z() { Y y; y.x(); }",
+/// \endcode
 ///
 /// FIXME: Overload to allow directly matching types?
 AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>,
@@ -996,8 +1288,10 @@
 /// \brief Matches if the call expression's callee expression matches.
 ///
 /// Given
+/// \code
 ///   class Y { void x() { this->x(); x(); Y y; y.x(); } };
 ///   void f() { f(); }
+/// \endcode
 /// call(callee(expression()))
 ///   matches this->x(), x(), y.x(), f()
 /// with callee(...)
@@ -1018,8 +1312,10 @@
 /// given matcher.
 ///
 /// Example matches y.x() (matcher = call(callee(method(hasName("x")))))
+/// \code
 ///   class Y { public: void x(); };
 ///   void z() { Y y; y.x();
+/// \endcode
 inline internal::Matcher<CallExpr> callee(
     const internal::Matcher<Decl> &InnerMatcher) {
   return internal::Matcher<CallExpr>(hasDeclaration(InnerMatcher));
@@ -1032,8 +1328,10 @@
 ///                        hasDeclaration(record(hasName("X"))))))
 ///             and z (matcher = variable(hasType(
 ///                        hasDeclaration(record(hasName("X"))))))
+/// \code
 ///  class X {};
 ///  void y(X &x) { x; X z; }
+/// \endcode
 AST_POLYMORPHIC_MATCHER_P(hasType, internal::Matcher<QualType>,
                           InnerMatcher) {
   TOOLING_COMPILE_ASSERT((llvm::is_base_of<Expr, NodeType>::value ||
@@ -1053,8 +1351,12 @@
 ///
 /// Example matches x (matcher = expression(hasType(record(hasName("X")))))
 ///             and z (matcher = variable(hasType(record(hasName("X")))))
+/// \code
 ///  class X {};
 ///  void y(X &x) { x; X z; }
+/// \endcode
+///
+/// Usable as: Matcher<Expr>, Matcher<ValueDecl>
 inline internal::PolymorphicMatcherWithParam1<
   internal::matcher_hasTypeMatcher,
   internal::Matcher<QualType> >
@@ -1066,8 +1368,10 @@
 /// \brief Matches if the matched type is represented by the given string.
 ///
 /// Given
+/// \code
 ///   class Y { public: void x(); };
 ///   void z() { Y* y; y->x(); }
+/// \endcode
 /// call(on(hasType(asString("class Y *"))))
 ///   matches y->x()
 AST_MATCHER_P(QualType, asString, std::string, Name) {
@@ -1079,8 +1383,10 @@
 ///
 /// Example matches y->x()
 ///     (matcher = call(on(hasType(pointsTo(record(hasName("Y")))))))
+/// \code
 ///   class Y { public: void x(); };
 ///   void z() { Y *y; y->x(); }
+/// \endcode
 AST_MATCHER_P(
     QualType, pointsTo, internal::Matcher<QualType>,
     InnerMatcher) {
@@ -1100,11 +1406,13 @@
 ///
 /// Example matches X &x and const X &y
 ///     (matcher = variable(hasType(references(record(hasName("X"))))))
+/// \code
 ///   class X {
 ///     void a(X b) {
 ///       X &x = b;
 ///       const X &y = b;
 ///   };
+/// \endcode
 AST_MATCHER_P(QualType, references, internal::Matcher<QualType>,
               InnerMatcher) {
   return (!Node.isNull() && Node->isReferenceType() &&
@@ -1146,8 +1454,10 @@
 ///
 /// Example matches x in if(x)
 ///     (matcher = declarationReference(to(variable(hasName("x")))))
+/// \code
 ///   bool x;
 ///   if (x) {}
+/// \endcode
 AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>,
               InnerMatcher) {
   const Decl *DeclNode = Node.getDecl();
@@ -1161,20 +1471,39 @@
 /// FIXME: This currently only works for functions. Fix.
 ///
 /// Given
+/// \code
 ///   namespace a { void f() {} }
 ///   using a::f;
 ///   void g() {
 ///     f();     // Matches this ..
 ///     a::f();  // .. but not this.
 ///   }
+/// \endcode
 /// declarationReference(throughUsingDeclaration(anything()))
 ///   matches \c f()
 AST_MATCHER_P(DeclRefExpr, throughUsingDecl,
-              internal::Matcher<UsingShadowDecl>, Matcher) {
+              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
   const NamedDecl *FoundDecl = Node.getFoundDecl();
   if (const UsingShadowDecl *UsingDecl =
       llvm::dyn_cast<UsingShadowDecl>(FoundDecl))
-    return Matcher.matches(*UsingDecl, Finder, Builder);
+    return InnerMatcher.matches(*UsingDecl, Finder, Builder);
+  return false;
+}
+
+/// \brief Matches the Decl of a DeclStmt which has a single declaration.
+///
+/// Given
+/// \code
+///   int a, b;
+///   int c;
+/// \endcode
+/// declarationStatement(hasSingleDecl(anything()))
+///   matches 'int c;' but not 'int a, b;'.
+AST_MATCHER_P(DeclStmt, hasSingleDecl, internal::Matcher<Decl>, InnerMatcher) {
+  if (Node.isSingleDecl()) {
+    const Decl *FoundDecl = Node.getSingleDecl();
+    return InnerMatcher.matches(*FoundDecl, Finder, Builder);
+  }
   return false;
 }
 
@@ -1182,8 +1511,10 @@
 /// that matches the given matcher.
 ///
 /// Example matches x (matcher = variable(hasInitializer(call())))
+/// \code
 ///   bool y() { return true; }
 ///   bool x = y();
+/// \endcode
 AST_MATCHER_P(
     VarDecl, hasInitializer, internal::Matcher<Expr>,
     InnerMatcher) {
@@ -1196,8 +1527,10 @@
 /// a specific number of arguments (including absent default arguments).
 ///
 /// Example matches f(0, 0) (matcher = call(argumentCountIs(2)))
+/// \code
 ///   void f(int x, int y);
 ///   f(0, 0);
+/// \endcode
 AST_POLYMORPHIC_MATCHER_P(argumentCountIs, unsigned, N) {
   TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
                           llvm::is_base_of<CXXConstructExpr,
@@ -1211,7 +1544,9 @@
 ///
 /// Example matches y in x(y)
 ///     (matcher = call(hasArgument(0, declarationReference())))
+/// \code
 ///   void x(int) { int y; x(y); }
+/// \endcode
 AST_POLYMORPHIC_MATCHER_P2(
     hasArgument, unsigned, N, internal::Matcher<Expr>, InnerMatcher) {
   TOOLING_COMPILE_ASSERT((llvm::is_base_of<CallExpr, NodeType>::value ||
@@ -1223,13 +1558,59 @@
               *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder));
 }
 
+/// \brief Matches declaration statements that contain a specific number of
+/// declarations.
+///
+/// Example: Given
+/// \code
+///   int a, b;
+///   int c;
+///   int d = 2, e;
+/// \endcode
+/// declCountIs(2)
+///   matches 'int a, b;' and 'int d = 2, e;', but not 'int c;'.
+AST_MATCHER_P(DeclStmt, declCountIs, unsigned, N) {
+  return std::distance(Node.decl_begin(), Node.decl_end()) == (ptrdiff_t)N;
+}
+
+/// \brief Matches the n'th declaration of a declaration statement.
+///
+/// Note that this does not work for global declarations because the AST
+/// breaks up multiple-declaration DeclStmt's into multiple single-declaration
+/// DeclStmt's.
+/// Example: Given non-global declarations
+/// \code
+///   int a, b = 0;
+///   int c;
+///   int d = 2, e;
+/// \endcode
+/// declarationStatement(containsDeclaration(
+///       0, variable(hasInitializer(anything()))))
+///   matches only 'int d = 2, e;', and
+/// declarationStatement(containsDeclaration(1, variable()))
+/// \code
+///   matches 'int a, b = 0' as well as 'int d = 2, e;'
+///   but 'int c;' is not matched.
+/// \endcode
+AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N,
+               internal::Matcher<Decl>, InnerMatcher) {
+  const unsigned NumDecls = std::distance(Node.decl_begin(), Node.decl_end());
+  if (N >= NumDecls)
+    return false;
+  DeclStmt::const_decl_iterator Iterator = Node.decl_begin();
+  std::advance(Iterator, N);
+  return InnerMatcher.matches(**Iterator, Finder, Builder);
+}
+
 /// \brief Matches a constructor initializer.
 ///
 /// Given
+/// \code
 ///   struct Foo {
 ///     Foo() : foo_(1) { }
 ///     int foo_;
 ///   };
+/// \endcode
 /// record(has(constructor(hasAnyConstructorInitializer(anything()))))
 ///   record matches Foo, hasAnyConstructorInitializer matches foo_(1)
 AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer,
@@ -1246,10 +1627,12 @@
 /// \brief Matches the field declaration of a constructor initializer.
 ///
 /// Given
+/// \code
 ///   struct Foo {
 ///     Foo() : foo_(1) { }
 ///     int foo_;
 ///   };
+/// \endcode
 /// record(has(constructor(hasAnyConstructorInitializer(
 ///     forField(hasName("foo_"))))))
 ///   matches Foo
@@ -1264,10 +1647,12 @@
 /// \brief Matches the initializer expression of a constructor initializer.
 ///
 /// Given
+/// \code
 ///   struct Foo {
 ///     Foo() : foo_(1) { }
 ///     int foo_;
 ///   };
+/// \endcode
 /// record(has(constructor(hasAnyConstructorInitializer(
 ///     withInitializer(integerLiteral(equals(1)))))))
 ///   matches Foo
@@ -1283,11 +1668,13 @@
 /// code (as opposed to implicitly added by the compiler).
 ///
 /// Given
+/// \code
 ///   struct Foo {
 ///     Foo() { }
 ///     Foo(int) : foo_("A") { }
 ///     string foo_;
 ///   };
+/// \endcode
 /// constructor(hasAnyConstructorInitializer(isWritten()))
 ///   will match Foo(int), but not Foo()
 AST_MATCHER(CXXCtorInitializer, isWritten) {
@@ -1304,7 +1691,9 @@
 /// expression.
 ///
 /// Given
+/// \code
 ///   void x(int, int, int) { int y; x(1, y, 42); }
+/// \endcode
 /// call(hasAnyArgument(declarationReference()))
 ///   matches x(1, y, 42)
 /// with hasAnyArgument(...)
@@ -1327,7 +1716,9 @@
 /// \brief Matches the n'th parameter of a function declaration.
 ///
 /// Given
+/// \code
 ///   class X { void f(int x) {} };
+/// \endcode
 /// method(hasParameter(0, hasType(variable())))
 ///   matches f(int x) {}
 /// with hasParameter(...)
@@ -1345,7 +1736,9 @@
 /// Does not match the 'this' parameter of a method.
 ///
 /// Given
+/// \code
 ///   class X { void f(int x, int y, int z) {} };
+/// \endcode
 /// method(hasAnyParameter(hasName("y")))
 ///   matches f(int x, int y, int z) {}
 /// with hasAnyParameter(...)
@@ -1363,18 +1756,37 @@
 /// \brief Matches the return type of a function declaration.
 ///
 /// Given:
+/// \code
 ///   class X { int f() { return 1; } };
+/// \endcode
 /// method(returns(asString("int")))
 ///   matches int f() { return 1; }
-AST_MATCHER_P(FunctionDecl, returns, internal::Matcher<QualType>, Matcher) {
-  return Matcher.matches(Node.getResultType(), Finder, Builder);
+AST_MATCHER_P(FunctionDecl, returns,
+              internal::Matcher<QualType>, InnerMatcher) {
+  return InnerMatcher.matches(Node.getResultType(), Finder, Builder);
+}
+
+/// \brief Matches extern "C" function declarations.
+///
+/// Given:
+/// \code
+///   extern "C" void f() {}
+///   extern "C" { void g() {} }
+///   void h() {}
+/// \endcode
+/// function(isExternC())
+///   matches the declaration of f and g, but not the declaration h
+AST_MATCHER(FunctionDecl, isExternC) {
+  return Node.isExternC();
 }
 
 /// \brief Matches the condition expression of an if statement, for loop,
 /// or conditional operator.
 ///
 /// Example matches true (matcher = hasCondition(boolLiteral(equals(true))))
+/// \code
 ///   if (true) {}
+/// \endcode
 AST_POLYMORPHIC_MATCHER_P(hasCondition, internal::Matcher<Expr>,
                           InnerMatcher) {
   TOOLING_COMPILE_ASSERT(
@@ -1392,7 +1804,9 @@
 /// \brief Matches the condition variable statement in an if statement.
 ///
 /// Given
+/// \code
 ///   if (A* a = GetAPointer()) {}
+/// \endcode
 /// hasConditionVariableStatment(...)
 ///   matches 'A* a = GetAPointer()'.
 AST_MATCHER_P(IfStmt, hasConditionVariableStatement,
@@ -1406,29 +1820,33 @@
 /// \brief Matches the index expression of an array subscript expression.
 ///
 /// Given
+/// \code
 ///   int i[5];
 ///   void f() { i[1] = 42; }
+/// \endcode
 /// arraySubscriptExpression(hasIndex(integerLiteral()))
 ///   matches \c i[1] with the \c integerLiteral() matching \c 1
 AST_MATCHER_P(ArraySubscriptExpr, hasIndex,
-              internal::Matcher<Expr>, matcher) {
+              internal::Matcher<Expr>, InnerMatcher) {
   if (const Expr* Expression = Node.getIdx())
-    return matcher.matches(*Expression, Finder, Builder);
+    return InnerMatcher.matches(*Expression, Finder, Builder);
   return false;
 }
 
 /// \brief Matches the base expression of an array subscript expression.
 ///
 /// Given
+/// \code
 ///   int i[5];
 ///   void f() { i[1] = 42; }
+/// \endcode
 /// arraySubscriptExpression(hasBase(implicitCast(
 ///     hasSourceExpression(declarationReference()))))
 ///   matches \c i[1] with the \c declarationReference() matching \c i
 AST_MATCHER_P(ArraySubscriptExpr, hasBase,
-              internal::Matcher<Expr>, matcher) {
+              internal::Matcher<Expr>, InnerMatcher) {
   if (const Expr* Expression = Node.getBase())
-    return matcher.matches(*Expression, Finder, Builder);
+    return InnerMatcher.matches(*Expression, Finder, Builder);
   return false;
 }
 
@@ -1436,7 +1854,9 @@
 /// a given body.
 ///
 /// Given
+/// \code
 ///   for (;;) {}
+/// \endcode
 /// hasBody(compoundStatement())
 ///   matches 'for (;;) {}'
 /// with compoundStatement()
@@ -1457,7 +1877,9 @@
 /// a given matcher.
 ///
 /// Given
+/// \code
 ///   { {}; 1+2; }
+/// \endcode
 /// hasAnySubstatement(compoundStatement())
 ///   matches '{ {}; 1+2; }'
 /// with compoundStatement()
@@ -1476,7 +1898,9 @@
 /// child statements.
 ///
 /// Example: Given
+/// \code
 ///   { for (;;) {} }
+/// \endcode
 /// compoundStatement(statementCountIs(0)))
 ///   matches '{}'
 ///   but does not match the outer compound statement.
@@ -1487,7 +1911,12 @@
 /// \brief Matches literals that are equal to the given value.
 ///
 /// Example matches true (matcher = boolLiteral(equals(true)))
+/// \code
 ///   true
+/// \endcode
+///
+/// Usable as: Matcher<CharacterLiteral>, Matcher<CXXBoolLiteral>,
+///            Matcher<FloatingLiteral>, Matcher<IntegerLiteral>
 template <typename ValueT>
 internal::PolymorphicMatcherWithParam1<internal::ValueEqualsMatcher, ValueT>
 equals(const ValueT &Value) {
@@ -1500,7 +1929,9 @@
 /// unary).
 ///
 /// Example matches a || b (matcher = binaryOperator(hasOperatorName("||")))
+/// \code
 ///   !(a || b)
+/// \endcode
 AST_POLYMORPHIC_MATCHER_P(hasOperatorName, std::string, Name) {
   TOOLING_COMPILE_ASSERT(
     (llvm::is_base_of<BinaryOperator, NodeType>::value) ||
@@ -1512,7 +1943,9 @@
 /// \brief Matches the left hand side of binary operator expressions.
 ///
 /// Example matches a (matcher = binaryOperator(hasLHS()))
+/// \code
 ///   a || b
+/// \endcode
 AST_MATCHER_P(BinaryOperator, hasLHS,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *LeftHandSide = Node.getLHS();
@@ -1523,7 +1956,9 @@
 /// \brief Matches the right hand side of binary operator expressions.
 ///
 /// Example matches b (matcher = binaryOperator(hasRHS()))
+/// \code
 ///   a || b
+/// \endcode
 AST_MATCHER_P(BinaryOperator, hasRHS,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *RightHandSide = Node.getRHS();
@@ -1541,7 +1976,9 @@
 /// \brief Matches if the operand of a unary operator matches.
 ///
 /// Example matches true (matcher = hasOperand(boolLiteral(equals(true))))
+/// \code
 ///   !true
+/// \endcode
 AST_MATCHER_P(UnaryOperator, hasUnaryOperand,
               internal::Matcher<Expr>, InnerMatcher) {
   const Expr * const Operand = Node.getSubExpr();
@@ -1549,15 +1986,14 @@
           InnerMatcher.matches(*Operand, Finder, Builder));
 }
 
-/// \brief Matches if the implicit cast's source expression matches the given
-/// matcher.
+/// \brief Matches if the cast's source expression matches the given matcher.
 ///
 /// Example: matches "a string" (matcher =
 ///                                  hasSourceExpression(constructorCall()))
-///
+/// \code
 /// class URL { URL(string); };
 /// URL url = "a string";
-AST_MATCHER_P(ImplicitCastExpr, hasSourceExpression,
+AST_MATCHER_P(CastExpr, hasSourceExpression,
               internal::Matcher<Expr>, InnerMatcher) {
   const Expr* const SubExpression = Node.getSubExpr();
   return (SubExpression != NULL &&
@@ -1586,7 +2022,9 @@
 /// \brief Matches the true branch expression of a conditional operator.
 ///
 /// Example matches a
+/// \code
 ///   condition ? a : b
+/// \endcode
 AST_MATCHER_P(ConditionalOperator, hasTrueExpression,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *Expression = Node.getTrueExpr();
@@ -1597,7 +2035,9 @@
 /// \brief Matches the false branch expression of a conditional operator.
 ///
 /// Example matches b
+/// \code
 ///   condition ? a : b
+/// \endcode
 AST_MATCHER_P(ConditionalOperator, hasFalseExpression,
               internal::Matcher<Expr>, InnerMatcher) {
   Expr *Expression = Node.getFalseExpr();
@@ -1608,12 +2048,16 @@
 /// \brief Matches if a declaration has a body attached.
 ///
 /// Example matches A, va, fa
+/// \code
 ///   class A {};
 ///   class B;  // Doesn't match, as it has no body.
 ///   int va;
 ///   extern int vb;  // Doesn't match, as it doesn't define the variable.
 ///   void fa() {}
 ///   void fb();  // Doesn't match, as it has no body.
+/// \endcode
+///
+/// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
 inline internal::PolymorphicMatcherWithParam0<internal::IsDefinitionMatcher>
 isDefinition() {
   return internal::PolymorphicMatcherWithParam0<
@@ -1630,11 +2074,13 @@
 /// Example matches A() in the last line
 ///     (matcher = constructorCall(hasDeclaration(method(
 ///         ofClass(hasName("A"))))))
+/// \code
 ///   class A {
 ///    public:
 ///     A();
 ///   };
 ///   A a = A();
+/// \endcode
 AST_MATCHER_P(CXXMethodDecl, ofClass,
               internal::Matcher<CXXRecordDecl>, InnerMatcher) {
   const CXXRecordDecl *Parent = Node.getParent();
@@ -1648,11 +2094,13 @@
 /// Member calls on the implicit this pointer match as called with '->'.
 ///
 /// Given
+/// \code
 ///   class Y {
 ///     void x() { this->x(); x(); Y y; y.x(); a; this->b; Y::b; }
 ///     int a;
 ///     static int b;
 ///   };
+/// \endcode
 /// memberExpression(isArrow())
 ///   matches this->x, x, y.x, a, this->b
 inline internal::Matcher<MemberExpr> isArrow() {
@@ -1662,9 +2110,11 @@
 /// \brief Matches QualType nodes that are of integer type.
 ///
 /// Given
+/// \code
 ///   void a(int);
 ///   void b(long);
 ///   void c(double);
+/// \endcode
 /// function(hasAnyParameter(hasType(isInteger())))
 /// matches "a(int)", "b(long)", but not "c(double)".
 AST_MATCHER(QualType, isInteger) {
@@ -1675,11 +2125,13 @@
 /// include "top-level" const.
 ///
 /// Given
+/// \code
 ///   void a(int);
 ///   void b(int const);
 ///   void c(const int);
 ///   void d(const int*);
 ///   void e(int const) {};
+/// \endcode
 /// function(hasAnyParameter(hasType(isConstQualified())))
 ///   matches "void b(int const)", "void c(const int)" and
 ///   "void e(int const) {}". It does not match d as there
@@ -1692,9 +2144,11 @@
 /// given matcher.
 ///
 /// Given
+/// \code
 ///   struct { int first, second; } first, second;
 ///   int i(second.first);
 ///   int j(first.second);
+/// \endcode
 /// memberExpression(member(hasName("first")))
 ///   matches second.first
 ///   but not first.second (because the member name there is "second").
@@ -1707,8 +2161,10 @@
 /// matched by a given matcher.
 ///
 /// Given
+/// \code
 ///   struct X { int m; };
 ///   void f(X x) { x.m; m; }
+/// \endcode
 /// memberExpression(hasObjectExpression(hasType(record(hasName("X")))))))
 ///   matches "x.m" and "m"
 /// with hasObjectExpression(...)
@@ -1721,15 +2177,17 @@
 /// \brief Matches any using shadow declaration.
 ///
 /// Given
+/// \code
 ///   namespace X { void b(); }
 ///   using X::b;
+/// \endcode
 /// usingDecl(hasAnyUsingShadowDecl(hasName("b"))))
 ///   matches \code using X::b \endcode
 AST_MATCHER_P(UsingDecl, hasAnyUsingShadowDecl,
-              internal::Matcher<UsingShadowDecl>, Matcher) {
+              internal::Matcher<UsingShadowDecl>, InnerMatcher) {
   for (UsingDecl::shadow_iterator II = Node.shadow_begin();
        II != Node.shadow_end(); ++II) {
-    if (Matcher.matches(**II, Finder, Builder))
+    if (InnerMatcher.matches(**II, Finder, Builder))
       return true;
   }
   return false;
@@ -1739,32 +2197,42 @@
 /// matched by the given matcher.
 ///
 /// Given
+/// \code
 ///   namespace X { int a; void b(); }
 ///   using X::a;
 ///   using X::b;
+/// \endcode
 /// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(function())))
 ///   matches \code using X::b \endcode
 ///   but not \code using X::a \endcode
 AST_MATCHER_P(UsingShadowDecl, hasTargetDecl,
-              internal::Matcher<NamedDecl>, Matcher) {
-  return Matcher.matches(*Node.getTargetDecl(), Finder, Builder);
+              internal::Matcher<NamedDecl>, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getTargetDecl(), Finder, Builder);
 }
 
 /// \brief Matches template instantiations of function, class, or static
 /// member variable template instantiations.
 ///
 /// Given
+/// \code
 ///   template <typename T> class X {}; class A {}; X<A> x;
+/// \endcode
 /// or
+/// \code
 ///   template <typename T> class X {}; class A {}; template class X<A>;
+/// \endcode
 /// record(hasName("::X"), isTemplateInstantiation())
 ///   matches the template instantiation of X<A>.
 ///
 /// But given
-///   template <typename T> class X {}; class A {};
+/// \code
+///   template <typename T>  class X {}; class A {};
 ///   template <> class X<A> {}; X<A> x;
+/// \endcode
 /// record(hasName("::X"), isTemplateInstantiation())
 ///   does not match, as X<A> is an explicit template specialization.
+///
+/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
 inline internal::PolymorphicMatcherWithParam0<
   internal::IsTemplateInstantiationMatcher>
 isTemplateInstantiation() {
@@ -1772,6 +2240,25 @@
     internal::IsTemplateInstantiationMatcher>();
 }
 
+/// \brief Matches explicit template specializations of function, class, or
+/// static member variable template instantiations.
+///
+/// Given
+/// \code
+///   template<typename T> void A(T t) { }
+///   template<> void A(int N) { }
+/// \endcode
+/// function(isExplicitTemplateSpecialization())
+///   matches the specialization A<int>().
+///
+/// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
+inline internal::PolymorphicMatcherWithParam0<
+  internal::IsExplicitTemplateSpecializationMatcher>
+isExplicitTemplateSpecialization() {
+  return internal::PolymorphicMatcherWithParam0<
+    internal::IsExplicitTemplateSpecializationMatcher>();
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
 
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index 3f55685..a94e925 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -858,6 +858,23 @@
   }
 };
 
+/// \brief Matches on explicit template specializations for FunctionDecl,
+/// VarDecl or CXXRecordDecl nodes.
+template <typename T>
+class IsExplicitTemplateSpecializationMatcher : public MatcherInterface<T> {
+  TOOLING_COMPILE_ASSERT((llvm::is_base_of<FunctionDecl, T>::value) ||
+                         (llvm::is_base_of<VarDecl, T>::value) ||
+                         (llvm::is_base_of<CXXRecordDecl, T>::value),
+                         requires_getTemplateSpecializationKind_method);
+ public:
+  virtual bool matches(const T& Node,
+                       ASTMatchFinder* Finder,
+                       BoundNodesTreeBuilder* Builder) const {
+    return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization);
+  }
+};
+
+
 class IsArrowMatcher : public SingleNodeMatcherInterface<MemberExpr> {
 public:
   virtual bool matchesNode(const MemberExpr &Node) const {
diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h
index f99b97a..7f50ee3 100644
--- a/include/clang/Analysis/Analyses/FormatString.h
+++ b/include/clang/Analysis/Analyses/FormatString.h
@@ -201,7 +201,7 @@
   Kind kind;
 };
 
-class ArgTypeResult {
+class ArgType {
 public:
   enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
               AnyCharTy, CStrTy, WCStrTy, WIntTy };
@@ -209,26 +209,26 @@
   const Kind K;
   QualType T;
   const char *Name;
-  ArgTypeResult(bool) : K(InvalidTy), Name(0) {}
+  bool Ptr;
 public:
-  ArgTypeResult(Kind k = UnknownTy) : K(k), Name(0) {}
-  ArgTypeResult(Kind k, const char *n) : K(k), Name(n) {}
-  ArgTypeResult(QualType t) : K(SpecificTy), T(t), Name(0) {}
-  ArgTypeResult(QualType t, const char *n) : K(SpecificTy), T(t), Name(n)  {}
-  ArgTypeResult(CanQualType t) : K(SpecificTy), T(t), Name(0) {}
+  ArgType(Kind k = UnknownTy, const char *n = 0) : K(k), Name(n), Ptr(false) {}
+  ArgType(QualType t, const char *n = 0)
+      : K(SpecificTy), T(t), Name(n), Ptr(false) {}
+  ArgType(CanQualType t) : K(SpecificTy), T(t), Name(0), Ptr(false) {}
 
-  static ArgTypeResult Invalid() { return ArgTypeResult(true); }
-
+  static ArgType Invalid() { return ArgType(InvalidTy); }
   bool isValid() const { return K != InvalidTy; }
 
-  const QualType *getSpecificType() const {
-    return K == SpecificTy ? &T : 0;
+  /// Create an ArgType which corresponds to the type pointer to A.
+  static ArgType PtrTo(const ArgType& A) {
+    assert(A.K >= InvalidTy && "ArgType cannot be pointer to invalid/unknown");
+    ArgType Res = A;
+    Res.Ptr = true;
+    return Res;
   }
 
   bool matchesType(ASTContext &C, QualType argTy) const;
 
-  bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
-
   QualType getRepresentativeType(ASTContext &C) const;
 
   std::string getRepresentativeTypeName(ASTContext &C) const;
@@ -279,7 +279,7 @@
     return length + UsesDotPrefix;
   }
 
-  ArgTypeResult getArgType(ASTContext &Ctx) const;
+  ArgType getArgType(ASTContext &Ctx) const;
 
   void toString(raw_ostream &os) const;
 
@@ -355,6 +355,10 @@
   bool hasStandardConversionSpecifier(const LangOptions &LangOpt) const;
 
   bool hasStandardLengthConversionCombination() const;
+
+  /// For a TypedefType QT, if it is a named integer type such as size_t,
+  /// assign the appropriate value to LM and return true.
+  static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM);
 };
 
 } // end analyze_format_string namespace
@@ -388,7 +392,7 @@
   }
 };
 
-using analyze_format_string::ArgTypeResult;
+using analyze_format_string::ArgType;
 using analyze_format_string::LengthModifier;
 using analyze_format_string::OptionalAmount;
 using analyze_format_string::OptionalFlag;
@@ -463,7 +467,7 @@
   /// 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, bool IsObjCLiteral) const;
+  ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
 
   const OptionalFlag &hasThousandsGrouping() const {
       return HasThousandsGrouping;
@@ -517,35 +521,11 @@
   }
 };
 
-using analyze_format_string::ArgTypeResult;
+using analyze_format_string::ArgType;
 using analyze_format_string::LengthModifier;
 using analyze_format_string::OptionalAmount;
 using analyze_format_string::OptionalFlag;
 
-class ScanfArgTypeResult : public ArgTypeResult {
-public:
-  enum Kind { UnknownTy, InvalidTy, CStrTy, WCStrTy, PtrToArgTypeResultTy };
-private:
-  Kind K;
-  ArgTypeResult A;
-  const char *Name;
-  QualType getRepresentativeType(ASTContext &C) const;
-public:
-  ScanfArgTypeResult(Kind k = UnknownTy, const char* n = 0) : K(k), Name(n) {}
-  ScanfArgTypeResult(ArgTypeResult a, const char *n = 0)
-      : K(PtrToArgTypeResultTy), A(a), Name(n) {
-    assert(A.isValid());
-  }
-
-  static ScanfArgTypeResult Invalid() { return ScanfArgTypeResult(InvalidTy); }
-
-  bool isValid() const { return K != InvalidTy; }
-
-  bool matchesType(ASTContext& C, QualType argTy) const;
-
-  std::string getRepresentativeTypeName(ASTContext& C) const;
-};
-
 class ScanfSpecifier : public analyze_format_string::FormatSpecifier {
   OptionalFlag SuppressAssignment; // '*'
 public:
@@ -574,7 +554,7 @@
     return CS.consumesDataArgument() && !SuppressAssignment;
   }
 
-  ScanfArgTypeResult getArgType(ASTContext &Ctx) const;
+  ArgType getArgType(ASTContext &Ctx) const;
 
   bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
 
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 6ae5b64..416bf86 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -830,6 +830,27 @@
   let TemplateDependent = 1;
 }
 
+// Type safety attributes for `void *' pointers and type tags.
+
+def ArgumentWithTypeTag : InheritableAttr {
+  let Spellings = [GNU<"argument_with_type_tag">,
+                   GNU<"pointer_with_type_tag">];
+  let Args = [IdentifierArgument<"ArgumentKind">,
+              UnsignedArgument<"ArgumentIdx">,
+              UnsignedArgument<"TypeTagIdx">,
+              BoolArgument<"IsPointer">];
+  let Subjects = [Function];
+}
+
+def TypeTagForDatatype : InheritableAttr {
+  let Spellings = [GNU<"type_tag_for_datatype">];
+  let Args = [IdentifierArgument<"ArgumentKind">,
+              TypeArgument<"MatchingCType">,
+              BoolArgument<"LayoutCompatible">,
+              BoolArgument<"MustBeNull">];
+  let Subjects = [Var];
+}
+
 // Microsoft-related attributes
 
 def MsStruct : InheritableAttr {
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 63e8d08..84b2881 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -376,9 +376,9 @@
 BUILTIN(__builtin_ctzl , "iULi" , "nc")
 BUILTIN(__builtin_ctzll, "iULLi", "nc")
 // TODO: int ctzimax(uintmax_t)
-BUILTIN(__builtin_ffs  , "iUi"  , "nc")
-BUILTIN(__builtin_ffsl , "iULi" , "nc")
-BUILTIN(__builtin_ffsll, "iULLi", "nc")
+BUILTIN(__builtin_ffs  , "ii"  , "nc")
+BUILTIN(__builtin_ffsl , "iLi" , "nc")
+BUILTIN(__builtin_ffsll, "iLLi", "nc")
 BUILTIN(__builtin_parity  , "iUi"  , "nc")
 BUILTIN(__builtin_parityl , "iULi" , "nc")
 BUILTIN(__builtin_parityll, "iULLi", "nc")
@@ -476,6 +476,7 @@
 
 BUILTIN(__builtin_expect, "LiLiLi"   , "nc")
 BUILTIN(__builtin_prefetch, "vvC*.", "nc")
+BUILTIN(__builtin_readcyclecounter, "ULLi", "n")
 BUILTIN(__builtin_trap, "v", "nr")
 BUILTIN(__builtin_unreachable, "v", "nr")
 BUILTIN(__builtin_shufflevector, "v."   , "nc")
diff --git a/include/clang/Basic/BuiltinsMips.def b/include/clang/Basic/BuiltinsMips.def
index d647e34..d013715 100644
--- a/include/clang/Basic/BuiltinsMips.def
+++ b/include/clang/Basic/BuiltinsMips.def
@@ -15,38 +15,38 @@
 // The format of this database matches clang/Basic/Builtins.def.
 
 // Add/subtract with optional saturation
-BUILTIN(__builtin_mips_addu_qb, "V4ScV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_addu_s_qb, "V4ScV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_subu_qb, "V4ScV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_subu_s_qb, "V4ScV4ScV4Sc", "nc")
+BUILTIN(__builtin_mips_addu_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_addu_s_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_subu_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_subu_s_qb, "V4ScV4ScV4Sc", "n")
 
-BUILTIN(__builtin_mips_addq_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_addq_s_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_subq_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_subq_s_ph, "V2sV2sV2s", "nc")
+BUILTIN(__builtin_mips_addq_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_addq_s_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_subq_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_subq_s_ph, "V2sV2sV2s", "n")
 
 BUILTIN(__builtin_mips_madd, "LLiLLiii", "nc")
 BUILTIN(__builtin_mips_maddu, "LLiLLiUiUi", "nc")
 BUILTIN(__builtin_mips_msub, "LLiLLiii", "nc")
 BUILTIN(__builtin_mips_msubu, "LLiLLiUiUi", "nc")
 
-BUILTIN(__builtin_mips_addq_s_w, "iii", "nc")
-BUILTIN(__builtin_mips_subq_s_w, "iii", "nc")
+BUILTIN(__builtin_mips_addq_s_w, "iii", "n")
+BUILTIN(__builtin_mips_subq_s_w, "iii", "n")
 
-BUILTIN(__builtin_mips_addsc, "iii", "nc")
-BUILTIN(__builtin_mips_addwc, "iii", "nc")
+BUILTIN(__builtin_mips_addsc, "iii", "n")
+BUILTIN(__builtin_mips_addwc, "iii", "n")
 
 BUILTIN(__builtin_mips_modsub, "iii", "nc")
 
 BUILTIN(__builtin_mips_raddu_w_qb, "iV4Sc", "nc")
 
-BUILTIN(__builtin_mips_absq_s_ph, "V2sV2s", "nc")
-BUILTIN(__builtin_mips_absq_s_w, "ii", "nc")
+BUILTIN(__builtin_mips_absq_s_ph, "V2sV2s", "n")
+BUILTIN(__builtin_mips_absq_s_w, "ii", "n")
 
 BUILTIN(__builtin_mips_precrq_qb_ph, "V4ScV2sV2s", "nc")
-BUILTIN(__builtin_mips_precrqu_s_qb_ph, "V4ScV2sV2s", "nc")
+BUILTIN(__builtin_mips_precrqu_s_qb_ph, "V4ScV2sV2s", "n")
 BUILTIN(__builtin_mips_precrq_ph_w, "V2sii", "nc")
-BUILTIN(__builtin_mips_precrq_rs_ph_w, "V2sii", "nc")
+BUILTIN(__builtin_mips_precrq_rs_ph_w, "V2sii", "n")
 BUILTIN(__builtin_mips_preceq_w_phl, "iV2s", "nc")
 BUILTIN(__builtin_mips_preceq_w_phr, "iV2s", "nc")
 BUILTIN(__builtin_mips_precequ_ph_qbl, "V2sV4Sc", "nc")
@@ -58,26 +58,26 @@
 BUILTIN(__builtin_mips_preceu_ph_qbla, "V2sV4Sc", "nc")
 BUILTIN(__builtin_mips_preceu_ph_qbra, "V2sV4Sc", "nc")
 
-BUILTIN(__builtin_mips_shll_qb, "V4ScV4Sci", "nc")
+BUILTIN(__builtin_mips_shll_qb, "V4ScV4Sci", "n")
 BUILTIN(__builtin_mips_shrl_qb, "V4ScV4Sci", "nc")
-BUILTIN(__builtin_mips_shll_ph, "V2sV2si", "nc")
-BUILTIN(__builtin_mips_shll_s_ph, "V2sV2si", "nc")
+BUILTIN(__builtin_mips_shll_ph, "V2sV2si", "n")
+BUILTIN(__builtin_mips_shll_s_ph, "V2sV2si", "n")
 BUILTIN(__builtin_mips_shra_ph, "V2sV2si", "nc")
 BUILTIN(__builtin_mips_shra_r_ph, "V2sV2si", "nc")
-BUILTIN(__builtin_mips_shll_s_w, "iii", "nc")
+BUILTIN(__builtin_mips_shll_s_w, "iii", "n")
 BUILTIN(__builtin_mips_shra_r_w, "iii", "nc")
 BUILTIN(__builtin_mips_shilo, "LLiLLii", "nc")
 
-BUILTIN(__builtin_mips_muleu_s_ph_qbl, "V2sV4ScV2s", "nc")
-BUILTIN(__builtin_mips_muleu_s_ph_qbr, "V2sV4ScV2s", "nc")
-BUILTIN(__builtin_mips_mulq_rs_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_muleq_s_w_phl, "iV2sV2s", "nc")
-BUILTIN(__builtin_mips_muleq_s_w_phr, "iV2sV2s", "nc")
-BUILTIN(__builtin_mips_mulsaq_s_w_ph, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_maq_s_w_phl, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_maq_s_w_phr, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_maq_sa_w_phl, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_maq_sa_w_phr, "LLiLLiV2sV2s", "nc")
+BUILTIN(__builtin_mips_muleu_s_ph_qbl, "V2sV4ScV2s", "n")
+BUILTIN(__builtin_mips_muleu_s_ph_qbr, "V2sV4ScV2s", "n")
+BUILTIN(__builtin_mips_mulq_rs_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_muleq_s_w_phl, "iV2sV2s", "n")
+BUILTIN(__builtin_mips_muleq_s_w_phr, "iV2sV2s", "n")
+BUILTIN(__builtin_mips_mulsaq_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_s_w_phl, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_s_w_phr, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_sa_w_phl, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_maq_sa_w_phr, "LLiLLiV2sV2s", "n")
 BUILTIN(__builtin_mips_mult, "LLiii", "nc")
 BUILTIN(__builtin_mips_multu, "LLiUiUi", "nc")
 
@@ -85,39 +85,39 @@
 BUILTIN(__builtin_mips_dpau_h_qbr, "LLiLLiV4ScV4Sc", "nc")
 BUILTIN(__builtin_mips_dpsu_h_qbl, "LLiLLiV4ScV4Sc", "nc")
 BUILTIN(__builtin_mips_dpsu_h_qbr, "LLiLLiV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_dpaq_s_w_ph, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_dpsq_s_w_ph, "LLiLLiV2sV2s", "nc")
-BUILTIN(__builtin_mips_dpaq_sa_l_w, "LLiLLiii", "nc")
-BUILTIN(__builtin_mips_dpsq_sa_l_w, "LLiLLiii", "nc")
+BUILTIN(__builtin_mips_dpaq_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpsq_s_w_ph, "LLiLLiV2sV2s", "n")
+BUILTIN(__builtin_mips_dpaq_sa_l_w, "LLiLLiii", "n")
+BUILTIN(__builtin_mips_dpsq_sa_l_w, "LLiLLiii", "n")
 
-BUILTIN(__builtin_mips_cmpu_eq_qb, "vV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_cmpu_lt_qb, "vV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_cmpu_le_qb, "vV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_cmpgu_eq_qb, "iV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_cmpgu_lt_qb, "iV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_cmpgu_le_qb, "iV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_cmp_eq_ph, "vV2sV2s", "nc")
-BUILTIN(__builtin_mips_cmp_lt_ph, "vV2sV2s", "nc")
-BUILTIN(__builtin_mips_cmp_le_ph, "vV2sV2s", "nc")
+BUILTIN(__builtin_mips_cmpu_eq_qb, "vV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpu_lt_qb, "vV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpu_le_qb, "vV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgu_eq_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgu_lt_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmpgu_le_qb, "iV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_cmp_eq_ph, "vV2sV2s", "n")
+BUILTIN(__builtin_mips_cmp_lt_ph, "vV2sV2s", "n")
+BUILTIN(__builtin_mips_cmp_le_ph, "vV2sV2s", "n")
 
-BUILTIN(__builtin_mips_extr_s_h, "iLLii", "nc")
-BUILTIN(__builtin_mips_extr_w, "iLLii", "nc")
-BUILTIN(__builtin_mips_extr_rs_w, "iLLii", "nc")
-BUILTIN(__builtin_mips_extr_r_w, "iLLii", "nc")
-BUILTIN(__builtin_mips_extp, "iLLii", "nc")
-BUILTIN(__builtin_mips_extpdp, "iLLii", "nc")
+BUILTIN(__builtin_mips_extr_s_h, "iLLii", "n")
+BUILTIN(__builtin_mips_extr_w, "iLLii", "n")
+BUILTIN(__builtin_mips_extr_rs_w, "iLLii", "n")
+BUILTIN(__builtin_mips_extr_r_w, "iLLii", "n")
+BUILTIN(__builtin_mips_extp, "iLLii", "n")
+BUILTIN(__builtin_mips_extpdp, "iLLii", "n")
 
-BUILTIN(__builtin_mips_wrdsp, "viIi", "nc")
-BUILTIN(__builtin_mips_rddsp, "iIi", "nc")
-BUILTIN(__builtin_mips_insv, "iii", "nc")
+BUILTIN(__builtin_mips_wrdsp, "viIi", "n")
+BUILTIN(__builtin_mips_rddsp, "iIi", "n")
+BUILTIN(__builtin_mips_insv, "iii", "n")
 BUILTIN(__builtin_mips_bitrev, "ii", "nc")
 BUILTIN(__builtin_mips_packrl_ph, "V2sV2sV2s", "nc")
 BUILTIN(__builtin_mips_repl_qb, "V4Sci", "nc")
 BUILTIN(__builtin_mips_repl_ph, "V2si", "nc")
-BUILTIN(__builtin_mips_pick_qb, "V4ScV4ScV4Sc", "nc")
-BUILTIN(__builtin_mips_pick_ph, "V2sV2sV2s", "nc")
-BUILTIN(__builtin_mips_mthlip, "LLiLLii", "nc")
-BUILTIN(__builtin_mips_bposge32, "i", "nc")
+BUILTIN(__builtin_mips_pick_qb, "V4ScV4ScV4Sc", "n")
+BUILTIN(__builtin_mips_pick_ph, "V2sV2sV2s", "n")
+BUILTIN(__builtin_mips_mthlip, "LLiLLii", "n")
+BUILTIN(__builtin_mips_bposge32, "i", "n")
 BUILTIN(__builtin_mips_lbux, "iv*i", "n")
 BUILTIN(__builtin_mips_lhx, "iv*i", "n")
 BUILTIN(__builtin_mips_lwx, "iv*i", "n")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 2730ab1..75e6074 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -352,17 +352,16 @@
 BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16ciIc", "")
 BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16ciIc","")
 
-// FIXME: These builtins are horribly broken; reenable when PR11305 is fixed.
-//BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","")
-//BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","")
-//BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","")
-//BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","")
-//BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","")
-//BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","")
-//BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","")
-//BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciic","")
-//BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","")
-//BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","")
+BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","")
+BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","")
 
 BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "")
 BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "")
diff --git a/include/clang/Basic/CommentNodes.td b/include/clang/Basic/CommentNodes.td
index 0e3f284..7bf32b7 100644
--- a/include/clang/Basic/CommentNodes.td
+++ b/include/clang/Basic/CommentNodes.td
@@ -17,6 +17,7 @@
   def ParagraphComment : DComment<BlockContentComment>;
   def BlockCommandComment : DComment<BlockContentComment>;
     def ParamCommandComment : DComment<BlockCommandComment>;
+    def TParamCommandComment : DComment<BlockCommandComment>;
     def VerbatimBlockComment : DComment<BlockCommandComment>;
     def VerbatimLineComment : DComment<BlockCommandComment>;
 
diff --git a/include/clang/Basic/ConvertUTF.h b/include/clang/Basic/ConvertUTF.h
index 53d4514..e7cfa8a 100644
--- a/include/clang/Basic/ConvertUTF.h
+++ b/include/clang/Basic/ConvertUTF.h
@@ -110,6 +110,8 @@
 #define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
 #define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
 
+#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
+
 typedef enum {
   conversionOK,           /* conversion successful */
   sourceExhausted,        /* partial character in source, but hit end */
@@ -139,11 +141,13 @@
 ConversionResult ConvertUTF16toUTF8 (
   const UTF16** sourceStart, const UTF16* sourceEnd,
   UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+#endif
 
 ConversionResult ConvertUTF32toUTF8 (
   const UTF32** sourceStart, const UTF32* sourceEnd,
   UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
 
+#ifdef CLANG_NEEDS_THESE_ONE_DAY
 ConversionResult ConvertUTF16toUTF32 (
   const UTF16** sourceStart, const UTF16* sourceEnd,
   UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
@@ -177,6 +181,18 @@
 bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
                        char *&ResultPtr);
 
+/**
+ * Convert an Unicode code point to UTF8 sequence.
+ *
+ * \param Source a Unicode code point.
+ * \param [in,out] ResultPtr pointer to the output buffer, needs to be at least
+ * \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes.  On success \c ResultPtr is
+ * updated one past end of the converted sequence.
+ *
+ * \returns true on success.
+ */
+bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
+
 }
 #endif
 
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 8b4d3a0..3997fb8 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -267,16 +267,14 @@
   }
 
   void PushDiagStatePoint(DiagState *State, SourceLocation L) {
-    FullSourceLoc Loc(L, *SourceMgr);
+    FullSourceLoc Loc(L, getSourceManager());
     // Make sure that DiagStatePoints is always sorted according to Loc.
-    assert((Loc.isValid() || DiagStatePoints.empty()) &&
-           "Adding invalid loc point after another point");
-    assert((Loc.isInvalid() || DiagStatePoints.empty() ||
-            DiagStatePoints.back().Loc.isInvalid() ||
+    assert(Loc.isValid() && "Adding invalid loc point");
+    assert(!DiagStatePoints.empty() &&
+           (DiagStatePoints.back().Loc.isInvalid() ||
             DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
            "Previous point loc comes after or is the same as new one");
-    DiagStatePoints.push_back(DiagStatePoint(State,
-                                             FullSourceLoc(Loc, *SourceMgr)));
+    DiagStatePoints.push_back(DiagStatePoint(State, Loc));
   }
 
   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td
index 890606a..235ca79 100644
--- a/include/clang/Basic/DiagnosticCommentKinds.td
+++ b/include/clang/Basic/DiagnosticCommentKinds.td
@@ -47,6 +47,16 @@
   "empty paragraph passed to '\\%0' command">,
   InGroup<Documentation>, DefaultIgnore;
 
+def warn_doc_block_command_duplicate : Warning<
+  "duplicated command '\\%0'">,
+  InGroup<Documentation>, DefaultIgnore;
+
+def note_doc_block_command_previous : Note<
+  "previous command '\\%0' here">;
+
+def note_doc_block_command_previous_alias : Note<
+  "previous command '\\%0' (an alias of '\\%1') here">;
+
 // \param command
 
 def warn_doc_param_invalid_direction : Warning<
@@ -63,6 +73,13 @@
   "a function declaration">,
   InGroup<Documentation>, DefaultIgnore;
 
+def warn_doc_param_duplicate : Warning<
+  "parameter '%0' is already documented">,
+  InGroup<Documentation>, DefaultIgnore;
+
+def note_doc_param_previous : Note<
+  "previous documentation">;
+
 def warn_doc_param_not_found : Warning<
   "parameter '%0' not found in the function declaration">,
   InGroup<Documentation>, DefaultIgnore;
@@ -70,5 +87,39 @@
 def note_doc_param_name_suggestion : Note<
   "did you mean '%0'?">;
 
+// \tparam command
+
+def warn_doc_tparam_not_attached_to_a_template_decl : Warning<
+  "'\\tparam' command used in a comment that is not attached to "
+  "a template declaration">,
+  InGroup<Documentation>, DefaultIgnore;
+
+def warn_doc_tparam_duplicate : Warning<
+  "template parameter '%0' is already documented">,
+  InGroup<Documentation>, DefaultIgnore;
+
+def note_doc_tparam_previous : Note<
+  "previous documentation">;
+
+def warn_doc_tparam_not_found : Warning<
+  "template parameter '%0' not found in the template declaration">,
+  InGroup<Documentation>, DefaultIgnore;
+
+def note_doc_tparam_name_suggestion : Note<
+  "did you mean '%0'?">;
+
+// \returns command
+
+def warn_doc_returns_not_attached_to_a_function_decl : Warning<
+  "'\\%0' command used in a comment that is not attached to "
+  "a function or method declaration">,
+  InGroup<Documentation>, DefaultIgnore;
+
+def warn_doc_returns_attached_to_a_void_function : Warning<
+  "'\\%0' command used in a comment that is attached to a "
+  "%select{function returning void|constructor|destructor|"
+  "method returning void}1">,
+  InGroup<Documentation>, DefaultIgnore;
+
 } // end of documentation issue category
 } // end of AST component
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index a73240b..a2e1539 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -91,10 +91,10 @@
   "invalid architecture '%0' for deployment target '%1'">;
 def err_drv_objc_gc_arr : Error<
   "cannot specify both '-fobjc-arc' and '%0'">;
-def err_arc_nonfragile_abi : Error<
-  "-fobjc-arc is not supported with legacy abi">;
-def err_arc_unsupported : Error<
-  "-fobjc-arc is not supported on current deployment target">;
+def err_arc_unsupported_on_runtime : Error<
+  "-fobjc-arc is not supported on platforms using the legacy runtime">;
+def err_arc_unsupported_on_toolchain : Error<
+  "-fobjc-arc is not supported on %select{versions of Mac OS prior to 10.6}0">;
 def err_drv_mg_requires_m_or_mm : Error<
   "option '-MG' requires '-M' or '-MM'">;
 def err_drv_asan_android_requires_pie : Error<
@@ -105,9 +105,14 @@
 def warn_c_kext : Warning<
   "ignoring -fapple-kext which is valid for C++ and Objective-C++ only">;
 def warn_drv_input_file_unused : Warning<
-  "%0: '%1' input unused when '%2' is present">;
+  "%0: '%1' input unused%select{ when '%3' is present|}2">,
+  InGroup<DiagGroup<"unused-command-line-argument">>;
+def warn_drv_input_file_unused_by_cpp : Warning<
+  "%0: '%1' input unused in cpp mode">,
+  InGroup<DiagGroup<"unused-command-line-argument">>;
 def warn_drv_preprocessed_input_file_unused : Warning<
-  "%0: previously preprocessed input unused when '%1' is present">;
+  "%0: previously preprocessed input%select{ unused when '%2' is present|}1">,
+  InGroup<DiagGroup<"unused-command-line-argument">>;
 def warn_drv_unused_argument : Warning<
   "argument unused during compilation: '%0'">,
   InGroup<DiagGroup<"unused-command-line-argument">>;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 5a67617..417a22c 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -107,7 +107,7 @@
     "unknown %0 warning specifier: '%1'">,
     InGroup<DiagGroup<"unknown-warning-option"> >;
 
-def warn_unknown_analyzer_checker : Warning<
+def err_unknown_analyzer_checker : Error<
     "no analyzer checkers are associated with '%0'">;
 def warn_incompatible_analyzer_plugin_api : Warning<
     "checker plugin '%0' is not compatible with this version of the analyzer">,
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 8811e6a..c2f2a9f 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -33,6 +33,7 @@
 def SignConversion : DiagGroup<"sign-conversion">;
 def BoolConversion : DiagGroup<"bool-conversion">;
 def IntConversion : DiagGroup<"int-conversion">;
+def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">;
 def NullConversion : DiagGroup<"null-conversion">;
 def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
 def CXXCompat: DiagGroup<"c++-compat">;
@@ -154,6 +155,9 @@
 def ObjCReceiver : DiagGroup<"receiver-expr">;
 def OverlengthStrings : DiagGroup<"overlength-strings">;
 def OverloadedVirtual : DiagGroup<"overloaded-virtual">;
+def PrivateExtern : DiagGroup<"private-extern">;
+def SelTypeCast : DiagGroup<"cast-of-sel-type">;
+def BadFunctionCast : DiagGroup<"bad-function-cast">;
 def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">;
 def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">;
 def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">;
@@ -314,7 +318,8 @@
                             StringConversion,
                             SignConversion,
                             BoolConversion,
-                            NullConversion,
+                            NullConversion, // NULL->non-pointer
+                            NonLiteralNullConversion, // (1-1)->pointer (etc)
                             IntConversion]>,
                  DiagCategory<"Value Conversion Issue">;
 
@@ -339,6 +344,8 @@
 def Format2 : DiagGroup<"format=2",
                         [FormatNonLiteral, FormatSecurity, FormatY2K]>;
 
+def TypeSafety : DiagGroup<"type-safety">;
+
 def Extra : DiagGroup<"extra", [
     MissingFieldInitializers,
     IgnoredQualifiers,
@@ -369,7 +376,9 @@
     Unused,
     VolatileRegisterVar,
     ObjCMissingSuperCalls,
-    OverloadedVirtual
+    OverloadedVirtual,
+    PrivateExtern,
+    SelTypeCast
  ]>;
 
 // Thread Safety warnings 
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 1d55d6e..cc958db 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -332,8 +332,7 @@
   "builtin feature check macro requires a parenthesized identifier">;
 
 def err_warning_check_malformed : Error<
-  "builtin warning check macro requires a parenthesized string">,
-  InGroup<MalformedWarningCheck>;
+  "builtin warning check macro requires a parenthesized string">;
 def warn_has_warning_invalid_option :
    ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">,
    InGroup<MalformedWarningCheck>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 31b8077..b1c16fa 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -415,9 +415,6 @@
   "variable declaration in condition cannot have a parenthesized initializer">;
 def err_extraneous_rparen_in_condition : Error<
   "extraneous ')' after condition, expected a statement">;
-def warn_parens_disambiguated_as_function_decl : Warning<
-  "parentheses were disambiguated as a function declarator">,
-  InGroup<VexingParse>;
 def warn_dangling_else : Warning<
   "add explicit braces to avoid dangling else">,
   InGroup<DanglingElse>;
@@ -680,6 +677,10 @@
   "'unavailable' availability overrides all other availability information">,
   InGroup<Availability>;
 
+// Type safety attributes
+def err_type_safety_unknown_flag : Error<
+  "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
+
 // Language specific pragmas
 // - Generic warnings
 def warn_pragma_expected_lparen : Warning<
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 5c3f115..aaa022e 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -158,6 +158,11 @@
 def warn_empty_parens_are_function_decl : Warning<
   "empty parentheses interpreted as a function declaration">,
   InGroup<VexingParse>;
+def warn_parens_disambiguated_as_function_declaration : Warning<
+  "parentheses were disambiguated as a function declaration">,
+  InGroup<VexingParse>;
+def note_additional_parens_for_variable_declaration : Note<
+  "add a pair of parentheses to declare a variable">;
 def note_empty_parens_function_call : Note<
   "change this ',' to a ';' to call %0">;
 def note_empty_parens_default_ctor : Note<
@@ -192,6 +197,9 @@
 def warn_return_value_udt: Warning<
   "%0 has C-linkage specified, but returns user-defined type %1 which is "
   "incompatible with C">, InGroup<ReturnTypeCLinkage>;
+def warn_return_value_udt_incomplete: Warning<
+  "%0 has C-linkage specified, but returns incomplete type %1 which could be "
+  "incompatible with C">, InGroup<ReturnTypeCLinkage>;
 def warn_implicit_function_decl : Warning<
   "implicit declaration of function %0">,
   InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
@@ -365,9 +373,11 @@
   
 def warn_strncat_large_size : Warning<
   "the value of the size argument in 'strncat' is too large, might lead to a " 
-  "buffer overflow">, InGroup<StrncatSize>, DefaultIgnore;
+  "buffer overflow">, InGroup<StrncatSize>;
 def warn_strncat_src_size : Warning<"size argument in 'strncat' call appears " 
-  "to be size of the source">, InGroup<StrncatSize>, DefaultIgnore;
+  "to be size of the source">, InGroup<StrncatSize>;
+def warn_strncat_wrong_size : Warning<
+  "the value of the size argument to 'strncat' is wrong">, InGroup<StrncatSize>;
 def note_strncat_wrong_size : Note<
   "change the argument to be the free space in the destination buffer minus " 
   "the terminating null byte">;
@@ -477,7 +487,7 @@
   "objc_root_class attribute may only be specified on a root class declaration">;
 def warn_objc_root_class_missing : Warning<
 	"class %0 defined without specifying a base class">,
-  InGroup<ObjCRootClass>, DefaultIgnore;
+  InGroup<ObjCRootClass>;
 def note_objc_needs_superclass : Note<
   "add a super class to fix this problem">;
 def warn_dup_category_def : Warning<
@@ -728,6 +738,9 @@
 def warn_objc_missing_super_dealloc : Warning<
   "method possibly missing a [super dealloc] call">,
   InGroup<ObjCMissingSuperCalls>;
+def error_dealloc_bad_result_type : Error<
+  "dealloc return type must be correctly specified as 'void' under ARC, "
+  "instead of %0">;
 def warn_objc_missing_super_finalize : Warning<
   "method possibly missing a [super finalize] call">,
   InGroup<ObjCMissingSuperCalls>;
@@ -802,7 +815,7 @@
   "friend function cannot be defined in a local class">;
   
 def err_abstract_type_in_decl : Error<
-  "%select{return|parameter|variable|field}0 type %1 is an abstract class">;
+  "%select{return|parameter|variable|field|ivar}0 type %1 is an abstract class">;
 def err_allocation_of_abstract_type : Error<
   "allocating an object of abstract class type %0">;
 def err_throw_abstract_type : Error<
@@ -867,8 +880,6 @@
   "%0 is missing exception specification '%1'">;
 def err_noexcept_needs_constant_expression : Error<
   "argument to noexcept specifier must be a constant expression">;
-def err_exception_spec_unknown : Error<
-  "exception specification is not available until end of class definition">;
 
 // C++ access checking
 def err_class_redeclared_with_different_access : Error<
@@ -898,6 +909,9 @@
   "field of type %0 has %select{private|protected}2 "
   "%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor">,
   AccessControl;
+def err_access_friend_function : Error<
+  "friend function %1 is a %select{private|protected}0 member of %3">,
+  AccessControl;
 
 def err_access_dtor : Error<
   "calling a %select{private|protected}1 destructor of class %0">, 
@@ -1202,9 +1216,16 @@
   "uninitialized reference member is here">;
 def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
   InGroup<Uninitialized>;
+def warn_reference_field_is_uninit : Warning<
+  "reference is not yet bound to a value when used here">,
+  InGroup<Uninitialized>;
 def warn_uninit_self_reference_in_init : Warning<
   "variable %0 is uninitialized when used within its own initialization">,
   InGroup<Uninitialized>;
+def warn_uninit_self_reference_in_reference_init : Warning<
+  "reference %0 is not yet bound to a value when used within its own"
+  " initialization">,
+  InGroup<Uninitialized>;
 def warn_uninit_var : Warning<
   "variable %0 is uninitialized when %select{used here|captured by block}1">,
   InGroup<Uninitialized>, DefaultIgnore;
@@ -1394,7 +1415,15 @@
   "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">;
 def err_for_range_begin_end_types_differ : Error<
   "'begin' and 'end' must return the same type (got %0 and %1)">;
-def note_for_range_type : Note<"range has type %0">;
+def note_in_for_range: Note<
+  "when looking up '%select{begin|end}0' function for range expression "
+  "of type %1">;
+def err_for_range_invalid: Error<
+  "invalid range expression of type %0; no viable '%select{begin|end}1' "
+  "function available">;
+def err_for_range_dereference : Error<
+  "invalid range expression of type %0; did you mean to dereference it "
+  "with '*'?">;
 def note_for_range_begin_end : Note<
   "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">;
 
@@ -1475,6 +1504,11 @@
   "%0 is not literal because it has a user-provided destructor">;
 def note_non_literal_nontrivial_dtor : Note<
   "%0 is not literal because it has a non-trivial destructor">;
+def warn_private_extern : Warning<
+  "use of __private_extern__ on a declaration may not produce external symbol "
+  "private to the linkage unit and is deprecated">, InGroup<PrivateExtern>;
+def note_private_extern : Note<
+  "use __attribute__((visibility(\"hidden\"))) attribute instead">;
 
 // C++11 char16_t/char32_t
 def warn_cxx98_compat_unicode_type : Warning<
@@ -1528,6 +1562,8 @@
   "'%0' attribute requires parameter %1 to be an integer constant">;
 def err_attribute_argument_n_not_string : Error<
   "'%0' attribute requires parameter %1 to be a string">;
+def err_attribute_argument_n_not_identifier : Error<
+  "'%0' attribute requires parameter %1 to be an identifier">;
 def err_attribute_argument_out_of_bounds : Error<
   "'%0' attribute parameter %1 is out of bounds">;
 def err_attribute_requires_objc_interface : Error<
@@ -1536,6 +1572,8 @@
   "uuid attribute contains a malformed GUID">;
 def warn_nonnull_pointers_only : Warning<
   "nonnull attribute only applies to pointer arguments">;
+def err_attribute_pointers_only : Error<
+  "'%0' attribute only applies to pointer arguments">;
 def err_attribute_invalid_implicit_this_argument : Error<
   "'%0' attribute is invalid for the implicit this argument">;
 def err_ownership_type : Error<
@@ -1751,7 +1789,6 @@
 def warn_attribute_not_on_decl : Error<
   "%0 attribute ignored when parsing type">;
 
-
 // Availability attribute
 def warn_availability_unknown_platform : Warning<
   "unknown platform %0 in availability macro">, InGroup<Availability>;
@@ -1887,6 +1924,9 @@
 def warn_impcast_bool_to_null_pointer : Warning<
     "initialization of pointer of type %0 to null from a constant boolean "
     "expression">, InGroup<BoolConversion>;
+def warn_non_literal_null_pointer : Warning<
+    "expression which evaluates to zero treated as a null pointer constant of "
+    "type %0">, InGroup<NonLiteralNullConversion>;
 def warn_impcast_null_pointer_to_integer : Warning<
     "implicit conversion of NULL constant to %0">,
     InGroup<NullConversion>;
@@ -3558,8 +3598,7 @@
 def err_arc_thread_ownership : Error<
   "thread-local variable has non-trivial ownership: type is %0">;
 def err_arc_indirect_no_ownership : Error<
-  "%select{pointer|reference}1 to non-const type %0 with no explicit ownership">,
-  InGroup<AutomaticReferenceCounting>;
+  "%select{pointer|reference}1 to non-const type %0 with no explicit ownership">;
 def err_arc_array_param_no_ownership : Error<
   "must explicitly describe intended ownership of an object array parameter">;
 def err_arc_pseudo_dtor_inconstant_quals : Error<
@@ -3661,6 +3700,10 @@
   "'%0' declared as array of references of type %1">;
 def err_decl_negative_array_size : Error<
   "'%0' declared as an array with a negative size">;
+def err_array_static_outside_prototype : Error<
+  "%0 used in array declarator outside of function prototype">;
+def err_array_static_not_outermost : Error<
+  "%0 used in non-outermost array type derivation">;
 def err_array_star_outside_prototype : Error<
   "star modifier used outside of function prototype">;
 def err_illegal_decl_pointer_to_reference : Error<
@@ -4937,6 +4980,12 @@
   "cast to union type from type %0 not present in union">;
 def err_cast_pointer_from_non_pointer_int : Error<
   "operand of type %0 cannot be cast to a pointer type">;
+def warn_cast_pointer_from_sel : Warning<
+  "cast of type %0 to %1 is deprecated; use sel_getName instead">,
+  InGroup<SelTypeCast>;
+def warn_bad_function_cast : Warning<
+  "cast from function call of type %0 to non-matching type %1">,
+  InGroup<BadFunctionCast>, DefaultIgnore;
 def err_cast_pointer_to_non_pointer_int : Error<
   "pointer cannot be cast to type %0">;
 def err_typecheck_expect_scalar_operand : Error<
@@ -5085,6 +5134,9 @@
   "'constexpr' specifier">;
 def err_in_class_initializer_non_constant : Error<
   "in-class initializer for static data member is not a constant expression">;
+def err_in_class_initializer_references_def_ctor : Error<
+  "defaulted default constructor of %0 cannot be used by non-static data "
+  "member initializer which appears before end of class definition">;
 
 def ext_in_class_initializer_non_constant : Extension<
   "in-class initializer for static data member is not a constant expression; "
@@ -5323,9 +5375,6 @@
 def note_array_index_out_of_bounds : Note<
   "array %0 declared here">;
 
-def warn_printf_write_back : Warning<
-  "use of '%%n' in format string discouraged (potentially insecure)">,
-  InGroup<FormatSecurity>;
 def warn_printf_insufficient_data_args : Warning<
   "more '%%' conversions than data arguments">, InGroup<Format>;
 def warn_printf_data_arg_not_used : Warning<
@@ -5451,6 +5500,23 @@
   "assigning %select{field|instance variable}0 to itself">,
   InGroup<SelfAssignmentField>;
 
+// Type safety attributes
+def err_type_tag_for_datatype_not_ice : Error<
+  "'type_tag_for_datatype' attribute requires the initializer to be "
+  "an %select{integer|integral}0 constant expression">;
+def err_type_tag_for_datatype_too_large : Error<
+  "'type_tag_for_datatype' attribute requires the initializer to be "
+  "an %select{integer|integral}0 constant expression "
+  "that can be represented by a 64 bit integer">;
+def warn_type_tag_for_datatype_wrong_kind : Warning<
+  "this type tag was not designed to be used with this function">,
+  InGroup<TypeSafety>;
+def warn_type_safety_type_mismatch : Warning<
+  "argument type %0 doesn't match specified '%1' type tag "
+  "%select{that requires %3|}2">, InGroup<TypeSafety>;
+def warn_type_safety_null_pointer_required : Warning<
+  "specified %0 type tag requires a null pointer">, InGroup<TypeSafety>;
+
 // Generic selections.
 def err_assoc_type_incomplete : Error<
   "type %0 in generic association incomplete">;
@@ -5482,8 +5548,7 @@
 
 // CFString checking
 def err_cfstring_literal_not_string_constant : Error<
-  "CFString literal is not a string constant">,
-  InGroup<DiagGroup<"CFString-literal">>;
+  "CFString literal is not a string constant">;
 def warn_cfstring_truncated : Warning<
   "input conversion stopped due to an input byte that does not "
   "belong to the input codeset UTF-8">,
@@ -5545,12 +5610,10 @@
 def note_insert_break_fixit : Note<
   "insert 'break;' to avoid fall-through">;
 def err_fallthrough_attr_wrong_target : Error<
-  "clang::fallthrough attribute is only allowed on empty statements">,
-  InGroup<IgnoredAttributes>;
+  "clang::fallthrough attribute is only allowed on empty statements">;
 def note_fallthrough_insert_semi_fixit : Note<"did you forget ';'?">;
 def err_fallthrough_attr_outside_switch : Error<
-  "fallthrough annotation is outside switch statement">,
-  InGroup<IgnoredAttributes>;
+  "fallthrough annotation is outside switch statement">;
 def warn_fallthrough_attr_invalid_placement : Warning<
   "fallthrough annotation does not directly precede switch label">,
   InGroup<ImplicitFallthrough>;
@@ -5750,6 +5813,8 @@
 def warn_missing_method_return_type : Warning<
   "method has no return type specified; defaults to 'id'">,
   InGroup<MissingMethodReturnType>, DefaultIgnore;
+def warn_direct_ivar_access : Warning<"instance variable %0 is being "
+  "directly accessed">, InGroup<DiagGroup<"direct-ivar-access">>, DefaultIgnore;
 
 // Spell-checking diagnostics
 def err_unknown_type_or_class_name_suggest : Error<
diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h
index 6be5053..edd89ec 100644
--- a/include/clang/Basic/ExceptionSpecificationType.h
+++ b/include/clang/Basic/ExceptionSpecificationType.h
@@ -25,7 +25,7 @@
   EST_MSAny,            ///< Microsoft throw(...) extension
   EST_BasicNoexcept,    ///< noexcept
   EST_ComputedNoexcept, ///< noexcept(expression)
-  EST_Delayed,          ///< not known yet
+  EST_Unevaluated,      ///< not evaluated yet, for special member function
   EST_Uninstantiated    ///< not instantiated yet
 };
 
@@ -37,6 +37,10 @@
   return ESpecType == EST_BasicNoexcept || ESpecType == EST_ComputedNoexcept;
 }
 
+inline bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType) {
+  return ESpecType == EST_Unevaluated || ESpecType == EST_Uninstantiated;
+}
+
 /// \brief Possible results from evaluation of a noexcept expression.
 enum CanThrowResult {
   CT_Cannot,
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index 930523f..b00f2b7 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -186,6 +186,9 @@
   /// \brief Removes the specified FileSystemStatCache object from the manager.
   void removeStatCache(FileSystemStatCache *statCache);
 
+  /// \brief Removes all FileSystemStatCache objects from the manager.
+  void clearStatCaches();
+
   /// \brief Lookup, cache, and verify the specified directory (real or
   /// virtual).
   ///
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 6170c46..69f58bc 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -136,7 +136,7 @@
 LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
 LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
 LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
-LANGOPT(ObjCRuntimeHasWeak , 1, 0, "__weak support in the ARC runtime")
+LANGOPT(ObjCARCWeak         , 1, 0, "__weak support in the ARC runtime")
 LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map")
 
 LANGOPT(MRTD , 1, 0, "-mrtd calling convention")
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index da3ecca..2ca421b 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -126,12 +126,25 @@
     return !isGNUFamily();
   }
 
+  /// \brief Does this runtime allow ARC at all?
+  bool allowsARC() const {
+    switch (getKind()) {
+    case FragileMacOSX: return false;
+    case MacOSX: return true;
+    case iOS: return true;
+    case GCC: return false;
+    case GNUstep: return true;
+    case ObjFW: return true;
+    }
+    llvm_unreachable("bad kind");
+  }
+
   /// \brief Does this runtime natively provide the ARC entrypoints? 
   ///
   /// ARC cannot be directly supported on a platform that does not provide
   /// these entrypoints, although it may be supportable via a stub
   /// library.
-  bool hasARC() const {
+  bool hasNativeARC() const {
     switch (getKind()) {
     case FragileMacOSX: return false;
     case MacOSX: return getVersion() >= VersionTuple(10, 7);
@@ -139,16 +152,22 @@
 
     case GCC: return false;
     case GNUstep: return getVersion() >= VersionTuple(1, 6);
-    case ObjFW: return false; // XXX: this will change soon
+    case ObjFW: return true;
     }
     llvm_unreachable("bad kind");
   }
 
+  /// Does this runtime allow the use of __weak?
+  bool allowsWeak() const {
+    return hasNativeWeak();
+  }
+
   /// \brief Does this runtime natively provide ARC-compliant 'weak'
   /// entrypoints?
-  bool hasWeak() const {
-    // Right now, this is always equivalent to the ARC decision.
-    return hasARC();
+  bool hasNativeWeak() const {
+    // Right now, this is always equivalent to whether the runtime
+    // natively supports ARC decision.
+    return hasNativeARC();
   }
 
   /// \brief Does this runtime directly support the subscripting methods?
@@ -170,6 +189,34 @@
     llvm_unreachable("bad kind");
   }
 
+  /// \brief Does this runtime allow sizeof or alignof on object types?
+  bool allowsSizeofAlignof() const {
+    return isFragile();
+  }
+
+  /// \brief Does this runtime allow pointer arithmetic on objects?
+  ///
+  /// This covers +, -, ++, --, and (if isSubscriptPointerArithmetic()
+  /// yields true) [].
+  bool allowsPointerArithmetic() const {
+    switch (getKind()) {
+    case FragileMacOSX:
+    case GCC:
+      return true;
+    case MacOSX:
+    case iOS:
+    case GNUstep:
+    case ObjFW:
+      return false;
+    }
+    llvm_unreachable("bad kind");
+  }
+
+  /// \brief Is subscripting pointer arithmetic?
+  bool isSubscriptPointerArithmetic() const {
+    return allowsPointerArithmetic();
+  }
+
   /// \brief Does this runtime provide an objc_terminate function?
   ///
   /// This is used in handlers for exceptions during the unwind process;
@@ -198,6 +245,7 @@
     }
     llvm_unreachable("bad kind");
   }
+
   /// \brief Does this runtime use zero-cost exceptions?
   bool hasUnwindExceptions() const {
     switch (getKind()) {
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index 79273fc..66109e7 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -65,8 +65,7 @@
 
 inline void Pad(raw_ostream& Out, unsigned A) {
   Offset off = (Offset) Out.tell();
-  uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off;
-  for (; n ; --n)
+  for (uint32_t n = llvm::OffsetToAlignment(off, A); n; --n)
     Emit8(Out, 0);
 }
 
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 1496355..32268d7 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -1517,13 +1517,12 @@
       return true;
 
     // If it is the last local entry, then it does if the location is local.
-    if (static_cast<unsigned>(FID.ID+1) == LocalSLocEntryTable.size()) {
+    if (FID.ID+1 == static_cast<int>(LocalSLocEntryTable.size()))
       return SLocOffset < NextLocalOffset;
-    }
 
     // Otherwise, the entry after it has to not include it. This works for both
     // local and loaded entries.
-    return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
+    return SLocOffset < getSLocEntryByID(FID.ID+1).getOffset();
   }
 
   /// \brief Create a new fileID for the specified ContentCache and
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 8fd3166..86b9bde 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -39,8 +39,6 @@
   HelpText<"Generate unoptimized CFGs for all analyses">;
 def analysis_CFGAddImplicitDtors : Flag<"-cfg-add-implicit-dtors">,
   HelpText<"Add C++ implicit destructors to CFGs for all analyses">;
-def analysis_CFGAddInitializers : Flag<"-cfg-add-initializers">,
-  HelpText<"Add C++ initializers to CFGs for all analyses">;
 
 def analyzer_store : Separate<"-analyzer-store">,
   HelpText<"Source Code Analysis - Abstract Memory Store Models">;
@@ -286,6 +284,11 @@
   HelpText<"The directory which holds the compiler resource files">;
 def version : Flag<"-version">,
   HelpText<"Print the compiler version">;
+def ast_dump_filter : Separate<"-ast-dump-filter">,
+  MetaVarName<"<dump_filter>">,
+  HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration"
+           " nodes having a certain substring in a qualified name. Use"
+           " -ast-list to list all filterable declaration node names.">;
 
 let Group = Action_Group in {
 
@@ -310,6 +313,8 @@
   HelpText<"Output input source as HTML">;
 def ast_print : Flag<"-ast-print">,
   HelpText<"Build ASTs and then pretty-print them">;
+def ast_list : Flag<"-ast-list">,
+  HelpText<"Build ASTs and print the list of declaration node qualified names">;
 def ast_dump : Flag<"-ast-dump">,
   HelpText<"Build ASTs and then debug dump them">;
 def ast_dump_xml : Flag<"-ast-dump-xml">,
@@ -410,6 +415,8 @@
   HelpText<"Should __STATIC__ be defined">;
 def stack_protector : Separate<"-stack-protector">,
   HelpText<"Enable stack protectors">;
+def stack_protector_buffer_size : Separate<"-stack-protector-buffer-size">,
+  HelpText<"Lower bound for a buffer to be considered for stack protection">;
 def fvisibility : Separate<"-fvisibility">,
   HelpText<"Default symbol visibility">;
 def ftemplate_depth : Separate<"-ftemplate-depth">,
diff --git a/include/clang/Driver/OptTable.h b/include/clang/Driver/OptTable.h
index 27bd119..15a22fe 100644
--- a/include/clang/Driver/OptTable.h
+++ b/include/clang/Driver/OptTable.h
@@ -15,21 +15,6 @@
 
 namespace clang {
 namespace driver {
-namespace options {
-  enum DriverFlag {
-    DriverOption     = (1 << 0),
-    HelpHidden       = (1 << 1),
-    LinkerInput      = (1 << 2),
-    NoArgumentUnused = (1 << 3),
-    NoForward        = (1 << 4),
-    RenderAsInput    = (1 << 5),
-    RenderJoined     = (1 << 6),
-    RenderSeparate   = (1 << 7),
-    Unsupported      = (1 << 8),
-    CC1Option        = (1 << 9)
-  };
-}
-
   class Arg;
   class ArgList;
   class InputArgList;
@@ -123,9 +108,7 @@
     }
 
     /// \brief Should the help for the given option be hidden by default.
-    bool isOptionHelpHidden(OptSpecifier id) const {
-      return getInfo(id).Flags & options::HelpHidden;
-    }
+    bool isOptionHelpHidden(OptSpecifier id) const;
 
     /// \brief Get the help text to use to describe this option.
     const char *getOptionHelpText(OptSpecifier id) const {
diff --git a/include/clang/Driver/Option.h b/include/clang/Driver/Option.h
index e6c4e12..a149f5b 100644
--- a/include/clang/Driver/Option.h
+++ b/include/clang/Driver/Option.h
@@ -10,15 +10,30 @@
 #ifndef CLANG_DRIVER_OPTION_H_
 #define CLANG_DRIVER_OPTION_H_
 
-#include "clang/Driver/OptSpecifier.h"
+#include "clang/Driver/OptTable.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
 #include "clang/Basic/LLVM.h"
 
 namespace clang {
 namespace driver {
   class Arg;
   class ArgList;
-  class OptionGroup;
+
+namespace options {
+  enum DriverFlag {
+    DriverOption     = (1 << 0),
+    HelpHidden       = (1 << 1),
+    LinkerInput      = (1 << 2),
+    NoArgumentUnused = (1 << 3),
+    NoForward        = (1 << 4),
+    RenderAsInput    = (1 << 5),
+    RenderJoined     = (1 << 6),
+    RenderSeparate   = (1 << 7),
+    Unsupported      = (1 << 8),
+    CC1Option        = (1 << 9)
+  };
+}
 
   /// Option - Abstract representation for a single form of driver
   /// argument.
@@ -54,86 +69,72 @@
     };
 
   private:
-    OptionClass Kind;
+    const OptTable::Info *Info;
 
     /// The option ID.
     OptSpecifier ID;
 
-    /// The option name.
-    StringRef Name;
-
     /// Group this option is a member of, if any.
-    const OptionGroup *Group;
+    const Option *Group;
 
     /// Option that this is an alias for, if any.
     const Option *Alias;
 
-    /// Unsupported options will be rejected.
-    bool Unsupported : 1;
-
-    /// Treat this option like a linker input?
-    bool LinkerInput : 1;
-
-    /// When rendering as an input, don't render the option.
-
-    // FIXME: We should ditch the render/renderAsInput distinction.
-    bool NoOptAsInput : 1;
-
-    /// 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;
-
-    /// This option should not report argument unused errors.
-    bool NoArgumentUnused : 1;
-
-    /// This option should not be implicitly forwarded.
-    bool NoForward : 1;
-
-    /// CC1Option - This option should be accepted by clang -cc1.
-    bool CC1Option : 1;
-
-  protected:
-    Option(OptionClass Kind, OptSpecifier ID, const char *Name,
-           const OptionGroup *Group, const Option *Alias);
   public:
-    virtual ~Option();
+    Option(const OptTable::Info *Info, OptSpecifier ID,
+           const Option *Group, const Option *Alias);
+    ~Option();
 
     unsigned getID() const { return ID.getID(); }
-    OptionClass getKind() const { return Kind; }
-    StringRef getName() const { return Name; }
-    const OptionGroup *getGroup() const { return Group; }
+    OptionClass getKind() const { return OptionClass(Info->Kind); }
+    StringRef getName() const { return Info->Name; }
+    const Option *getGroup() const { return Group; }
     const Option *getAlias() const { return Alias; }
 
-    bool isUnsupported() const { return Unsupported; }
-    void setUnsupported(bool Value) { Unsupported = Value; }
+    unsigned getNumArgs() const { return Info->Param; }
 
-    bool isLinkerInput() const { return LinkerInput; }
-    void setLinkerInput(bool Value) { LinkerInput = Value; }
+    bool isUnsupported() const { return Info->Flags & options::Unsupported; }
 
-    bool hasNoOptAsInput() const { return NoOptAsInput; }
-    void setNoOptAsInput(bool Value) { NoOptAsInput = Value; }
+    bool isLinkerInput() const { return Info->Flags & options::LinkerInput; }
+
+    bool hasNoOptAsInput() const { return Info->Flags & options::RenderAsInput;}
 
     RenderStyleKind getRenderStyle() const {
-      return RenderStyleKind(RenderStyle);
+      if (Info->Flags & options::RenderJoined)
+        return RenderJoinedStyle;
+      if (Info->Flags & options::RenderSeparate)
+        return RenderSeparateStyle;
+      switch (getKind()) {
+      case GroupClass:
+      case InputClass:
+      case UnknownClass:
+        return RenderValuesStyle;
+      case JoinedClass:
+      case JoinedAndSeparateClass:
+        return RenderJoinedStyle;
+      case CommaJoinedClass:
+        return RenderCommaJoinedStyle;
+      case FlagClass:
+      case SeparateClass:
+      case MultiArgClass:
+      case JoinedOrSeparateClass:
+        return RenderSeparateStyle;
+      }
+      llvm_unreachable("Unexpected kind!");
     }
-    void setRenderStyle(RenderStyleKind Value) { RenderStyle = Value; }
 
-    bool isDriverOption() const { return DriverOption; }
-    void setDriverOption(bool Value) { DriverOption = Value; }
+    bool isDriverOption() const { return Info->Flags & options::DriverOption; }
 
-    bool hasNoArgumentUnused() const { return NoArgumentUnused; }
-    void setNoArgumentUnused(bool Value) { NoArgumentUnused = Value; }
+    bool hasNoArgumentUnused() const {
+      return Info->Flags & options::NoArgumentUnused;
+    }
 
-    bool hasNoForward() const { return NoForward; }
-    void setNoForward(bool Value) { NoForward = Value; }
+    bool hasNoForward() const { return Info->Flags & options::NoForward; }
 
-    bool isCC1Option() const { return CC1Option; }
-    void setIsCC1Option(bool Value) { CC1Option = Value; }
+    bool isCC1Option() const { return Info->Flags & options::CC1Option; }
 
     bool hasForwardToGCC() const {
-      return !NoForward && !DriverOption && !LinkerInput;
+      return !hasNoForward() && !isDriverOption() && !isLinkerInput();
     }
 
     /// getUnaliasedOption - Return the final option this option
@@ -164,158 +165,9 @@
     /// 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 ArgList &Args, unsigned &Index) const = 0;
+    Arg *accept(const ArgList &Args, unsigned &Index) const;
 
     void dump() const;
-
-    static bool classof(const Option *) { return true; }
-  };
-
-  /// OptionGroup - A set of options which are can be handled uniformly
-  /// by the driver.
-  class OptionGroup : public Option {
-  public:
-    OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::GroupClass;
-    }
-    static bool classof(const OptionGroup *) { return true; }
-  };
-
-  // Dummy option classes.
-
-  /// InputOption - Dummy option class for representing driver inputs.
-  class InputOption : public Option {
-  public:
-    InputOption(OptSpecifier ID);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::InputClass;
-    }
-    static bool classof(const InputOption *) { return true; }
-  };
-
-  /// UnknownOption - Dummy option class for represent unknown arguments.
-  class UnknownOption : public Option {
-  public:
-    UnknownOption(OptSpecifier ID);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::UnknownClass;
-    }
-    static bool classof(const UnknownOption *) { return true; }
-  };
-
-  // Normal options.
-
-  class FlagOption : public Option {
-  public:
-    FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
-               const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::FlagClass;
-    }
-    static bool classof(const FlagOption *) { return true; }
-  };
-
-  class JoinedOption : public Option {
-  public:
-    JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
-                 const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::JoinedClass;
-    }
-    static bool classof(const JoinedOption *) { return true; }
-  };
-
-  class SeparateOption : public Option {
-  public:
-    SeparateOption(OptSpecifier ID, const char *Name,
-                   const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::SeparateClass;
-    }
-    static bool classof(const SeparateOption *) { return true; }
-  };
-
-  class CommaJoinedOption : public Option {
-  public:
-    CommaJoinedOption(OptSpecifier ID, const char *Name,
-                      const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::CommaJoinedClass;
-    }
-    static bool classof(const CommaJoinedOption *) { return true; }
-  };
-
-  // FIXME: Fold MultiArgOption into SeparateOption?
-
-  /// MultiArgOption - An option which takes multiple arguments (these
-  /// are always separate arguments).
-  class MultiArgOption : public Option {
-    unsigned NumArgs;
-
-  public:
-    MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
-                   const Option *Alias, unsigned NumArgs);
-
-    unsigned getNumArgs() const { return NumArgs; }
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::MultiArgClass;
-    }
-    static bool classof(const MultiArgOption *) { return true; }
-  };
-
-  /// JoinedOrSeparateOption - An option which either literally
-  /// prefixes its (non-empty) value, or is follwed by a value.
-  class JoinedOrSeparateOption : public Option {
-  public:
-    JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
-                           const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::JoinedOrSeparateClass;
-    }
-    static bool classof(const JoinedOrSeparateOption *) { return true; }
-  };
-
-  /// JoinedAndSeparateOption - An option which literally prefixes its
-  /// value and is followed by another value.
-  class JoinedAndSeparateOption : public Option {
-  public:
-    JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
-                            const OptionGroup *Group, const Option *Alias);
-
-    virtual Arg *accept(const ArgList &Args, unsigned &Index) const;
-
-    static bool classof(const Option *O) {
-      return O->getKind() == Option::JoinedAndSeparateClass;
-    }
-    static bool classof(const JoinedAndSeparateOption *) { return true; }
   };
 
 } // end namespace driver
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index ab417bb..bc6331e 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -183,8 +183,8 @@
   /// Does this tool chain support Objective-C garbage collection.
   virtual bool SupportsObjCGC() const { return true; }
 
-  /// Does this tool chain support Objective-C ARC.
-  virtual bool SupportsObjCARC() const { return true; }
+  /// Complain if this tool chain doesn't support Objective-C ARC.
+  virtual void CheckObjCARC() const {}
 
   /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
   /// compile unit information.
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index cef9509..3731478 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -33,11 +33,15 @@
 // original C code.  The output is intended to be in a format such that
 // clang could re-parse the output back into the same AST, but the
 // implementation is still incomplete.
-ASTConsumer *CreateASTPrinter(raw_ostream *OS);
+ASTConsumer *CreateASTPrinter(raw_ostream *OS, StringRef FilterString);
 
 // AST dumper: dumps the raw AST in human-readable form to stderr; this is
 // intended for debugging.
-ASTConsumer *CreateASTDumper();
+ASTConsumer *CreateASTDumper(StringRef FilterString);
+
+// AST Decl node lister: prints qualified names of all filterable AST Decl
+// nodes.
+ASTConsumer *CreateASTDeclNodeLister();
 
 // AST XML-dumper: dumps out the AST to stderr in a very detailed XML
 // format; this is intended for particularly intense debugging.
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index 8dd863e..144b796 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -284,12 +284,11 @@
     /// \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;
+    /// The bits in the bitmask correspond to the values of
+    /// CodeCompleteContext::Kind. To map from a completion context kind to a
+    /// bit, shift 1 by that number of bits. Many completions can occur in
+    /// several different contexts.
+    uint64_t ShowInContexts;
     
     /// \brief The priority given to this code-completion result.
     unsigned Priority;
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index b5b9394..829ad71 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -47,7 +47,10 @@
 #endif
 
 ANALYSIS_IPA(None, "none", "Perform only intra-procedural analysis")
-ANALYSIS_IPA(Inlining, "inlining", "Experimental: Inline callees when their definitions are available")
+ANALYSIS_IPA(BasicInlining, "basic-inlining", "Inline C functions and blocks when their definitions are available")
+ANALYSIS_IPA(Inlining, "inlining", "Inline callees when their definitions are available")
+ANALYSIS_IPA(DynamicDispatch, "dynamic", "Experimental: Enable inlining of dynamically dispatched methods")
+ANALYSIS_IPA(DynamicDispatchBifurcate, "dynamic-bifurcate", "Experimental: Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailable")
 
 #ifndef ANALYSIS_INLINING_MODE
 #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC)
diff --git a/include/clang/Frontend/AnalyzerOptions.h b/include/clang/Frontend/AnalyzerOptions.h
index 847bfbd..4e5d7cb 100644
--- a/include/clang/Frontend/AnalyzerOptions.h
+++ b/include/clang/Frontend/AnalyzerOptions.h
@@ -96,7 +96,6 @@
   unsigned VisualizeEGUbi : 1;
   unsigned UnoptimizedCFG : 1;
   unsigned CFGAddImplicitDtors : 1;
-  unsigned CFGAddInitializers : 1;
   unsigned EagerlyTrimEGraph : 1;
   unsigned PrintStats : 1;
   unsigned NoRetryExhausted : 1;
@@ -110,7 +109,7 @@
     AnalysisConstraintsOpt = RangeConstraintsModel;
     AnalysisDiagOpt = PD_HTML;
     AnalysisPurgeOpt = PurgeStmt;
-    IPAMode = Inlining;
+    IPAMode = BasicInlining;
     ShowCheckerHelp = 0;
     AnalyzeAll = 0;
     AnalyzerDisplayProgress = 0;
@@ -121,7 +120,6 @@
     VisualizeEGUbi = 0;
     UnoptimizedCFG = 0;
     CFGAddImplicitDtors = 0;
-    CFGAddInitializers = 0;
     EagerlyTrimEGraph = 0;
     PrintStats = 0;
     NoRetryExhausted = 0;
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 3e34093..8610b8a 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -185,6 +185,9 @@
   /// The run-time penalty for bounds checking, or 0 to disable.
   unsigned char BoundsChecking;
 
+  /// The lower bound for a buffer to be considered for stack protection.
+  unsigned SSPBufferSize;
+
   /// The default TLS model to use.
   TLSModel DefaultTLSModel;
 
@@ -241,6 +244,7 @@
     StackRealignment = 0;
     StackAlignment = 0;
     BoundsChecking = 0;
+    SSPBufferSize = 8;
     UseInitArray = 0;
 
     DebugInfo = NoDebugInfo;
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 8f7fe87..477ac45 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -50,6 +50,12 @@
                                          StringRef InFile);
 };
 
+class ASTDeclListAction : public ASTFrontendAction {
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile);
+};
+
 class ASTDumpXMLAction : public ASTFrontendAction {
 protected:
   virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index 22cce9c..ce1cd9b 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -20,6 +20,7 @@
 
 namespace frontend {
   enum ActionKind {
+    ASTDeclList,            ///< Parse ASTs and list Decl nodes.
     ASTDump,                ///< Parse ASTs and dump them.
     ASTDumpXML,             ///< Parse ASTs and dump them in XML.
     ASTPrint,               ///< Parse ASTs and print them.
@@ -141,6 +142,9 @@
   /// If given, the new suffix for fix-it rewritten files.
   std::string FixItSuffix;
 
+  /// If given, filter dumped AST Decl nodes by this substring.
+  std::string ASTDumpFilter;
+
   /// If given, enable code completion at the provided location.
   ParsedSourceLocation CodeCompletionAt;
 
diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h
index 4a6081b..bc39bba 100644
--- a/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -12,9 +12,9 @@
 
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/STLExtras.h"
 #include <climits>
 
@@ -167,18 +167,40 @@
   };
 
 private:
-  typedef llvm::DenseSet<FileID> FilesWithDiagnosticsSet;
-  typedef llvm::SmallPtrSet<const FileEntry *, 4> FilesWithDirectivesSet;
-
   DiagnosticsEngine &Diags;
   DiagnosticConsumer *PrimaryClient;
   bool OwnsPrimaryClient;
   OwningPtr<TextDiagnosticBuffer> Buffer;
   const Preprocessor *CurrentPreprocessor;
-  FilesWithDiagnosticsSet FilesWithDiagnostics;
-  FilesWithDirectivesSet FilesWithDirectives;
+  const LangOptions *LangOpts;
+  SourceManager *SrcManager;
+  unsigned ActiveSourceFiles;
   ExpectedData ED;
+
   void CheckDiagnostics();
+  void setSourceManager(SourceManager &SM) {
+    assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!");
+    SrcManager = &SM;
+  }
+
+#ifndef NDEBUG
+  class UnparsedFileStatus {
+    llvm::PointerIntPair<const FileEntry *, 1, bool> Data;
+
+  public:
+    UnparsedFileStatus(const FileEntry *File, bool FoundDirectives)
+      : Data(File, FoundDirectives) {}
+
+    const FileEntry *getFile() const { return Data.getPointer(); }
+    bool foundDirectives() const { return Data.getInt(); }
+  };
+
+  typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap;
+  typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap;
+
+  ParsedFilesMap ParsedFiles;
+  UnparsedFilesMap UnparsedFiles;
+#endif
 
 public:
   /// Create a new verifying diagnostic client, which will issue errors to
@@ -192,6 +214,20 @@
 
   virtual void EndSourceFile();
 
+  enum ParsedStatus {
+    /// File has been processed via HandleComment.
+    IsParsed,
+
+    /// File has diagnostics and may have directives.
+    IsUnparsed,
+
+    /// File has diagnostics but guaranteed no directives.
+    IsUnparsedNoDirectives
+  };
+
+  /// \brief Update lists of parsed and unparsed files.
+  void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS);
+
   virtual bool HandleComment(Preprocessor &PP, SourceRange Comment);
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index 25a4903..44f9ab3 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -101,7 +101,7 @@
 
 public:
   // The current PTH version.
-  enum { Version = 9 };
+  enum { Version = 10 };
 
   ~PTHManager();
 
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 02e3f1e..ca2c59d 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -724,6 +724,14 @@
       CachedTokens[CachedLexPos-1] = Tok;
   }
 
+  /// TypoCorrectToken - Update the current token to represent the provided
+  /// identifier, in order to cache an action performed by typo correction.
+  void TypoCorrectToken(const Token &Tok) {
+    assert(Tok.getIdentifierInfo() && "Expected identifier token");
+    if (CachedLexPos != 0 && isBacktrackEnabled())
+      CachedTokens[CachedLexPos-1] = Tok;
+  }
+
   /// \brief Recompute the current lexer kind based on the CurLexer/CurPTHLexer/
   /// CurTokenLexer pointers.
   void recomputeCurLexerKind();
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index ca38046..5e80ca3 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -30,12 +30,14 @@
   class PragmaHandler;
   class Scope;
   class BalancedDelimiterTracker;
+  class CorrectionCandidateCallback;
   class DeclGroupRef;
   class DiagnosticBuilder;
   class Parser;
   class ParsingDeclRAIIObject;
   class ParsingDeclSpec;
   class ParsingDeclarator;
+  class ParsingFieldDeclarator;
   class PragmaUnusedHandler;
   class ColonProtectionRAIIObject;
   class InMessageExpressionRAIIObject;
@@ -203,6 +205,9 @@
   /// top-level declaration is finished.
   SmallVector<TemplateIdAnnotation *, 16> TemplateIds;
 
+  /// \brief Identifiers which have been declared within a tentative parse.
+  SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers;
+
   IdentifierInfo *getSEHExceptKeyword();
 
   /// True if we are within an Objective-C container while parsing C-like decls.
@@ -481,7 +486,28 @@
   // find a type name by attempting typo correction.
   bool TryAnnotateTypeOrScopeToken(bool EnteringContext = false,
                                    bool NeedType = false);
+  bool TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
+                                                 bool NeedType,
+                                                 CXXScopeSpec &SS,
+                                                 bool IsNewScope);
   bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+  enum AnnotatedNameKind {
+    /// Annotation has failed and emitted an error.
+    ANK_Error,
+    /// The identifier is a tentatively-declared name.
+    ANK_TentativeDecl,
+    /// The identifier is a template name. FIXME: Add an annotation for that.
+    ANK_TemplateName,
+    /// The identifier can't be resolved.
+    ANK_Unresolved,
+    /// Annotation was successful.
+    ANK_Success
+  };
+  AnnotatedNameKind TryAnnotateName(bool IsAddressOfOperand,
+                                    CorrectionCandidateCallback *CCC = 0);
+
+  /// Push a tok::annot_cxxscope token onto the token stream.
+  void AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation);
 
   /// TryAltiVecToken - Check for context-sensitive AltiVec identifier tokens,
   /// replacing them with the non-context-sensitive keywords.  This returns
@@ -528,12 +554,15 @@
   class TentativeParsingAction {
     Parser &P;
     Token PrevTok;
+    size_t PrevTentativelyDeclaredIdentifierCount;
     unsigned short PrevParenCount, PrevBracketCount, PrevBraceCount;
     bool isActive;
 
   public:
     explicit TentativeParsingAction(Parser& p) : P(p) {
       PrevTok = P.Tok;
+      PrevTentativelyDeclaredIdentifierCount =
+          P.TentativelyDeclaredIdentifiers.size();
       PrevParenCount = P.ParenCount;
       PrevBracketCount = P.BracketCount;
       PrevBraceCount = P.BraceCount;
@@ -542,6 +571,8 @@
     }
     void Commit() {
       assert(isActive && "Parsing action was finished!");
+      P.TentativelyDeclaredIdentifiers.resize(
+          PrevTentativelyDeclaredIdentifierCount);
       P.PP.CommitBacktrackedTokens();
       isActive = false;
     }
@@ -549,6 +580,8 @@
       assert(isActive && "Parsing action was finished!");
       P.PP.Backtrack();
       P.Tok = PrevTok;
+      P.TentativelyDeclaredIdentifiers.resize(
+          PrevTentativelyDeclaredIdentifierCount);
       P.ParenCount = PrevParenCount;
       P.BracketCount = PrevBracketCount;
       P.BraceCount = PrevBraceCount;
@@ -1056,7 +1089,6 @@
                                           ParsingDeclSpec *DS = 0);
   bool isDeclarationAfterDeclarator();
   bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
-  bool isStartOfDelayParsedFunctionDefinition(const ParsingDeclarator &Declarator);
   DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
                                                   ParsedAttributesWithRange &attrs,
                                                   ParsingDeclSpec *DS = 0,
@@ -1559,7 +1591,7 @@
                             Decl *TagDecl);
 
   struct FieldCallback {
-    virtual Decl *invoke(FieldDeclarator &Field) = 0;
+    virtual void invoke(ParsingFieldDeclarator &Field) = 0;
     virtual ~FieldCallback() {}
 
   private:
@@ -1567,7 +1599,7 @@
   };
   struct ObjCPropertyCallback;
 
-  void ParseStructDeclaration(DeclSpec &DS, FieldCallback &Callback);
+  void ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Callback);
 
   bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false);
   bool isTypeSpecifierQualifier();
@@ -1643,11 +1675,11 @@
   /// isCXXFunctionDeclarator - Disambiguates between a function declarator or
   /// a constructor-style initializer, when parsing declaration statements.
   /// Returns true for function declarator and false for constructor-style
-  /// initializer. If 'warnIfAmbiguous' is true a warning will be emitted to
-  /// indicate that the parens were disambiguated as function declarator.
+  /// initializer. Sets 'IsAmbiguous' to true to indicate that this declaration 
+  /// might be a constructor-style initializer.
   /// If during the disambiguation process a parsing error is encountered,
   /// the function returns true to let the declaration parsing code handle it.
-  bool isCXXFunctionDeclarator(bool warnIfAmbiguous);
+  bool isCXXFunctionDeclarator(bool *IsAmbiguous = 0);
 
   /// isCXXConditionDeclaration - Disambiguates between a declaration or an
   /// expression for a condition of a if/switch/while/for statement.
@@ -1707,6 +1739,11 @@
   isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(),
                             bool *HasMissingTypename = 0);
 
+  /// \brief Determine whether an identifier has been tentatively declared as a
+  /// non-type. Such tentative declarations should not be found to name a type
+  /// during a tentative parse, but also should not be annotated as a non-type.
+  bool isTentativelyDeclared(IdentifierInfo *II);
+
   // "Tentative parsing" functions, used for disambiguation. If a parsing error
   // is encountered they will return TPResult::Error().
   // Returning TPResult::True()/False() indicates that the ambiguity was
@@ -1834,6 +1871,10 @@
                                   ParsedAttributes &Attrs,
                                   SourceLocation *EndLoc);
 
+  void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
+                                        SourceLocation AttrNameLoc,
+                                        ParsedAttributes &Attrs,
+                                        SourceLocation *EndLoc);
 
   void ParseTypeofSpecifier(DeclSpec &DS);
   SourceLocation ParseDecltypeSpecifier(DeclSpec &DS);
@@ -1903,6 +1944,7 @@
   void ParseFunctionDeclarator(Declarator &D,
                                ParsedAttributes &attrs,
                                BalancedDelimiterTracker &Tracker,
+                               bool IsAmbiguous,
                                bool RequiresArg = false);
   bool isFunctionDeclaratorIdentifierList();
   void ParseFunctionDeclaratorIdentifierList(
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index 5239044..bf35886 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/VersionTuple.h"
+#include "clang/Sema/Ownership.h"
 #include <cassert>
 
 namespace clang {
@@ -87,6 +88,10 @@
   /// availability attribute.
   unsigned IsAvailability : 1;
 
+  /// True if this has extra information associated with a
+  /// type_tag_for_datatype attribute.
+  unsigned IsTypeTagForDatatype : 1;
+
   unsigned AttrKind : 8;
 
   /// \brief The location of the 'unavailable' keyword in an
@@ -119,6 +124,22 @@
     return reinterpret_cast<const AvailabilityChange*>(this+1)[index];
   }
 
+public:
+  struct TypeTagForDatatypeData {
+    ParsedType *MatchingCType;
+    unsigned LayoutCompatible : 1;
+    unsigned MustBeNull : 1;
+  };
+
+private:
+  TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
+    return *reinterpret_cast<TypeTagForDatatypeData *>(this + 1);
+  }
+
+  const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
+    return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1);
+  }
+
   AttributeList(const AttributeList &); // DO NOT IMPLEMENT
   void operator=(const AttributeList &); // DO NOT IMPLEMENT
   void operator delete(void *); // DO NOT IMPLEMENT
@@ -126,6 +147,7 @@
 
   size_t allocated_size() const;
 
+  /// Constructor for attributes with expression arguments.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
                 IdentifierInfo *parmName, SourceLocation parmLoc,
@@ -134,12 +156,13 @@
     : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
       AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
       NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false),
-      UsedAsTypeAttr(false), IsAvailability(false), 
-      NextInPosition(0), NextInPool(0) {
+      UsedAsTypeAttr(false), IsAvailability(false),
+      IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) {
     if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
+  /// Constructor for availability attributes.
   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
                 IdentifierInfo *parmName, SourceLocation parmLoc,
@@ -153,6 +176,7 @@
       AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
       NumArgs(0), SyntaxUsed(syntaxUsed),
       Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
+      IsTypeTagForDatatype(false),
       UnavailableLoc(unavailable), MessageExpr(messageExpr),
       NextInPosition(0), NextInPool(0) {
     new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
@@ -161,6 +185,25 @@
     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
   }
 
+  /// Constructor for type_tag_for_datatype attribute.
+  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
+                IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                IdentifierInfo *argumentKindName,
+                SourceLocation argumentKindLoc,
+                ParsedType matchingCType, bool layoutCompatible,
+                bool mustBeNull, Syntax syntaxUsed)
+    : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName),
+      AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc),
+      NumArgs(0), SyntaxUsed(syntaxUsed),
+      Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
+      IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) {
+    TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
+    new (&ExtraData.MatchingCType) ParsedType(matchingCType);
+    ExtraData.LayoutCompatible = layoutCompatible;
+    ExtraData.MustBeNull = mustBeNull;
+    AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
+  }
+
   friend class AttributePool;
   friend class AttributeFactory;
 
@@ -279,6 +322,24 @@
     assert(getKind() == AT_Availability && "Not an availability attribute");
     return MessageExpr;
   }
+
+  const ParsedType &getMatchingCType() const {
+    assert(getKind() == AT_TypeTagForDatatype &&
+           "Not a type_tag_for_datatype attribute");
+    return *getTypeTagForDatatypeDataSlot().MatchingCType;
+  }
+
+  bool getLayoutCompatible() const {
+    assert(getKind() == AT_TypeTagForDatatype &&
+           "Not a type_tag_for_datatype attribute");
+    return getTypeTagForDatatypeDataSlot().LayoutCompatible;
+  }
+
+  bool getMustBeNull() const {
+    assert(getKind() == AT_TypeTagForDatatype &&
+           "Not a type_tag_for_datatype attribute");
+    return getTypeTagForDatatypeDataSlot().MustBeNull;
+  }
 };
 
 /// A factory, from which one makes pools, from which one creates
@@ -294,7 +355,11 @@
     AvailabilityAllocSize =
       sizeof(AttributeList)
       + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1)
-         / sizeof(void*) * sizeof(void*))
+         / sizeof(void*) * sizeof(void*)),
+    TypeTagForDatatypeAllocSize =
+      sizeof(AttributeList)
+      + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1)
+        / sizeof(void*) * sizeof(void*)
   };
 
 private:
@@ -411,6 +476,21 @@
 
   AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
                                         SourceLocation TokLoc, int Arg);
+
+  AttributeList *createTypeTagForDatatype(
+                    IdentifierInfo *attrName, SourceRange attrRange,
+                    IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                    IdentifierInfo *argumentKindName,
+                    SourceLocation argumentKindLoc,
+                    ParsedType matchingCType, bool layoutCompatible,
+                    bool mustBeNull, AttributeList::Syntax syntax) {
+    void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
+    return add(new (memory) AttributeList(attrName, attrRange,
+                                          scopeName, scopeLoc,
+                                          argumentKindName, argumentKindLoc,
+                                          matchingCType, layoutCompatible,
+                                          mustBeNull, syntax));
+  }
 };
 
 /// addAttributeLists - Add two AttributeLists together
@@ -503,7 +583,7 @@
   /// dependencies on this method, it may not be long-lived.
   AttributeList *&getListRef() { return list; }
 
-
+  /// Add attribute with expression arguments.
   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
                         IdentifierInfo *parmName, SourceLocation parmLoc,
@@ -516,6 +596,7 @@
     return attr;
   }
 
+  /// Add availability attribute.
   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
                         IdentifierInfo *parmName, SourceLocation parmLoc,
@@ -533,6 +614,24 @@
     return attr;
   }
 
+  /// Add type_tag_for_datatype attribute.
+  AttributeList *addNewTypeTagForDatatype(
+                        IdentifierInfo *attrName, SourceRange attrRange,
+                        IdentifierInfo *scopeName, SourceLocation scopeLoc,
+                        IdentifierInfo *argumentKindName,
+                        SourceLocation argumentKindLoc,
+                        ParsedType matchingCType, bool layoutCompatible,
+                        bool mustBeNull, AttributeList::Syntax syntax) {
+    AttributeList *attr =
+      pool.createTypeTagForDatatype(attrName, attrRange,
+                                    scopeName, scopeLoc,
+                                    argumentKindName, argumentKindLoc,
+                                    matchingCType, layoutCompatible,
+                                    mustBeNull, syntax);
+    add(attr);
+    return attr;
+  }
+
   AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
                                SourceLocation loc, int arg) {
     AttributeList *attr =
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 0f323bd..792b0c6 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -598,7 +598,8 @@
   }
 
   bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
-                   unsigned &DiagID, const LangOptions &Lang);
+                   unsigned &DiagID, const LangOptions &Lang,
+                   bool IsTypeSpec);
 
   bool SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
                              unsigned &DiagID);
@@ -1103,6 +1104,9 @@
     /// contains the location of the ellipsis.
     unsigned isVariadic : 1;
 
+    /// Can this declaration be a constructor-style initializer?
+    unsigned isAmbiguous : 1;
+
     /// \brief Whether the ref-qualifier (if any) is an lvalue reference.
     /// Otherwise, it's an rvalue reference.
     unsigned RefQualifierIsLValueRef : 1;
@@ -1151,8 +1155,7 @@
     /// any.
     unsigned MutableLoc;
 
-    /// \brief When ExceptionSpecType isn't EST_None or EST_Delayed, the
-    /// location of the keyword introducing the spec.
+    /// \brief The location of the keyword introducing the spec, if any.
     unsigned ExceptionSpecLoc;
 
     /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
@@ -1356,6 +1359,7 @@
   /// 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,
+                                     bool isAmbiguous,
                                      SourceLocation EllipsisLoc,
                                      ParamInfo *ArgInfo, unsigned NumArgs,
                                      unsigned TypeQuals, 
@@ -1928,9 +1932,8 @@
 struct FieldDeclarator {
   Declarator D;
   Expr *BitfieldSize;
-  explicit FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) {
-    BitfieldSize = 0;
-  }
+  explicit FieldDeclarator(const DeclSpec &DS)
+    : D(DS, Declarator::MemberContext), BitfieldSize(0) { }
 };
 
 /// \brief Represents a C++11 virt-specifier-seq.
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 97c76a5..b4752f5 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -84,6 +84,14 @@
   /// \brief Whether this function contains any indirect gotos.
   bool HasIndirectGoto;
 
+  /// A flag that is set when parsing a -dealloc method and no [super dealloc]
+  /// call was found yet.
+  bool ObjCShouldCallSuperDealloc;
+
+  /// A flag that is set when parsing a -finalize method and no [super finalize]
+  /// call was found yet.
+  bool ObjCShouldCallSuperFinalize;
+
   /// \brief Used to determine if errors occurred in this function or block.
   DiagnosticErrorTrap ErrorTrap;
 
@@ -127,6 +135,8 @@
       HasBranchProtectedScope(false),
       HasBranchIntoScope(false),
       HasIndirectGoto(false),
+      ObjCShouldCallSuperDealloc(false),
+      ObjCShouldCallSuperFinalize(false),
       ErrorTrap(Diag) { }
 
   virtual ~FunctionScopeInfo();
@@ -344,6 +354,9 @@
   /// \brief Whether any of the capture expressions requires cleanups.
   bool ExprNeedsCleanups;
 
+  /// \brief Whether the lambda contains an unexpanded parameter pack.
+  bool ContainsUnexpandedParameterPack;
+
   /// \brief Variables used to index into by-copy array captures.
   llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
 
@@ -355,7 +368,7 @@
                   CXXMethodDecl *CallOperator)
     : CapturingScopeInfo(Diag, ImpCap_None), Lambda(Lambda),
       CallOperator(CallOperator), NumExplicitCaptures(0), Mutable(false),
-      ExprNeedsCleanups(false)
+      ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false)
   {
     Kind = SK_Lambda;
   }
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index a3be78c..4e2a971 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -267,7 +267,7 @@
   ///
   /// This set is used to suppress redundant diagnostics.
   llvm::SmallPtrSet<NamedDecl *, 4> HiddenDefinitions;
-  
+
   /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
   OwningPtr<CXXFieldCollector> FieldCollector;
 
@@ -382,7 +382,7 @@
   public:
     DelayedDiagnostics() : CurPool(0) {}
 
-    /// Adds a delayed diagnostic.    
+    /// Adds a delayed diagnostic.
     void add(const sema::DelayedDiagnostic &diag); // in DelayedDiagnostic.h
 
     /// Determines whether diagnostics should be delayed.
@@ -432,7 +432,7 @@
     DeclContext *SavedContext;
     ProcessingContextState SavedContextState;
     QualType SavedCXXThisTypeOverride;
-    
+
   public:
     ContextRAII(Sema &S, DeclContext *ContextToPush)
       : S(S), SavedContext(S.CurContext),
@@ -507,19 +507,19 @@
 
   /// \brief The declaration of the Objective-C NSNumber class.
   ObjCInterfaceDecl *NSNumberDecl;
-  
+
   /// \brief Pointer to NSNumber type (NSNumber *).
   QualType NSNumberPointer;
-  
+
   /// \brief The Objective-C NSNumber methods used to create NSNumber literals.
   ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
-  
+
   /// \brief The declaration of the Objective-C NSString class.
   ObjCInterfaceDecl *NSStringDecl;
 
   /// \brief Pointer to NSString type (NSString *).
   QualType NSStringPointer;
-  
+
   /// \brief The declaration of the stringWithUTF8String: method.
   ObjCMethodDecl *StringWithUTF8StringMethod;
 
@@ -528,7 +528,7 @@
 
   /// \brief The declaration of the arrayWithObjects:count: method.
   ObjCMethodDecl *ArrayWithObjectsMethod;
-  
+
   /// \brief The declaration of the Objective-C NSDictionary class.
   ObjCInterfaceDecl *NSDictionaryDecl;
 
@@ -542,13 +542,6 @@
   /// have been declared.
   bool GlobalNewDeleteDeclared;
 
-  /// A flag that is set when parsing a -dealloc method and no [super dealloc]
-  /// call was found yet.
-  bool ObjCShouldCallSuperDealloc;
-  /// A flag that is set when parsing a -finalize method and no [super finalize]
-  /// call was found yet.
-  bool ObjCShouldCallSuperFinalize;
-
   /// \brief Describes how the expressions currently being parsed are
   /// evaluated at run-time, if at all.
   enum ExpressionEvaluationContext {
@@ -603,10 +596,10 @@
     llvm::SmallVector<LambdaExpr *, 2> Lambdas;
 
     /// \brief The declaration that provides context for the lambda expression
-    /// if the normal declaration context does not suffice, e.g., in a 
+    /// if the normal declaration context does not suffice, e.g., in a
     /// default function argument.
     Decl *LambdaContextDecl;
-    
+
     /// \brief The context information used to mangle lambda expressions
     /// within this context.
     ///
@@ -621,7 +614,7 @@
     /// \brief If we are processing a decltype type, a set of temporary binding
     /// expressions for which we have deferred checking the destructor.
     llvm::SmallVector<CXXBindTemporaryExpr*, 8> DelayedDecltypeBinds;
-    
+
     ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
                                       unsigned NumCleanupObjects,
                                       bool ParentNeedsCleanups,
@@ -630,11 +623,11 @@
       : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups),
         IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects),
         LambdaContextDecl(LambdaContextDecl), LambdaMangle() { }
-    
+
     ~ExpressionEvaluationContextRecord() {
       delete LambdaMangle;
     }
-    
+
     /// \brief Retrieve the mangling context for lambdas.
     LambdaMangleContext &getLambdaMangleContext() {
       assert(LambdaContextDecl && "Need to have a lambda context declaration");
@@ -646,7 +639,7 @@
 
   /// A stack of expression evaluation contexts.
   SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
-  
+
   /// SpecialMemberOverloadResult - The overloading result for a special member
   /// function.
   ///
@@ -889,7 +882,7 @@
   TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
   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);
@@ -929,9 +922,9 @@
   /// \brief Abstract class used to diagnose incomplete types.
   struct TypeDiagnoser {
     bool Suppressed;
-    
+
     TypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { }
-    
+
     virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0;
     virtual ~TypeDiagnoser() {}
   };
@@ -951,12 +944,12 @@
   static SourceRange getPrintable(SourceLocation L) { return L; }
   static SourceRange getPrintable(Expr *E) { return E->getSourceRange(); }
   static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();}
-  
+
   template<typename T1>
   class BoundTypeDiagnoser1 : public TypeDiagnoser {
     unsigned DiagID;
     const T1 &Arg1;
-    
+
   public:
     BoundTypeDiagnoser1(unsigned DiagID, const T1 &Arg1)
       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { }
@@ -964,7 +957,7 @@
       if (Suppressed) return;
       S.Diag(Loc, DiagID) << getPrintable(Arg1) << T;
     }
-    
+
     virtual ~BoundTypeDiagnoser1() { }
   };
 
@@ -973,18 +966,18 @@
     unsigned DiagID;
     const T1 &Arg1;
     const T2 &Arg2;
-    
+
   public:
     BoundTypeDiagnoser2(unsigned DiagID, const T1 &Arg1,
                                   const T2 &Arg2)
       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
         Arg2(Arg2) { }
-    
+
     virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
       if (Suppressed) return;
       S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T;
     }
-    
+
     virtual ~BoundTypeDiagnoser2() { }
   };
 
@@ -994,34 +987,34 @@
     const T1 &Arg1;
     const T2 &Arg2;
     const T3 &Arg3;
-    
+
   public:
     BoundTypeDiagnoser3(unsigned DiagID, const T1 &Arg1,
                                   const T2 &Arg2, const T3 &Arg3)
     : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1),
       Arg2(Arg2), Arg3(Arg3) { }
-    
+
     virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
       if (Suppressed) return;
       S.Diag(Loc, DiagID)
         << getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T;
     }
-    
+
     virtual ~BoundTypeDiagnoser3() { }
   };
-  
+
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            TypeDiagnoser &Diagnoser);
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            unsigned DiagID);
-  
+
   template<typename T1>
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            unsigned DiagID, const T1 &Arg1) {
     BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1);
     return RequireCompleteType(Loc, T, Diagnoser);
   }
-  
+
   template<typename T1, typename T2>
   bool RequireCompleteType(SourceLocation Loc, QualType T,
                            unsigned DiagID, const T1 &Arg1, const T2 &Arg2) {
@@ -1065,7 +1058,7 @@
   bool RequireLiteralType(SourceLocation Loc, QualType T,
                           TypeDiagnoser &Diagnoser);
   bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID);
-  
+
   template<typename T1>
   bool RequireLiteralType(SourceLocation Loc, QualType T,
                           unsigned DiagID, const T1 &Arg1) {
@@ -1210,7 +1203,7 @@
       assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate);
       return Kind == NC_TypeTemplate? TNK_Type_template : TNK_Function_template;
     }
-};
+  };
 
   /// \brief Perform name lookup on the given name, classifying it based on
   /// the results of name lookup and the following token.
@@ -1230,11 +1223,19 @@
   ///
   /// \param NextToken The token following the identifier. Used to help
   /// disambiguate the name.
+  ///
+  /// \param IsAddressOfOperand True if this name is the operand of a unary
+  ///        address of ('&') expression, assuming it is classified as an
+  ///        expression.
+  ///
+  /// \param CCC The correction callback, if typo correction is desired.
   NameClassification ClassifyName(Scope *S,
                                   CXXScopeSpec &SS,
                                   IdentifierInfo *&Name,
                                   SourceLocation NameLoc,
-                                  const Token &NextToken);
+                                  const Token &NextToken,
+                                  bool IsAddressOfOperand,
+                                  CorrectionCandidateCallback *CCC = 0);
 
   Decl *ActOnDeclarator(Scope *S, Declarator &D);
 
@@ -1325,8 +1326,7 @@
   void CheckForFunctionRedefinition(FunctionDecl *FD);
   Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
   Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
-  void ActOnStartOfObjCMethodOrCFunctionDef(Scope *S, Decl *D, 
-                                            bool parseMethod);
+  void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
   bool isObjCMethodDecl(Decl *D) {
     return D && isa<ObjCMethodDecl>(D);
   }
@@ -1364,7 +1364,7 @@
   /// \param ImportLoc The location of the 'import' keyword.
   ///
   /// \param Path The module access path.
-  DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, 
+  DeclResult ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc,
                                ModuleIdPath Path);
 
   /// \brief Retrieve a suitable printing policy.
@@ -1735,20 +1735,20 @@
   public:
     bool Suppress;
     bool SuppressConversion;
-    
+
     ICEConvertDiagnoser(bool Suppress = false,
                         bool SuppressConversion = false)
       : Suppress(Suppress), SuppressConversion(SuppressConversion) { }
-    
+
     /// \brief Emits a diagnostic complaining that the expression does not have
     /// integral or enumeration type.
     virtual DiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
                                              QualType T) = 0;
-    
+
     /// \brief Emits a diagnostic when the expression has incomplete class type.
     virtual DiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
                                                  QualType T) = 0;
-    
+
     /// \brief Emits a diagnostic when the only matching conversion function
     /// is explicit.
     virtual DiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
@@ -1773,7 +1773,7 @@
     virtual DiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc,
                                                  QualType T,
                                                  QualType ConvTy) = 0;
-    
+
     virtual ~ICEConvertDiagnoser() {}
   };
 
@@ -1924,6 +1924,30 @@
                                    OverloadCandidateSet &CandidateSet,
                                    bool PartialOverloading = false);
 
+  // An enum used to represent the different possible results of building a
+  // range-based for loop.
+  enum ForRangeStatus {
+    FRS_Success,
+    FRS_NoViableFunction,
+    FRS_DiagnosticIssued
+  };
+
+  // An enum to represent whether something is dealing with a call to begin()
+  // or a call to end() in a range-based for loop.
+  enum BeginEndFunction {
+    BEF_begin,
+    BEF_end
+  };
+
+  ForRangeStatus BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc,
+                                           SourceLocation RangeLoc,
+                                           VarDecl *Decl,
+                                           BeginEndFunction BEF,
+                                           const DeclarationNameInfo &NameInfo,
+                                           LookupResult &MemberLookup,
+                                           OverloadCandidateSet *CandidateSet,
+                                           Expr *Range, ExprResult *CallExpr);
+
   ExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
                                      UnresolvedLookupExpr *ULE,
                                      SourceLocation LParenLoc,
@@ -1932,6 +1956,12 @@
                                      Expr *ExecConfig,
                                      bool AllowTypoCorrection=true);
 
+  bool buildOverloadedCallSet(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
+                              Expr **Args, unsigned NumArgs,
+                              SourceLocation RParenLoc,
+                              OverloadCandidateSet *CandidateSet,
+                              ExprResult *Result);
+
   ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
                                      unsigned Opc,
                                      const UnresolvedSetImpl &Fns,
@@ -2337,7 +2367,7 @@
 
   /// \brief Add the given method to the list of globally-known methods.
   void addMethodToGlobalList(ObjCMethodList *List, ObjCMethodDecl *Method);
-  
+
 private:
   /// AddMethodToGlobalPool - Add an instance or factory method to the global
   /// pool. See descriptoin of AddInstanceMethodToGlobalPool.
@@ -2506,21 +2536,21 @@
   ExprResult CheckObjCForCollectionOperand(SourceLocation forLoc,
                                            Expr *collection);
   StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
-                                        SourceLocation LParenLoc,
                                         Stmt *First, Expr *collection,
                                         SourceLocation RParenLoc);
   StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body);
-  
-  StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc,
-                                  SourceLocation LParenLoc, Stmt *LoopVar,
+
+  StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, Stmt *LoopVar,
                                   SourceLocation ColonLoc, Expr *Collection,
-                                  SourceLocation RParenLoc);
+                                  SourceLocation RParenLoc,
+                                  bool ShouldTryDeref);
   StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc,
                                   SourceLocation ColonLoc,
                                   Stmt *RangeDecl, Stmt *BeginEndDecl,
                                   Expr *Cond, Expr *Inc,
                                   Stmt *LoopVarDecl,
-                                  SourceLocation RParenLoc);
+                                  SourceLocation RParenLoc,
+                                  bool ShouldTryDeref);
   StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body);
 
   StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
@@ -2546,11 +2576,11 @@
                           MultiExprArg Exprs,
                           Expr *AsmString,
                           MultiExprArg Clobbers,
-                          SourceLocation RParenLoc,
-                          bool MSAsm = false);
+                          SourceLocation RParenLoc);
 
   StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc,
-                            std::string &AsmString,
+                            SourceLocation LBraceLoc,
+                            ArrayRef<Token> AsmToks,
                             SourceLocation EndLoc);
 
   VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
@@ -2707,13 +2737,13 @@
   ///
   /// \param Loc The location at which the capture occurs.
   ///
-  /// \param Kind The kind of capture, which may be implicit (for either a 
+  /// \param Kind The kind of capture, which may be implicit (for either a
   /// block or a lambda), or explicit by-value or by-reference (for a lambda).
   ///
   /// \param EllipsisLoc The location of the ellipsis, if one is provided in
   /// an explicit lambda capture.
   ///
-  /// \param BuildAndDiagnose Whether we are actually supposed to add the 
+  /// \param BuildAndDiagnose Whether we are actually supposed to add the
   /// captures or diagnose errors. If false, this routine merely check whether
   /// the capture can occur without performing the capture itself or complaining
   /// if the variable cannot be captured.
@@ -2723,13 +2753,13 @@
   /// variable can be captured.
   ///
   /// \param DeclRefType Will be set to the type of a reference to the capture
-  /// from within the current scope. Only valid when the variable can be 
+  /// from within the current scope. Only valid when the variable can be
   /// captured.
   ///
   /// \returns true if an error occurred (i.e., the variable cannot be
   /// captured) and false if the capture succeeded.
   bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc, TryCaptureKind Kind,
-                          SourceLocation EllipsisLoc, bool BuildAndDiagnose, 
+                          SourceLocation EllipsisLoc, bool BuildAndDiagnose,
                           QualType &CaptureType,
                           QualType &DeclRefType);
 
@@ -2737,13 +2767,13 @@
   bool tryCaptureVariable(VarDecl *Var, SourceLocation Loc,
                           TryCaptureKind Kind = TryCapture_Implicit,
                           SourceLocation EllipsisLoc = SourceLocation());
-  
+
   /// \brief Given a variable, determine the type that a reference to that
   /// variable will have in the given scope.
   QualType getCapturedDeclRefType(VarDecl *Var, SourceLocation Loc);
-  
+
   void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
-  void MarkDeclarationsReferencedInExpr(Expr *E, 
+  void MarkDeclarationsReferencedInExpr(Expr *E,
                                         bool SkipLocalVariables = false);
 
   /// \brief Try to recover by turning the given expression into a
@@ -3335,17 +3365,6 @@
     /// \brief Integrate an invoked expression into the collected data.
     void CalledExpr(Expr *E);
 
-    /// \brief Specify that the exception specification can't be detemined yet.
-    void SetDelayed() {
-      ClearExceptions();
-      ComputedEST = EST_Delayed;
-    }
-
-    /// \brief Have we been unable to compute this exception specification?
-    bool isDelayed() {
-      return ComputedEST == EST_Delayed;
-    }
-
     /// \brief Overwrite an EPI's exception specification with this
     /// computed exception specification.
     void getEPI(FunctionProtoType::ExtProtoInfo &EPI) const {
@@ -3363,34 +3382,39 @@
   /// \brief Determine what sort of exception specification a defaulted
   /// copy constructor of a class will have.
   ImplicitExceptionSpecification
-  ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl);
+  ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
+                                           CXXMethodDecl *MD);
 
   /// \brief Determine what sort of exception specification a defaulted
   /// default constructor of a class will have, and whether the parameter
   /// will be const.
-  std::pair<ImplicitExceptionSpecification, bool>
-  ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl);
+  ImplicitExceptionSpecification
+  ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD);
 
   /// \brief Determine what sort of exception specification a defautled
   /// copy assignment operator of a class will have, and whether the
   /// parameter will be const.
-  std::pair<ImplicitExceptionSpecification, bool>
-  ComputeDefaultedCopyAssignmentExceptionSpecAndConst(CXXRecordDecl *ClassDecl);
+  ImplicitExceptionSpecification
+  ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD);
 
   /// \brief Determine what sort of exception specification a defaulted move
   /// constructor of a class will have.
   ImplicitExceptionSpecification
-  ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl);
+  ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD);
 
   /// \brief Determine what sort of exception specification a defaulted move
   /// assignment operator of a class will have.
   ImplicitExceptionSpecification
-  ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl);
+  ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD);
 
   /// \brief Determine what sort of exception specification a defaulted
   /// destructor of a class will have.
   ImplicitExceptionSpecification
-  ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl);
+  ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD);
+
+  /// \brief Evaluate the implicit exception specification for a defaulted
+  /// special member function.
+  void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD);
 
   /// \brief Check the given exception-specification and update the
   /// extended prototype information with the results.
@@ -3438,8 +3462,7 @@
   /// C++11 says that user-defined destructors with no exception spec get one
   /// that looks as if the destructor was implicitly declared.
   void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
-                                     CXXDestructorDecl *Destructor,
-                                     bool WasDelayed = false);
+                                     CXXDestructorDecl *Destructor);
 
   /// \brief Declare all inherited constructors for the given class.
   ///
@@ -3506,7 +3529,7 @@
   /// \brief Determine whether the given function is an implicitly-deleted
   /// special member function.
   bool isImplicitlyDeleted(FunctionDecl *FD);
-  
+
   /// \brief Check whether 'this' shows up in the type of a static member
   /// function after the (naturally empty) cv-qualifier-seq would be.
   ///
@@ -3522,7 +3545,7 @@
   ///
   /// \returns true if an error occurred.
   bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method);
-  
+
   /// 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.
@@ -3602,29 +3625,29 @@
   /// \returns The type of 'this', if possible. Otherwise, returns a NULL type.
   QualType getCurrentThisType();
 
-  /// \brief When non-NULL, the C++ 'this' expression is allowed despite the 
+  /// \brief When non-NULL, the C++ 'this' expression is allowed despite the
   /// current context not being a non-static member function. In such cases,
   /// this provides the type used for 'this'.
   QualType CXXThisTypeOverride;
-  
+
   /// \brief RAII object used to temporarily allow the C++ 'this' expression
   /// to be used, with the given qualifiers on the current class type.
   class CXXThisScopeRAII {
     Sema &S;
     QualType OldCXXThisTypeOverride;
     bool Enabled;
-    
+
   public:
     /// \brief Introduce a new scope where 'this' may be allowed (when enabled),
-    /// using the given declaration (which is either a class template or a 
+    /// using the given declaration (which is either a class template or a
     /// class) along with the given qualifiers.
     /// along with the qualifiers placed on '*this'.
-    CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals, 
+    CXXThisScopeRAII(Sema &S, Decl *ContextDecl, unsigned CXXThisTypeQuals,
                      bool Enabled = true);
-    
+
     ~CXXThisScopeRAII();
   };
-  
+
   /// \brief Make sure the value of 'this' is actually available in the current
   /// context, if it is a potentially evaluated context.
   ///
@@ -3635,14 +3658,14 @@
   void CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false);
 
   /// \brief Determine whether the given type is the type of *this that is used
-  /// outside of the body of a member function for a type that is currently 
+  /// outside of the body of a member function for a type that is currently
   /// being defined.
   bool isThisOutsideMemberFunctionBody(QualType BaseType);
-  
+
   /// ActOnCXXBoolLiteral - Parse {true,false} literals.
   ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
-  
-  
+
+
   /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals.
   ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind);
 
@@ -3758,7 +3781,7 @@
   ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
                             ArrayRef<TypeSourceInfo *> Args,
                             SourceLocation RParenLoc);
-  
+
   /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support
   /// pseudo-functions.
   ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT,
@@ -3817,7 +3840,7 @@
   ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
                                        SourceLocation OpLoc,
                                        tok::TokenKind OpKind,
-                                       SourceLocation TildeLoc, 
+                                       SourceLocation TildeLoc,
                                        const DeclSpec& DS,
                                        bool HasTrailingLParen);
 
@@ -3909,7 +3932,7 @@
   ExprResult ActOnDecltypeExpression(Expr *E);
 
   bool ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS,
-                                           const DeclSpec &DS, 
+                                           const DeclSpec &DS,
                                            SourceLocation ColonColonLoc);
 
   bool IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
@@ -4008,14 +4031,14 @@
   /// \brief Create a new lambda closure type.
   CXXRecordDecl *createLambdaClosureType(SourceRange IntroducerRange,
                                          bool KnownDependent = false);
-  
+
   /// \brief Start the definition of a lambda expression.
   CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
                                        SourceRange IntroducerRange,
                                        TypeSourceInfo *MethodType,
                                        SourceLocation EndLoc,
                                        llvm::ArrayRef<ParmVarDecl *> Params);
-  
+
   /// \brief Introduce the scope for a lambda expression.
   sema::LambdaScopeInfo *enterLambdaScope(CXXMethodDecl *CallOperator,
                                           SourceRange IntroducerRange,
@@ -4023,20 +4046,20 @@
                                           bool ExplicitParams,
                                           bool ExplicitResultType,
                                           bool Mutable);
-  
+
   /// \brief Note that we have finished the explicit captures for the
   /// given lambda.
   void finishLambdaExplicitCaptures(sema::LambdaScopeInfo *LSI);
-  
+
   /// \brief Introduce the lambda parameters into scope.
   void addLambdaParameters(CXXMethodDecl *CallOperator, Scope *CurScope);
 
   /// \brief Deduce a block or lambda's return type based on the return
   /// statements present in the body.
   void deduceClosureReturnType(sema::CapturingScopeInfo &CSI);
-  
+
   /// ActOnStartOfLambdaDefinition - This is called just before we start
-  /// parsing the body of a lambda; it analyzes the explicit captures and 
+  /// parsing the body of a lambda; it analyzes the explicit captures and
   /// arguments, and sets up various data-structures for the body of the
   /// lambda.
   void ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
@@ -4050,10 +4073,10 @@
   /// ActOnLambdaExpr - This is called when the body of a lambda expression
   /// was successfully completed.
   ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body,
-                             Scope *CurScope, 
+                             Scope *CurScope,
                              bool IsInstantiation = false);
 
-  /// \brief Define the "body" of the conversion from a lambda object to a 
+  /// \brief Define the "body" of the conversion from a lambda object to a
   /// function pointer.
   ///
   /// This routine doesn't actually define a sensible body; rather, it fills
@@ -4063,7 +4086,7 @@
   void DefineImplicitLambdaToFunctionPointerConversion(
          SourceLocation CurrentLoc, CXXConversionDecl *Conv);
 
-  /// \brief Define the "body" of the conversion from a lambda object to a 
+  /// \brief Define the "body" of the conversion from a lambda object to a
   /// block pointer.
   ///
   /// This routine doesn't actually define a sensible body; rather, it fills
@@ -4082,9 +4105,9 @@
   ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
                                     Expr **Strings,
                                     unsigned NumStrings);
-    
+
   ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S);
-  
+
   /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
   /// numeric literal expression. Type of the expression will be "NSNumber *"
   /// or "id" if NSNumber is unavailable.
@@ -4092,23 +4115,23 @@
   ExprResult ActOnObjCBoolLiteral(SourceLocation AtLoc, SourceLocation ValueLoc,
                                   bool Value);
   ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements);
-  
+
   /// BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the
   /// '@' prefixed parenthesized expression. The type of the expression will
   /// either be "NSNumber *" or "NSString *" depending on the type of
   /// ValueType, which is allowed to be a built-in numeric type or
   /// "char *" or "const char *".
   ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr);
-  
+
   ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
                                           Expr *IndexExpr,
                                           ObjCMethodDecl *getterMethod,
                                           ObjCMethodDecl *setterMethod);
-    
+
   ExprResult BuildObjCDictionaryLiteral(SourceRange SR,
                                         ObjCDictionaryElement *Elements,
                                         unsigned NumElements);
- 
+
   ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc,
                                   TypeSourceInfo *EncodedTypeInfo,
                                   SourceLocation RParenLoc);
@@ -4262,6 +4285,11 @@
   void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
                       bool DefinitionRequired = false);
 
+  /// \brief Mark the exception specifications of all virtual member functions
+  /// in the given class as needed.
+  void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc,
+                                             const CXXRecordDecl *RD);
+
   /// MarkVirtualMembersReferenced - Will mark all members of the given
   /// CXXRecordDecl referenced.
   void MarkVirtualMembersReferenced(SourceLocation Loc,
@@ -4388,12 +4416,12 @@
 
   bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
 
-  /// CheckOverrideControl - Check C++0x override control semantics.
-  void CheckOverrideControl(const Decl *D);
+  /// CheckOverrideControl - Check C++11 override control semantics.
+  void CheckOverrideControl(Decl *D);
 
   /// CheckForFunctionMarkedFinal - Checks whether a virtual member function
   /// overrides a virtual member function marked 'final', according to
-  /// C++0x [class.virtual]p3.
+  /// C++11 [class.virtual]p4.
   bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New,
                                               const CXXMethodDecl *Old);
 
@@ -4436,9 +4464,7 @@
                                      CXXDestructorDecl *Dtor,
                                      const PartialDiagnostic &PDiag,
                                      QualType objectType = QualType());
-  AccessResult CheckDirectMemberAccess(SourceLocation Loc,
-                                       NamedDecl *D,
-                                       const PartialDiagnostic &PDiag);
+  AccessResult CheckFriendAccess(NamedDecl *D);
   AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
                                          Expr *ObjectExpr,
                                          Expr *ArgExpr,
@@ -4474,6 +4500,7 @@
     AbstractParamType,
     AbstractVariableType,
     AbstractFieldType,
+    AbstractIvarType,
     AbstractArrayType
   };
 
@@ -4519,9 +4546,9 @@
   //===--------------------------------------------------------------------===//
   // C++ Templates [C++ 14]
   //
-  void FilterAcceptableTemplateNames(LookupResult &R, 
+  void FilterAcceptableTemplateNames(LookupResult &R,
                                      bool AllowFunctionTemplates = true);
-  bool hasAnyAcceptableTemplateNames(LookupResult &R, 
+  bool hasAnyAcceptableTemplateNames(LookupResult &R,
                                      bool AllowFunctionTemplates = true);
 
   void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
@@ -4987,10 +5014,10 @@
 
     /// \brief Microsoft __if_not_exists.
     UPPC_IfNotExists,
-    
+
     /// \brief Lambda expression.
     UPPC_Lambda,
-    
+
     /// \brief Block expression,
     UPPC_Block
 };
@@ -5003,7 +5030,9 @@
   /// parameter packs.
   ///
   /// \param Unexpanded the set of unexpanded parameter packs.
-  void DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
                                         UnexpandedParameterPackContext UPPC,
                                   ArrayRef<UnexpandedParameterPack> Unexpanded);
 
@@ -5709,6 +5738,14 @@
   /// diagnostics that will be suppressed.
   llvm::Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
 
+  /// \brief Determines whether we are currently in a context that
+  /// is not evaluated as per C++ [expr] p5.
+  bool isUnevaluatedContext() const {
+    assert(!ExprEvalContexts.empty() &&
+           "Must be in an expression evaluation context");
+    return ExprEvalContexts.back().Context == Sema::Unevaluated;
+  }
+
   /// \brief RAII class used to determine whether SFINAE has
   /// trapped any errors that occur during template argument
   /// deduction.`
@@ -5958,7 +5995,7 @@
                                  SourceLocation EndProtoLoc,
                                  AttributeList *AttrList);
 
-  Decl *ActOnCompatiblityAlias(
+  Decl *ActOnCompatibilityAlias(
                     SourceLocation AtCompatibilityAliasLoc,
                     IdentifierInfo *AliasName,  SourceLocation AliasLocation,
                     IdentifierInfo *ClassName, SourceLocation ClassLocation);
@@ -6107,14 +6144,6 @@
     AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
     bool isVariadic, bool MethodDefinition);
 
-  // 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);
   ObjCMethodDecl *LookupMethodInQualifiedType(Selector Sel,
                                               const ObjCObjectPointerType *OPT,
                                               bool IsInstance);
@@ -6306,7 +6335,7 @@
                          SourceLocation PragmaLoc,
                          SourceLocation WeakNameLoc);
 
-  /// ActOnPragmaRedefineExtname - Called on well formed 
+  /// ActOnPragmaRedefineExtname - Called on well formed
   /// \#pragma redefine_extname oldname newname.
   void ActOnPragmaRedefineExtname(IdentifierInfo* WeakName,
                                   IdentifierInfo* AliasName,
@@ -6357,9 +6386,9 @@
   void AddCFAuditedAttribute(Decl *D);
 
   /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
-  void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 
+  void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
                       bool isDeclSpec);
-  void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T, 
+  void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
                       bool isDeclSpec);
 
   /// \brief The kind of conversion being performed.
@@ -6548,7 +6577,7 @@
                                 QualType DstType, QualType SrcType,
                                 Expr *SrcExpr, AssignmentAction Action,
                                 bool *Complained = 0);
-  
+
   /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant
   /// integer not in the range of enum values.
   void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
@@ -6719,7 +6748,7 @@
   /// \brief Force an expression with unknown-type to an expression of the
   /// given type.
   ExprResult forceUnknownAnyToType(Expr *E, QualType ToType);
-                             
+
   // 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.
@@ -6830,14 +6859,14 @@
   class VerifyICEDiagnoser {
   public:
     bool Suppress;
-    
+
     VerifyICEDiagnoser(bool Suppress = false) : Suppress(Suppress) { }
-    
+
     virtual void diagnoseNotICE(Sema &S, SourceLocation Loc, SourceRange SR) =0;
     virtual void diagnoseFold(Sema &S, SourceLocation Loc, SourceRange SR);
     virtual ~VerifyICEDiagnoser() { }
   };
-    
+
   /// 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.
@@ -7051,7 +7080,7 @@
                            FormatStringInfo *FSI);
   bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
                          const FunctionProtoType *Proto);
-  bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, 
+  bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
                            Expr **Args, unsigned NumArgs);
   bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall,
                       const FunctionProtoType *Proto);
@@ -7155,6 +7184,42 @@
   void CheckBitFieldInitialization(SourceLocation InitLoc, FieldDecl *Field,
                                    Expr *Init);
 
+public:
+  /// \brief Register a magic integral constant to be used as a type tag.
+  void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
+                                  uint64_t MagicValue, QualType Type,
+                                  bool LayoutCompatible, bool MustBeNull);
+
+  struct TypeTagData {
+    TypeTagData() {}
+
+    TypeTagData(QualType Type, bool LayoutCompatible, bool MustBeNull) :
+        Type(Type), LayoutCompatible(LayoutCompatible),
+        MustBeNull(MustBeNull)
+    {}
+
+    QualType Type;
+
+    /// If true, \c Type should be compared with other expression's types for
+    /// layout-compatibility.
+    unsigned LayoutCompatible : 1;
+    unsigned MustBeNull : 1;
+  };
+
+  /// A pair of ArgumentKind identifier and magic value.  This uniquely
+  /// identifies the magic value.
+  typedef std::pair<const IdentifierInfo *, uint64_t> TypeTagMagicValue;
+
+private:
+  /// \brief A map from magic value to type information.
+  OwningPtr<llvm::DenseMap<TypeTagMagicValue, TypeTagData> >
+      TypeTagForDatatypeMagicValues;
+
+  /// \brief Peform checks on a call of a function with argument_with_type_tag
+  /// or pointer_with_type_tag attributes.
+  void CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
+                                const Expr * const *ExprArgs);
+
   /// \brief The parser's current scope.
   ///
   /// The parser maintains this state here.
diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h
index 87d71b8..273374d 100644
--- a/include/clang/Sema/Template.h
+++ b/include/clang/Sema/Template.h
@@ -372,8 +372,10 @@
   public:
     TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
                              const MultiLevelTemplateArgumentList &TemplateArgs)
-      : SemaRef(SemaRef), SubstIndex(SemaRef, -1), Owner(Owner), 
-        TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0) { }
+      : SemaRef(SemaRef),
+        SubstIndex(SemaRef, SemaRef.ArgumentPackSubstitutionIndex),
+        Owner(Owner), TemplateArgs(TemplateArgs), LateAttrs(0), StartingScope(0)
+    { }
 
     // FIXME: Once we get closer to completion, replace these manually-written
     // declarations with automatically-generated ones from
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 5ee52cc..48393a3 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -81,15 +81,19 @@
   typedef llvm::DenseSet<SymbolRef> Symbols;
   typedef llvm::DenseSet<const MemRegion *> Regions;
 
-  /// A set of symbols that are registered with this report as being
-  /// "interesting", and thus used to help decide which diagnostics
-  /// to include when constructing the final path diagnostic.
-  Symbols interestingSymbols;
+  /// A (stack of) a set of symbols that are registered with this
+  /// report as being "interesting", and thus used to help decide which
+  /// diagnostics to include when constructing the final path diagnostic.
+  /// The stack is largely used by BugReporter when generating PathDiagnostics
+  /// for multiple PathDiagnosticConsumers.
+  llvm::SmallVector<Symbols *, 2> interestingSymbols;
 
-  /// A set of regions that are registered with this report as being
+  /// A (stack of) set of regions that are registered with this report as being
   /// "interesting", and thus used to help decide which diagnostics
   /// to include when constructing the final path diagnostic.
-  Regions interestingRegions;
+  /// The stack is largely used by BugReporter when generating PathDiagnostics
+  /// for multiple PathDiagnosticConsumers.
+  llvm::SmallVector<Regions *, 2> interestingRegions;
 
   /// A set of custom visitors which generate "event" diagnostics at
   /// interesting points in the path.
@@ -107,6 +111,15 @@
   /// when reporting an issue.
   bool DoNotPrunePath;
 
+private:
+  // Used internally by BugReporter.
+  Symbols &getInterestingSymbols();
+  Regions &getInterestingRegions();
+
+  void lazyInitializeInterestingSets();
+  void pushInterestingSymbolsAndRegions();
+  void popInterestingSymbolsAndRegions();
+
 public:
   BugReport(BugType& bt, StringRef desc, const ExplodedNode *errornode)
     : BT(bt), DeclWithIssue(0), Description(desc), ErrorNode(errornode),
@@ -160,9 +173,9 @@
   void markInteresting(const MemRegion *R);
   void markInteresting(SVal V);
   
-  bool isInteresting(SymbolRef sym) const;
-  bool isInteresting(const MemRegion *R) const;
-  bool isInteresting(SVal V) const;
+  bool isInteresting(SymbolRef sym);
+  bool isInteresting(const MemRegion *R);
+  bool isInteresting(SVal V);
 
   unsigned getConfigurationChangeToken() const {
     return ConfigurationChangeToken;
@@ -295,7 +308,7 @@
 public:
   virtual ~BugReporterData();
   virtual DiagnosticsEngine& getDiagnostic() = 0;
-  virtual PathDiagnosticConsumer* getPathDiagnosticConsumer() = 0;
+  virtual ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() = 0;
   virtual ASTContext &getASTContext() = 0;
   virtual SourceManager& getSourceManager() = 0;
 };
@@ -318,6 +331,12 @@
   /// Generate and flush the diagnostics for the given bug report.
   void FlushReport(BugReportEquivClass& EQ);
 
+  /// Generate and flush the diagnostics for the given bug report
+  /// and PathDiagnosticConsumer.
+  void FlushReport(BugReport *exampleReport,
+                   PathDiagnosticConsumer &PD,
+                   ArrayRef<BugReport*> BugReports);
+
   /// The set of bug reports tracked by the BugReporter.
   llvm::FoldingSet<BugReportEquivClass> EQClasses;
   /// A vector of BugReports for tracking the allocated pointers and cleanup.
@@ -341,8 +360,8 @@
     return D.getDiagnostic();
   }
 
-  PathDiagnosticConsumer* getPathDiagnosticConsumer() {
-    return D.getPathDiagnosticConsumer();
+  ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() {
+    return D.getPathDiagnosticConsumers();
   }
 
   /// \brief Iterator over the set of BugTypes tracked by the BugReporter.
@@ -360,7 +379,8 @@
   SourceManager& getSourceManager() { return D.getSourceManager(); }
 
   virtual void GeneratePathDiagnostic(PathDiagnostic& pathDiagnostic,
-        SmallVectorImpl<BugReport *> &bugReports) {}
+                                      PathDiagnosticConsumer &PC,
+                                      ArrayRef<BugReport *> &bugReports) {}
 
   void Register(BugType *BT);
 
@@ -421,7 +441,8 @@
   ProgramStateManager &getStateManager();
 
   virtual void GeneratePathDiagnostic(PathDiagnostic &pathDiagnostic,
-                     SmallVectorImpl<BugReport*> &bugReports);
+                                      PathDiagnosticConsumer &PC,
+                                      ArrayRef<BugReport*> &bugReports);
 
   /// classof - Used by isa<>, cast<>, and dyn_cast<>.
   static bool classof(const BugReporter* R) {
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
index 7e665ce..f53c15f 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
@@ -226,13 +226,11 @@
   
 namespace bugreporter {
 
-BugReporterVisitor *getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
-                                                    const Stmt *S,
-                                                    BugReport *R);
+void addTrackNullOrUndefValueVisitor(const ExplodedNode *N, const Stmt *S,
+                                     BugReport *R);
 
 const Stmt *GetDerefExpr(const ExplodedNode *N);
 const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetCalleeExpr(const ExplodedNode *N);
 const Stmt *GetRetValExpr(const ExplodedNode *N);
 
 } // end namespace clang
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
index 730a558..973cfb1 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h
@@ -51,22 +51,25 @@
 class PathDiagnostic;
 
 class PathDiagnosticConsumer {
+public:
+  typedef std::vector<std::pair<StringRef, std::string> > FilesMade;
+
+private:
   virtual void anchor();
 public:
   PathDiagnosticConsumer() : flushed(false) {}
   virtual ~PathDiagnosticConsumer();
 
-  void FlushDiagnostics(SmallVectorImpl<std::string> *FilesMade);
+  void FlushDiagnostics(FilesMade *FilesMade);
 
   virtual void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                                    SmallVectorImpl<std::string> *FilesMade)
-                                    = 0;
+                                    FilesMade *filesMade) = 0;
 
   virtual StringRef getName() const = 0;
   
   void HandlePathDiagnostic(PathDiagnostic *D);
 
-  enum PathGenerationScheme { Minimal, Extensive };
+  enum PathGenerationScheme { None, Minimal, Extensive };
   virtual PathGenerationScheme getGenerationScheme() const { return Minimal; }
   virtual bool supportsLogicalOpControlFlow() const { return false; }
   virtual bool supportsAllBlockEdges() const { return false; }
@@ -148,6 +151,15 @@
     assert(Range.isValid());
   }
 
+  /// Create a location at an explicit offset in the source.
+  ///
+  /// This should only be used if there are no more appropriate constructors.
+  PathDiagnosticLocation(SourceLocation loc, const SourceManager &sm)
+    : K(SingleLocK), S(0), D(0), SM(&sm), Loc(loc, sm), Range(genRange()) {
+    assert(Loc.isValid());
+    assert(Range.isValid());
+  }
+
   /// Create a location corresponding to the given declaration.
   static PathDiagnosticLocation create(const Decl *D,
                                        const SourceManager &SM) {
@@ -163,6 +175,14 @@
                                             const SourceManager &SM,
                                             const LocationOrAnalysisDeclContext LAC);
 
+  /// Create a location for the end of the statement.
+  ///
+  /// If the statement is a CompoundStatement, the location will point to the
+  /// closing brace instead of following it.
+  static PathDiagnosticLocation createEnd(const Stmt *S,
+                                          const SourceManager &SM,
+                                       const LocationOrAnalysisDeclContext LAC);
+
   /// Create the location for the operator of the binary expression.
   /// Assumes the statement has a valid location.
   static PathDiagnosticLocation createOperatorLoc(const BinaryOperator *BO,
@@ -315,15 +335,8 @@
     ranges.push_back(SourceRange(B,E));
   }
 
-  typedef const SourceRange* range_iterator;
-
-  range_iterator ranges_begin() const {
-    return ranges.empty() ? NULL : &ranges[0];
-  }
-
-  range_iterator ranges_end() const {
-    return ranges_begin() + ranges.size();
-  }
+  /// Return the SourceRanges associated with this PathDiagnosticPiece.
+  ArrayRef<SourceRange> getRanges() const { return ranges; }
 
   static inline bool classof(const PathDiagnosticPiece *P) {
     return true;
@@ -333,10 +346,17 @@
 };
   
   
-class PathPieces :
-  public std::deque<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+class PathPieces : public std::deque<IntrusiveRefCntPtr<PathDiagnosticPiece> > {
+  void flattenTo(PathPieces &Primary, PathPieces &Current,
+                 bool ShouldFlattenMacros) const;
 public:
-  ~PathPieces();  
+  ~PathPieces();
+
+  PathPieces flatten(bool ShouldFlattenMacros) const {
+    PathPieces Result;
+    flattenTo(Result, Result, ShouldFlattenMacros);
+    return Result;
+  }
 };
 
 class PathDiagnosticSpotPiece : public PathDiagnosticPiece {
@@ -637,6 +657,8 @@
 
   void pushActivePath(PathPieces *p) { pathStack.push_back(p); }
   void popActivePath() { if (!pathStack.empty()) pathStack.pop_back(); }
+
+  bool isWithinCall() const { return !pathStack.empty(); }
   
   //  PathDiagnostic();
   PathDiagnostic(const Decl *DeclWithIssue,
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 7e1b07a..e11b6d5 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -211,15 +211,18 @@
   void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst,
                                      const ExplodedNodeSet &Src,
                                      const ObjCMethodCall &msg,
-                                     ExprEngine &Eng) {
-    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng);
+                                     ExprEngine &Eng,
+                                     bool wasInlined = false) {
+    runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng,
+                              wasInlined);
   }
 
   /// \brief Run checkers for visiting obj-c messages.
   void runCheckersForObjCMessage(bool isPreVisit,
                                  ExplodedNodeSet &Dst,
                                  const ExplodedNodeSet &Src,
-                                 const ObjCMethodCall &msg, ExprEngine &Eng);
+                                 const ObjCMethodCall &msg, ExprEngine &Eng,
+                                 bool wasInlined = false);
 
   /// \brief Run checkers for pre-visiting obj-c messages.
   void runCheckersForPreCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
@@ -229,14 +232,17 @@
 
   /// \brief Run checkers for post-visiting obj-c messages.
   void runCheckersForPostCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src,
-                              const CallEvent &Call, ExprEngine &Eng) {
-    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng);
+                              const CallEvent &Call, ExprEngine &Eng,
+                              bool wasInlined = false) {
+    runCheckersForCallEvent(/*isPreVisit=*/false, Dst, Src, Call, Eng,
+                            wasInlined);
   }
 
   /// \brief Run checkers for visiting obj-c messages.
   void runCheckersForCallEvent(bool isPreVisit, ExplodedNodeSet &Dst,
                                const ExplodedNodeSet &Src,
-                               const CallEvent &Call, ExprEngine &Eng);
+                               const CallEvent &Call, ExprEngine &Eng,
+                               bool wasInlined = false);
 
   /// \brief Run checkers for load/store of a location.
   void runCheckersForLocation(ExplodedNodeSet &Dst,
@@ -313,9 +319,11 @@
                                                SVal Cond, bool Assumption);
 
   /// \brief Run checkers for evaluating a call.
+  ///
+  /// Warning: Currently, the CallEvent MUST come from a CallExpr!
   void runCheckersForEvalCall(ExplodedNodeSet &Dst,
                               const ExplodedNodeSet &Src,
-                              const SimpleCall &CE, ExprEngine &Eng);
+                              const CallEvent &CE, ExprEngine &Eng);
   
   /// \brief Run checkers for the entire Translation Unit.
   void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU,
diff --git a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index 65be3a4..3aab648 100644
--- a/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -15,6 +15,7 @@
 #define LLVM_CLANG_GR_PATH_DIAGNOSTIC_CLIENTS_H
 
 #include <string>
+#include <vector>
 
 namespace clang {
 
@@ -23,24 +24,25 @@
 namespace ento {
 
 class PathDiagnosticConsumer;
+typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
 
-PathDiagnosticConsumer*
-createHTMLDiagnosticConsumer(const std::string& prefix, const Preprocessor &PP);
+void createHTMLDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                  const std::string& prefix,
+                                  const Preprocessor &PP);
 
-PathDiagnosticConsumer*
-createPlistDiagnosticConsumer(const std::string& prefix, const Preprocessor &PP,
-                              PathDiagnosticConsumer *SubPD = 0);
+void createPlistDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                   const std::string& prefix,
+                                   const Preprocessor &PP);
 
-PathDiagnosticConsumer*
-createPlistMultiFileDiagnosticConsumer(const std::string& prefix,
-                                       const Preprocessor &PP);
+void createPlistMultiFileDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                            const std::string& prefix,
+                                            const Preprocessor &PP);
 
-PathDiagnosticConsumer*
-createTextPathDiagnosticConsumer(const std::string& prefix,
-                                 const Preprocessor &PP);
+void createTextPathDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                      const std::string& prefix,
+                                      const Preprocessor &PP);
 
-} // end GR namespace
-
-} // end clang namespace
+} // end 'ento' namespace
+} // end 'clang' namespace
 
 #endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 32ff025..876196b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -19,6 +19,7 @@
 #include "clang/Frontend/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
+#include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
 
 namespace clang {
 
@@ -32,8 +33,7 @@
   ASTContext &Ctx;
   DiagnosticsEngine &Diags;
   const LangOptions &LangOpts;
-
-  OwningPtr<PathDiagnosticConsumer> PD;
+  PathDiagnosticConsumers PathConsumers;
 
   // Configurable components creators.
   StoreManagerCreator CreateStoreMgr;
@@ -82,8 +82,9 @@
   bool NoRetryExhausted;
 
 public:
-  AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, 
-                  const LangOptions &lang, PathDiagnosticConsumer *pd,
+  AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags,
+                  const LangOptions &lang,
+                  const PathDiagnosticConsumers &Consumers,
                   StoreManagerCreator storemgr,
                   ConstraintManagerCreator constraintmgr, 
                   CheckerManager *checkerMgr,
@@ -91,7 +92,7 @@
                   bool vizdot, bool vizubi, AnalysisPurgeMode purge,
                   bool eager, bool trim,
                   bool useUnoptimizedCFG,
-                  bool addImplicitDtors, bool addInitializers,
+                  bool addImplicitDtors,
                   bool eagerlyTrimEGraph,
                   AnalysisIPAMode ipa,
                   unsigned inlineMaxStack,
@@ -99,12 +100,7 @@
                   AnalysisInliningMode inliningMode,
                   bool NoRetry);
 
-  /// Construct a clone of the given AnalysisManager with the given ASTContext
-  /// and DiagnosticsEngine.
-  AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
-                  AnalysisManager &ParentAM);
-
-  ~AnalysisManager() { FlushDiagnostics(); }
+  ~AnalysisManager();
   
   void ClearContexts() {
     AnaCtxMgr.clear();
@@ -140,14 +136,11 @@
     return LangOpts;
   }
 
-  virtual PathDiagnosticConsumer *getPathDiagnosticConsumer() {
-    return PD.get();
+  ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers()  {
+    return PathConsumers;
   }
-  
-  void FlushDiagnostics() {
-    if (PD.get())
-      PD->FlushDiagnostics(0);
-  }
+
+  void FlushDiagnostics();
 
   unsigned getMaxNodes() const { return MaxNodes; }
 
@@ -169,7 +162,7 @@
 
   bool shouldEagerlyAssume() const { return EagerlyAssume; }
 
-  bool shouldInlineCall() const { return (IPAMode == Inlining); }
+  bool shouldInlineCall() const { return (IPAMode != None); }
 
   CFG *getCFG(Decl const *D) {
     return AnaCtxMgr.getContext(D)->getCFG();
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
new file mode 100644
index 0000000..f6c5830
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -0,0 +1,966 @@
+//===- CallEvent.h - Wrapper for all function and method calls ----*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file defines CallEvent and its subclasses, which represent path-
+/// sensitive instances of different kinds of function and method calls
+/// (C, C++, and Objective-C).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
+#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
+
+#include "clang/Basic/SourceManager.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+class ProgramPoint;
+class ProgramPointTag;
+
+namespace ento {
+
+enum CallEventKind {
+  CE_Function,
+  CE_Block,
+  CE_BEG_SIMPLE_CALLS = CE_Function,
+  CE_END_SIMPLE_CALLS = CE_Block,
+  CE_CXXMember,
+  CE_CXXMemberOperator,
+  CE_CXXDestructor,
+  CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
+  CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor,
+  CE_CXXConstructor,
+  CE_CXXAllocator,
+  CE_BEG_FUNCTION_CALLS = CE_Function,
+  CE_END_FUNCTION_CALLS = CE_CXXAllocator,
+  CE_ObjCMessage
+};
+
+class CallEvent;
+class CallEventManager;
+
+template<typename T = CallEvent>
+class CallEventRef : public IntrusiveRefCntPtr<const T> {
+public:
+  CallEventRef(const T *Call) : IntrusiveRefCntPtr<const T>(Call) {}
+  CallEventRef(const CallEventRef &Orig) : IntrusiveRefCntPtr<const T>(Orig) {}
+
+  CallEventRef<T> cloneWithState(ProgramStateRef State) const {
+    return this->getPtr()->template cloneWithState<T>(State);
+  }
+
+  // Allow implicit conversions to a superclass type, since CallEventRef
+  // behaves like a pointer-to-const.
+  template <typename SuperT>
+  operator CallEventRef<SuperT> () const {
+    return this->getPtr();
+  }
+};
+
+/// \brief Defines the runtime definition of the called function.
+class RuntimeDefinition {
+  /// The Declaration of the function which will be called at runtime.
+  /// 0 if not available.
+  const Decl *D;
+
+  /// The region representing an object (ObjC/C++) on which the method is
+  /// called. With dynamic dispatch, the method definition depends on the
+  /// runtime type of this object. 0 when there is no dynamic dispatch.
+  const MemRegion *R;
+
+public:
+  RuntimeDefinition(): D(0), R(0) {}
+  RuntimeDefinition(const Decl *InD): D(InD), R(0) {}
+  RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {}
+  const Decl *getDecl() { return D; }
+  const MemRegion *getDispatchRegion() { return R; }
+  bool mayHaveOtherDefinitions() { return R != 0; }
+};
+
+/// \brief Represents an abstract call to a function or method along a
+/// particular path.
+///
+/// CallEvents are created through the factory methods of CallEventManager.
+///
+/// CallEvents should always be cheap to create and destroy. In order for
+/// CallEventManager to be able to re-use CallEvent-sized memory blocks,
+/// subclasses of CallEvent may not add any data members to the base class.
+/// Use the "Data" and "Location" fields instead.
+class CallEvent {
+public:
+  typedef CallEventKind Kind;
+
+private:
+  ProgramStateRef State;
+  const LocationContext *LCtx;
+  llvm::PointerUnion<const Expr *, const Decl *> Origin;
+
+  // DO NOT IMPLEMENT
+  CallEvent &operator=(const CallEvent &);
+
+protected:
+  // This is user data for subclasses.
+  const void *Data;
+
+  // This is user data for subclasses.
+  // This should come right before RefCount, so that the two fields can be
+  // packed together on LP64 platforms.
+  SourceLocation Location;
+
+private:
+  mutable unsigned RefCount;
+
+  template <typename T> friend struct llvm::IntrusiveRefCntPtrInfo;
+  void Retain() const { ++RefCount; }
+  void Release() const;
+
+protected:
+  friend class CallEventManager;
+
+  CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx)
+    : State(state), LCtx(lctx), Origin(E), RefCount(0) {}
+
+  CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx)
+    : State(state), LCtx(lctx), Origin(D), RefCount(0) {}
+
+  // DO NOT MAKE PUBLIC
+  CallEvent(const CallEvent &Original)
+    : State(Original.State), LCtx(Original.LCtx), Origin(Original.Origin),
+      Data(Original.Data), Location(Original.Location), RefCount(0) {}
+
+
+  ProgramStateRef getState() const {
+    return State;
+  }
+
+  const LocationContext *getLocationContext() const {
+    return LCtx;
+  }
+
+
+  /// Copies this CallEvent, with vtable intact, into a new block of memory.
+  virtual void cloneTo(void *Dest) const = 0;
+
+  /// \brief Get the value of arbitrary expressions at this point in the path.
+  SVal getSVal(const Stmt *S) const {
+    return getState()->getSVal(S, getLocationContext());
+  }
+
+
+  typedef SmallVectorImpl<const MemRegion *> RegionList;
+
+  /// \brief Used to specify non-argument regions that will be invalidated as a
+  /// result of this call.
+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const {}
+
+  virtual QualType getDeclaredResultType() const = 0;
+
+public:
+  virtual ~CallEvent() {}
+
+  /// \brief Returns the kind of call this is.
+  virtual Kind getKind() const = 0;
+
+  /// \brief Returns the declaration of the function or method that will be
+  /// called. May be null.
+  virtual const Decl *getDecl() const {
+    return Origin.dyn_cast<const Decl *>();
+  }
+
+  /// \brief Returns the definition of the function or method that will be
+  /// called.
+  virtual RuntimeDefinition getRuntimeDefinition() const = 0;
+
+  /// \brief Returns the expression whose value will be the result of this call.
+  /// May be null.
+  const Expr *getOriginExpr() const {
+    return Origin.dyn_cast<const Expr *>();
+  }
+
+  /// \brief Returns the number of arguments (explicit and implicit).
+  ///
+  /// Note that this may be greater than the number of parameters in the
+  /// callee's declaration, and that it may include arguments not written in
+  /// the source.
+  virtual unsigned getNumArgs() const = 0;
+
+  /// \brief Returns true if the callee is known to be from a system header.
+  bool isInSystemHeader() const {
+    const Decl *D = getDecl();
+    if (!D)
+      return false;
+
+    SourceLocation Loc = D->getLocation();
+    if (Loc.isValid()) {
+      const SourceManager &SM =
+        getState()->getStateManager().getContext().getSourceManager();
+      return SM.isInSystemHeader(D->getLocation());
+    }
+
+    // Special case for implicitly-declared global operator new/delete.
+    // These should be considered system functions.
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
+
+    return false;
+  }
+
+  /// \brief Returns a source range for the entire call, suitable for
+  /// outputting in diagnostics.
+  virtual SourceRange getSourceRange() const {
+    return getOriginExpr()->getSourceRange();
+  }
+
+  /// \brief Returns the value of a given argument at the time of the call.
+  virtual SVal getArgSVal(unsigned Index) const;
+
+  /// \brief Returns the expression associated with a given argument.
+  /// May be null if this expression does not appear in the source.
+  virtual const Expr *getArgExpr(unsigned Index) const { return 0; }
+
+  /// \brief Returns the source range for errors associated with this argument.
+  ///
+  /// May be invalid if the argument is not written in the source.
+  virtual SourceRange getArgSourceRange(unsigned Index) const;
+
+  /// \brief Returns the result type, adjusted for references.
+  QualType getResultType() const;
+
+  /// \brief Returns true if any of the arguments appear to represent callbacks.
+  bool hasNonZeroCallbackArg() const;
+
+  /// \brief Returns true if any of the arguments are known to escape to long-
+  /// term storage, even if this method will not modify them.
+  // NOTE: The exact semantics of this are still being defined!
+  // We don't really want a list of hardcoded exceptions in the long run,
+  // but we don't want duplicated lists of known APIs in the short term either.
+  virtual bool argumentsMayEscape() const {
+    return hasNonZeroCallbackArg();
+  }
+
+  /// \brief Returns an appropriate ProgramPoint for this call.
+  ProgramPoint getProgramPoint(bool IsPreVisit = false,
+                               const ProgramPointTag *Tag = 0) const;
+
+  /// \brief Returns a new state with all argument regions invalidated.
+  ///
+  /// This accepts an alternate state in case some processing has already
+  /// occurred.
+  ProgramStateRef invalidateRegions(unsigned BlockCount,
+                                    ProgramStateRef Orig = 0) const;
+
+  typedef std::pair<Loc, SVal> FrameBindingTy;
+  typedef SmallVectorImpl<FrameBindingTy> BindingsTy;
+
+  /// Populates the given SmallVector with the bindings in the callee's stack
+  /// frame at the start of this call.
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const = 0;
+
+  /// Returns a copy of this CallEvent, but using the given state.
+  template <typename T>
+  CallEventRef<T> cloneWithState(ProgramStateRef NewState) const;
+
+  /// Returns a copy of this CallEvent, but using the given state.
+  CallEventRef<> cloneWithState(ProgramStateRef NewState) const {
+    return cloneWithState<CallEvent>(NewState);
+  }
+
+  /// \brief Returns true if this is a statement that can be considered for
+  /// inlining.
+  ///
+  /// FIXME: This should go away once CallEvents are cheap and easy to
+  /// construct from ExplodedNodes.
+  static bool mayBeInlined(const Stmt *S);
+
+  // Iterator access to formal parameters and their types.
+private:
+  typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
+  
+public:
+  typedef const ParmVarDecl * const *param_iterator;
+
+  /// Returns an iterator over the call's formal parameters.
+  ///
+  /// If UseDefinitionParams is set, this will return the parameter decls
+  /// used in the callee's definition (suitable for inlining). Most of the
+  /// time it is better to use the decl found by name lookup, which likely
+  /// carries more annotations.
+  ///
+  /// Remember that the number of formal parameters may not match the number
+  /// of arguments for all calls. However, the first parameter will always
+  /// correspond with the argument value returned by \c getArgSVal(0).
+  ///
+  /// If the call has no accessible declaration (or definition, if
+  /// \p UseDefinitionParams is set), \c param_begin() will be equal to
+  /// \c param_end().
+  virtual param_iterator param_begin() const =0;
+  /// \sa param_begin()
+  virtual param_iterator param_end() const = 0;
+
+  typedef llvm::mapped_iterator<param_iterator, get_type_fun>
+    param_type_iterator;
+
+  /// Returns an iterator over the types of the call's formal parameters.
+  ///
+  /// This uses the callee decl found by default name lookup rather than the
+  /// definition because it represents a public interface, and probably has
+  /// more annotations.
+  param_type_iterator param_type_begin() const {
+    return llvm::map_iterator(param_begin(),
+                              get_type_fun(&ParmVarDecl::getType));
+  }
+  /// \sa param_type_begin()
+  param_type_iterator param_type_end() const {
+    return llvm::map_iterator(param_end(), get_type_fun(&ParmVarDecl::getType));
+  }
+
+  // For debugging purposes only
+  void dump(raw_ostream &Out) const;
+  LLVM_ATTRIBUTE_USED void dump() const;
+
+  static bool classof(const CallEvent *) { return true; }
+};
+
+
+/// \brief Represents a call to any sort of function that might have a
+/// FunctionDecl.
+class AnyFunctionCall : public CallEvent {
+protected:
+  AnyFunctionCall(const Expr *E, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : CallEvent(E, St, LCtx) {}
+  AnyFunctionCall(const Decl *D, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : CallEvent(D, St, LCtx) {}
+  AnyFunctionCall(const AnyFunctionCall &Other) : CallEvent(Other) {}
+
+  virtual QualType getDeclaredResultType() const;
+
+public:
+  // This function is overridden by subclasses, but they must return
+  // a FunctionDecl.
+  virtual const FunctionDecl *getDecl() const {
+    return cast<FunctionDecl>(CallEvent::getDecl());
+  }
+
+  virtual RuntimeDefinition getRuntimeDefinition() const {
+    const FunctionDecl *FD = getDecl();
+    // Note that hasBody() will fill FD with the definition FunctionDecl.
+    if (FD && FD->hasBody(FD))
+      return RuntimeDefinition(FD);
+    return RuntimeDefinition();
+  }
+
+  virtual bool argumentsMayEscape() const;
+
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const;
+
+  virtual param_iterator param_begin() const;
+  virtual param_iterator param_end() const;
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
+           CA->getKind() <= CE_END_FUNCTION_CALLS;
+  }
+};
+
+/// \brief Represents a call to a non-C++ function, written as a CallExpr.
+class SimpleCall : public AnyFunctionCall {
+protected:
+  SimpleCall(const CallExpr *CE, ProgramStateRef St,
+             const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {}
+  SimpleCall(const SimpleCall &Other) : AnyFunctionCall(Other) {}
+
+public:
+  virtual const CallExpr *getOriginExpr() const {
+    return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
+  }
+
+  virtual const FunctionDecl *getDecl() const;
+
+  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() >= CE_BEG_SIMPLE_CALLS &&
+           CA->getKind() <= CE_END_SIMPLE_CALLS;
+  }
+};
+
+/// \brief Represents a C function or static C++ member function call.
+///
+/// Example: \c fun()
+class FunctionCall : public SimpleCall {
+  friend class CallEventManager;
+
+protected:
+  FunctionCall(const CallExpr *CE, ProgramStateRef St,
+               const LocationContext *LCtx)
+    : SimpleCall(CE, St, LCtx) {}
+
+  FunctionCall(const FunctionCall &Other) : SimpleCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) FunctionCall(*this); }
+
+public:
+  virtual Kind getKind() const { return CE_Function; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_Function;
+  }
+};
+
+/// \brief Represents a call to a block.
+///
+/// Example: <tt>^{ /* ... */ }()</tt>
+class BlockCall : public SimpleCall {
+  friend class CallEventManager;
+
+protected:
+  BlockCall(const CallExpr *CE, ProgramStateRef St,
+            const LocationContext *LCtx)
+    : SimpleCall(CE, St, LCtx) {}
+
+  BlockCall(const BlockCall &Other) : SimpleCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) BlockCall(*this); }
+
+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+
+  virtual QualType getDeclaredResultType() const;
+
+public:
+  /// \brief Returns the region associated with this instance of the block.
+  ///
+  /// This may be NULL if the block's origin is unknown.
+  const BlockDataRegion *getBlockRegion() const;
+
+  /// \brief Gets the declaration of the block.
+  ///
+  /// This is not an override of getDecl() because AnyFunctionCall has already
+  /// assumed that it's a FunctionDecl.
+  const BlockDecl *getBlockDecl() const {
+    const BlockDataRegion *BR = getBlockRegion();
+    if (!BR)
+      return 0;
+    return BR->getDecl();
+  }
+
+  virtual RuntimeDefinition getRuntimeDefinition() const {
+    return RuntimeDefinition(getBlockDecl());
+  }
+
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const;
+
+  virtual param_iterator param_begin() const;
+  virtual param_iterator param_end() const;
+
+  virtual Kind getKind() const { return CE_Block; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_Block;
+  }
+};
+
+/// \brief Represents a non-static C++ member function call, no matter how
+/// it is written.
+class CXXInstanceCall : public AnyFunctionCall {
+protected:
+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+
+  CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {}
+  CXXInstanceCall(const FunctionDecl *D, ProgramStateRef St,
+                  const LocationContext *LCtx)
+    : AnyFunctionCall(D, St, LCtx) {}
+
+
+  CXXInstanceCall(const CXXInstanceCall &Other) : AnyFunctionCall(Other) {}
+
+public:
+  /// \brief Returns the expression representing the implicit 'this' object.
+  virtual const Expr *getCXXThisExpr() const { return 0; }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  virtual SVal getCXXThisVal() const {
+    const Expr *Base = getCXXThisExpr();
+    // FIXME: This doesn't handle an overloaded ->* operator.
+    if (!Base)
+      return UnknownVal();
+    return getSVal(Base);
+  }
+
+  virtual const FunctionDecl *getDecl() const;
+
+  virtual RuntimeDefinition getRuntimeDefinition() const;
+
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const;
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
+           CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
+  }
+};
+
+/// \brief Represents a non-static C++ member function call.
+///
+/// Example: \c obj.fun()
+class CXXMemberCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
+                const LocationContext *LCtx)
+    : CXXInstanceCall(CE, St, LCtx) {}
+
+  CXXMemberCall(const CXXMemberCall &Other) : CXXInstanceCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) CXXMemberCall(*this); }
+
+public:
+  virtual const CXXMemberCallExpr *getOriginExpr() const {
+    return cast<CXXMemberCallExpr>(CXXInstanceCall::getOriginExpr());
+  }
+
+  virtual unsigned getNumArgs() const {
+    if (const CallExpr *CE = getOriginExpr())
+      return CE->getNumArgs();
+    return 0;
+  }
+
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  virtual const Expr *getCXXThisExpr() const;
+
+  virtual Kind getKind() const { return CE_CXXMember; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXMember;
+  }
+};
+
+/// \brief Represents a C++ overloaded operator call where the operator is
+/// implemented as a non-static member function.
+///
+/// Example: <tt>iter + 1</tt>
+class CXXMemberOperatorCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
+                        const LocationContext *LCtx)
+    : CXXInstanceCall(CE, St, LCtx) {}
+
+  CXXMemberOperatorCall(const CXXMemberOperatorCall &Other)
+    : CXXInstanceCall(Other) {}
+  virtual void cloneTo(void *Dest) const {
+    new (Dest) CXXMemberOperatorCall(*this);
+  }
+
+public:
+  virtual const CXXOperatorCallExpr *getOriginExpr() const {
+    return cast<CXXOperatorCallExpr>(CXXInstanceCall::getOriginExpr());
+  }
+
+  virtual unsigned getNumArgs() const {
+    return getOriginExpr()->getNumArgs() - 1;
+  }
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index + 1);
+  }
+
+  virtual const Expr *getCXXThisExpr() const;
+
+  virtual Kind getKind() const { return CE_CXXMemberOperator; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXMemberOperator;
+  }
+};
+
+/// \brief Represents an implicit call to a C++ destructor.
+///
+/// This can occur at the end of a scope (for automatic objects), at the end
+/// of a full-expression (for temporaries), or as part of a delete.
+class CXXDestructorCall : public CXXInstanceCall {
+  friend class CallEventManager;
+
+protected:
+  /// Creates an implicit destructor.
+  ///
+  /// \param DD The destructor that will be called.
+  /// \param Trigger The statement whose completion causes this destructor call.
+  /// \param Target The object region to be destructed.
+  /// \param St The path-sensitive state at this point in the program.
+  /// \param LCtx The location context at this point in the program.
+  CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
+                    const MemRegion *Target, ProgramStateRef St,
+                    const LocationContext *LCtx)
+    : CXXInstanceCall(DD, St, LCtx) {
+    Data = Target;
+    Location = Trigger->getLocEnd();
+  }
+
+  CXXDestructorCall(const CXXDestructorCall &Other) : CXXInstanceCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) CXXDestructorCall(*this); }
+
+public:
+  virtual SourceRange getSourceRange() const { return Location; }
+  virtual unsigned getNumArgs() const { return 0; }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  virtual SVal getCXXThisVal() const;
+
+  virtual Kind getKind() const { return CE_CXXDestructor; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXDestructor;
+  }
+};
+
+/// \brief Represents a call to a C++ constructor.
+///
+/// Example: \c T(1)
+class CXXConstructorCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
+protected:
+  /// Creates a constructor call.
+  ///
+  /// \param CE The constructor expression as written in the source.
+  /// \param Target The region where the object should be constructed. If NULL,
+  ///               a new symbolic region will be used.
+  /// \param St The path-sensitive state at this point in the program.
+  /// \param LCtx The location context at this point in the program.
+  CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *target,
+                     ProgramStateRef St, const LocationContext *LCtx)
+    : AnyFunctionCall(CE, St, LCtx) {
+    Data = target;
+  }
+
+  CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){}
+  virtual void cloneTo(void *Dest) const { new (Dest) CXXConstructorCall(*this); }
+
+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+
+public:
+  virtual const CXXConstructExpr *getOriginExpr() const {
+    return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
+  }
+
+  virtual const CXXConstructorDecl *getDecl() const {
+    return getOriginExpr()->getConstructor();
+  }
+
+  virtual unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
+
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  /// \brief Returns the value of the implicit 'this' object.
+  SVal getCXXThisVal() const;
+
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const;
+
+  virtual Kind getKind() const { return CE_CXXConstructor; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_CXXConstructor;
+  }
+};
+
+/// \brief Represents the memory allocation call in a C++ new-expression.
+///
+/// This is a call to "operator new".
+class CXXAllocatorCall : public AnyFunctionCall {
+  friend class CallEventManager;
+
+protected:
+  CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
+                   const LocationContext *LCtx)
+    : AnyFunctionCall(E, St, LCtx) {}
+
+  CXXAllocatorCall(const CXXAllocatorCall &Other) : AnyFunctionCall(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) CXXAllocatorCall(*this); }
+
+public:
+  virtual const CXXNewExpr *getOriginExpr() const {
+    return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
+  }
+
+  virtual const FunctionDecl *getDecl() const {
+    return getOriginExpr()->getOperatorNew();
+  }
+
+  virtual unsigned getNumArgs() const {
+    return getOriginExpr()->getNumPlacementArgs() + 1;
+  }
+
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    // The first argument of an allocator call is the size of the allocation.
+    if (Index == 0)
+      return 0;
+    return getOriginExpr()->getPlacementArg(Index - 1);
+  }
+
+  virtual Kind getKind() const { return CE_CXXAllocator; }
+
+  static bool classof(const CallEvent *CE) {
+    return CE->getKind() == CE_CXXAllocator;
+  }
+};
+
+/// \brief Represents the ways an Objective-C message send can occur.
+//
+// Note to maintainers: OCM_Message should always be last, since it does not
+// need to fit in the Data field's low bits.
+enum ObjCMessageKind {
+  OCM_PropertyAccess,
+  OCM_Subscript,
+  OCM_Message
+};
+
+/// \brief Represents any expression that calls an Objective-C method.
+///
+/// This includes all of the kinds listed in ObjCMessageKind.
+class ObjCMethodCall : public CallEvent {
+  friend class CallEventManager;
+
+  const PseudoObjectExpr *getContainingPseudoObjectExpr() const;
+
+protected:
+  ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
+                 const LocationContext *LCtx)
+    : CallEvent(Msg, St, LCtx) {
+    Data = 0;
+  }
+
+  ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {}
+  virtual void cloneTo(void *Dest) const { new (Dest) ObjCMethodCall(*this); }
+
+  virtual void getExtraInvalidatedRegions(RegionList &Regions) const;
+
+  virtual QualType getDeclaredResultType() const;
+
+  /// Check if the selector may have multiple definitions (may have overrides).
+  virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
+                                        Selector Sel) const;
+
+public:
+  virtual const ObjCMessageExpr *getOriginExpr() const {
+    return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
+  }
+  virtual const ObjCMethodDecl *getDecl() const {
+    return getOriginExpr()->getMethodDecl();
+  }
+  virtual unsigned getNumArgs() const {
+    return getOriginExpr()->getNumArgs();
+  }
+  virtual const Expr *getArgExpr(unsigned Index) const {
+    return getOriginExpr()->getArg(Index);
+  }
+
+  bool isInstanceMessage() const {
+    return getOriginExpr()->isInstanceMessage();
+  }
+  ObjCMethodFamily getMethodFamily() const {
+    return getOriginExpr()->getMethodFamily();
+  }
+  Selector getSelector() const {
+    return getOriginExpr()->getSelector();
+  }
+
+  virtual SourceRange getSourceRange() const;
+
+  /// \brief Returns the value of the receiver at the time of this call.
+  SVal getReceiverSVal() const;
+
+  /// \brief Get the interface for the receiver.
+  ///
+  /// This works whether this is an instance message or a class message.
+  /// However, it currently just uses the static type of the receiver.
+  const ObjCInterfaceDecl *getReceiverInterface() const {
+    return getOriginExpr()->getReceiverInterface();
+  }
+
+  /// Returns how the message was written in the source (property access,
+  /// subscript, or explicit message send).
+  ObjCMessageKind getMessageKind() const;
+
+  /// Returns true if this property access or subscript is a setter (has the
+  /// form of an assignment).
+  bool isSetter() const {
+    switch (getMessageKind()) {
+    case OCM_Message:
+      llvm_unreachable("This is not a pseudo-object access!");
+    case OCM_PropertyAccess:
+      return getNumArgs() > 0;
+    case OCM_Subscript:
+      return getNumArgs() > 1;
+    }
+    llvm_unreachable("Unknown message kind");
+  }
+
+  virtual RuntimeDefinition getRuntimeDefinition() const;
+
+  virtual void getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const;
+
+  virtual param_iterator param_begin() const;
+  virtual param_iterator param_end() const;
+
+  virtual Kind getKind() const { return CE_ObjCMessage; }
+
+  static bool classof(const CallEvent *CA) {
+    return CA->getKind() == CE_ObjCMessage;
+  }
+};
+
+
+/// \brief Manages the lifetime of CallEvent objects.
+///
+/// CallEventManager provides a way to create arbitrary CallEvents "on the
+/// stack" as if they were value objects by keeping a cache of CallEvent-sized
+/// memory blocks. The CallEvents created by CallEventManager are only valid
+/// for the lifetime of the OwnedCallEvent that holds them; right now these
+/// objects cannot be copied and ownership cannot be transferred.
+class CallEventManager {
+  friend class CallEvent;
+
+  llvm::BumpPtrAllocator &Alloc;
+  SmallVector<void *, 8> Cache;
+
+  void reclaim(const void *Memory) {
+    Cache.push_back(const_cast<void *>(Memory));
+  }
+
+  /// Returns memory that can be initialized as a CallEvent.
+  void *allocate() {
+    if (Cache.empty())
+      return Alloc.Allocate<FunctionCall>();
+    else
+      return Cache.pop_back_val();
+  }
+
+  template <typename T, typename Arg>
+  T *create(Arg A, ProgramStateRef St, const LocationContext *LCtx) {
+    return new (allocate()) T(A, St, LCtx);
+  }
+
+  template <typename T, typename Arg1, typename Arg2>
+  T *create(Arg1 A1, Arg2 A2, ProgramStateRef St, const LocationContext *LCtx) {
+    return new (allocate()) T(A1, A2, St, LCtx);
+  }
+
+  template <typename T, typename Arg1, typename Arg2, typename Arg3>
+  T *create(Arg1 A1, Arg2 A2, Arg3 A3, ProgramStateRef St,
+            const LocationContext *LCtx) {
+    return new (allocate()) T(A1, A2, A3, St, LCtx);
+  }
+
+public:
+  CallEventManager(llvm::BumpPtrAllocator &alloc) : Alloc(alloc) {}
+
+
+  CallEventRef<>
+  getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State);
+
+
+  CallEventRef<>
+  getSimpleCall(const CallExpr *E, ProgramStateRef State,
+                const LocationContext *LCtx);
+
+  CallEventRef<ObjCMethodCall>
+  getObjCMethodCall(const ObjCMessageExpr *E, ProgramStateRef State,
+                    const LocationContext *LCtx) {
+    return create<ObjCMethodCall>(E, State, LCtx);
+  }
+
+  CallEventRef<CXXConstructorCall>
+  getCXXConstructorCall(const CXXConstructExpr *E, const MemRegion *Target,
+                        ProgramStateRef State, const LocationContext *LCtx) {
+    return create<CXXConstructorCall>(E, Target, State, LCtx);
+  }
+
+  CallEventRef<CXXDestructorCall>
+  getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
+                       const MemRegion *Target, ProgramStateRef State,
+                       const LocationContext *LCtx) {
+    return create<CXXDestructorCall>(DD, Trigger, Target, State, LCtx);
+  }
+
+  CallEventRef<CXXAllocatorCall>
+  getCXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef State,
+                      const LocationContext *LCtx) {
+    return create<CXXAllocatorCall>(E, State, LCtx);
+  }
+};
+
+
+template <typename T>
+CallEventRef<T> CallEvent::cloneWithState(ProgramStateRef NewState) const {
+  assert(isa<T>(*this) && "Cloning to unrelated type");
+  assert(sizeof(T) == sizeof(CallEvent) && "Subclasses may not add fields");
+
+  if (NewState == State)
+    return cast<T>(this);
+
+  CallEventManager &Mgr = State->getStateManager().getCallEventManager();
+  T *Copy = static_cast<T *>(Mgr.allocate());
+  cloneTo(Copy);
+  assert(Copy->getKind() == this->getKind() && "Bad copy");
+
+  Copy->State = NewState;
+  return Copy;
+}
+
+inline void CallEvent::Release() const {
+  assert(RefCount > 0 && "Reference count is already zero.");
+  --RefCount;
+
+  if (RefCount > 0)
+    return;
+
+  CallEventManager &Mgr = State->getStateManager().getCallEventManager();
+  Mgr.reclaim(this);
+
+  this->~CallEvent();
+}
+
+} // end namespace ento
+} // end namespace clang
+
+namespace llvm {
+  // Support isa<>, cast<>, and dyn_cast<> for CallEventRef.
+  template<class T> struct simplify_type< clang::ento::CallEventRef<T> > {
+    typedef const T *SimpleType;
+
+    static SimpleType
+    getSimplifiedValue(const clang::ento::CallEventRef<T>& Val) {
+      return Val.getPtr();
+    }
+  };
+}
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
deleted file mode 100644
index d406827..0000000
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Calls.h
+++ /dev/null
@@ -1,822 +0,0 @@
-//===- Calls.h - Wrapper for all function and method calls --------*- C++ -*--//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file This file defines CallEvent and its subclasses, which represent path-
-/// sensitive instances of different kinds of function and method calls
-/// (C, C++, and Objective-C).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
-#define LLVM_CLANG_STATICANALYZER_PATHSENSITIVE_CALL
-
-#include "clang/Basic/SourceManager.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/PointerIntPair.h"
-
-namespace clang {
-class ProgramPoint;
-class ProgramPointTag;
-
-namespace ento {
-
-enum CallEventKind {
-  CE_Function,
-  CE_CXXMember,
-  CE_CXXMemberOperator,
-  CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember,
-  CE_END_CXX_INSTANCE_CALLS = CE_CXXMemberOperator,
-  CE_Block,
-  CE_BEG_SIMPLE_CALLS = CE_Function,
-  CE_END_SIMPLE_CALLS = CE_Block,
-  CE_CXXConstructor,
-  CE_CXXDestructor,
-  CE_CXXAllocator,
-  CE_BEG_FUNCTION_CALLS = CE_Function,
-  CE_END_FUNCTION_CALLS = CE_CXXAllocator,
-  CE_ObjCMessage
-};
-
-
-/// \brief Represents an abstract call to a function or method along a
-/// particular path.
-class CallEvent {
-public:
-  typedef CallEventKind Kind;
-
-private:
-  // PointerIntPair doesn't respect IntrusiveRefCntPtr, so we have to manually
-  // retain and release the state.
-  llvm::PointerIntPair<const ProgramState *, 2> State;
-  llvm::PointerIntPair<const LocationContext *, 2> LCtx;
-  llvm::PointerUnion<const Expr *, const Decl *> Origin;
-
-protected:
-  // This is user data for subclasses.
-  const void *Data;
-  SourceLocation Location;
-
-  CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx,
-            Kind k)
-    : State(state.getPtr(), (k & 0x3)),
-      LCtx(lctx, ((k >> 2) & 0x3)),
-      Origin(E) {
-    IntrusiveRefCntPtrInfo<const ProgramState>::retain(getState());
-    assert(k == getKind() && "More kinds than bits in the PointerIntPairs.");
-  }
-
-  CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx,
-            Kind k)
-    : State(state.getPtr(), (k & 0x3)),
-      LCtx(lctx, ((k >> 2) & 0x3)),
-      Origin(D) {
-    IntrusiveRefCntPtrInfo<const ProgramState>::retain(getState());
-    assert(k == getKind() && "More kinds than bits in the PointerIntPairs.");
-  }
-
-  const ProgramState *getState() const {
-    return State.getPointer();
-  }
-
-  const LocationContext *getLocationContext() const {
-    return LCtx.getPointer();
-  }
-
-  ~CallEvent() {
-    IntrusiveRefCntPtrInfo<const ProgramState>::release(getState());
-  }
-
-
-  /// \brief Get the value of arbitrary expressions at this point in the path.
-  SVal getSVal(const Stmt *S) const {
-    return getState()->getSVal(S, getLocationContext());
-  }
-
-  typedef SmallVectorImpl<const MemRegion *> RegionList;
-
-  /// \brief Used to specify non-argument regions that will be invalidated as a
-  /// result of this call.
-  void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-  QualType getDeclaredResultType() const;
-
-public:
-  /// \brief Returns the kind of call this is.
-  Kind getKind() const {
-    return static_cast<Kind>((State.getInt()) | (LCtx.getInt() << 2));
-  }
-
-  /// \brief Returns the declaration of the function or method that will be
-  /// called. May be null.
-  const Decl *getDecl() const;
-
-  /// \brief Returns the definition of the function or method that will be
-  /// called. May be null.
-  ///
-  /// This is used when deciding how to inline the call.
-  ///
-  /// \param IsDynamicDispatch True if the definition returned may not be the
-  ///   definition that is actually invoked at runtime. Note that if we have
-  ///   sufficient type information to devirtualize a dynamic method call,
-  ///   we will (and \p IsDynamicDispatch will be set to \c false).
-  const Decl *getDefinition(bool &IsDynamicDispatch) const;
-
-  /// \brief Returns the expression whose value will be the result of this call.
-  /// May be null.
-  const Expr *getOriginExpr() const {
-    return Origin.dyn_cast<const Expr *>();
-  }
-
-  /// \brief Returns the number of arguments (explicit and implicit).
-  ///
-  /// Note that this may be greater than the number of parameters in the
-  /// callee's declaration, and that it may include arguments not written in
-  /// the source.
-  unsigned getNumArgs() const;
-
-  /// \brief Returns true if the callee is known to be from a system header.
-  bool isInSystemHeader() const {
-    const Decl *D = getDecl();
-    if (!D)
-      return false;
-
-    SourceLocation Loc = D->getLocation();
-    if (Loc.isValid()) {
-      const SourceManager &SM =
-        getState()->getStateManager().getContext().getSourceManager();
-      return SM.isInSystemHeader(D->getLocation());
-    }
-
-    // Special case for implicitly-declared global operator new/delete.
-    // These should be considered system functions.
-    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-      return FD->isOverloadedOperator() && FD->isImplicit() && FD->isGlobal();
-
-    return false;
-  }
-
-  /// \brief Returns a source range for the entire call, suitable for
-  /// outputting in diagnostics.
-  SourceRange getSourceRange() const;
-
-  /// \brief Returns the value of a given argument at the time of the call.
-  SVal getArgSVal(unsigned Index) const;
-
-  /// \brief Returns the expression associated with a given argument.
-  /// May be null if this expression does not appear in the source.
-  const Expr *getArgExpr(unsigned Index) const;
-
-  /// \brief Returns the source range for errors associated with this argument.
-  /// May be invalid if the argument is not written in the source.
-  // FIXME: Is it better to return an invalid range or the range of the origin
-  // expression?
-  SourceRange getArgSourceRange(unsigned Index) const;
-
-  /// \brief Returns the result type, adjusted for references.
-  QualType getResultType() const;
-
-  /// \brief Returns the value of the implicit 'this' object, or UndefinedVal if
-  /// this is not a C++ member function call.
-  SVal getCXXThisVal() const;
-
-  /// \brief Returns true if any of the arguments appear to represent callbacks.
-  bool hasNonZeroCallbackArg() const;
-
-  /// \brief Returns true if any of the arguments are known to escape to long-
-  /// term storage, even if this method will not modify them.
-  // NOTE: The exact semantics of this are still being defined!
-  // We don't really want a list of hardcoded exceptions in the long run,
-  // but we don't want duplicated lists of known APIs in the short term either.
-  bool argumentsMayEscape() const;
-
-  /// \brief Returns an appropriate ProgramPoint for this call.
-  ProgramPoint getProgramPoint(bool IsPreVisit = false,
-                               const ProgramPointTag *Tag = 0) const;
-
-  /// \brief Returns a new state with all argument regions invalidated.
-  ///
-  /// This accepts an alternate state in case some processing has already
-  /// occurred.
-  ProgramStateRef invalidateRegions(unsigned BlockCount,
-                                    ProgramStateRef Orig = 0) const;
-
-  /// \brief Returns true if this is a statement that can be considered for
-  /// inlining.
-  static bool mayBeInlined(const Stmt *S);
-
-  // Iterator access to formal parameters and their types.
-private:
-  typedef std::const_mem_fun_t<QualType, ParmVarDecl> get_type_fun;
-  
-public:
-  typedef const ParmVarDecl * const *param_iterator;
-
-  /// Returns an iterator over the call's formal parameters.
-  ///
-  /// If UseDefinitionParams is set, this will return the parameter decls
-  /// used in the callee's definition (suitable for inlining). Most of the
-  /// time it is better to use the decl found by name lookup, which likely
-  /// carries more annotations.
-  ///
-  /// Remember that the number of formal parameters may not match the number
-  /// of arguments for all calls. However, the first parameter will always
-  /// correspond with the argument value returned by \c getArgSVal(0).
-  ///
-  /// If the call has no accessible declaration (or definition, if
-  /// \p UseDefinitionParams is set), \c param_begin() will be equal to
-  /// \c param_end().
-  param_iterator param_begin(bool UseDefinitionParams = false) const;
-  /// \sa param_begin()
-  param_iterator param_end(bool UseDefinitionParams = false) const;
-
-  typedef llvm::mapped_iterator<param_iterator, get_type_fun>
-    param_type_iterator;
-
-  /// Returns an iterator over the types of the call's formal parameters.
-  ///
-  /// This uses the callee decl found by default name lookup rather than the
-  /// definition because it represents a public interface, and probably has
-  /// more annotations.
-  param_type_iterator param_type_begin() const {
-    return llvm::map_iterator(param_begin(),
-                              get_type_fun(&ParmVarDecl::getType));
-  }
-  /// \sa param_type_begin()
-  param_type_iterator param_type_end() const {
-    return llvm::map_iterator(param_end(), get_type_fun(&ParmVarDecl::getType));
-  }
-
-  // For debugging purposes only
-  void dump(raw_ostream &Out) const;
-  LLVM_ATTRIBUTE_USED void dump() const { dump(llvm::errs()); }
-
-  static bool classof(const CallEvent *) { return true; }
-};
-
-
-/// \brief Represents a call to any sort of function that might have a
-/// FunctionDecl.
-class AnyFunctionCall : public CallEvent {
-  friend class CallEvent;
-
-protected:
-  AnyFunctionCall(const Expr *E, ProgramStateRef St,
-                  const LocationContext *LCtx, Kind K)
-    : CallEvent(E, St, LCtx, K) {}
-  AnyFunctionCall(const Decl *D, ProgramStateRef St,
-                  const LocationContext *LCtx, Kind K)
-    : CallEvent(D, St, LCtx, K) {}
-
-  // Most function calls have no extra invalidated regions.
-  void getExtraInvalidatedRegions(RegionList &Regions) const {}
-
-  QualType getDeclaredResultType() const;
-
-public:
-  // This function is overridden by subclasses, but they must return
-  // a FunctionDecl.
-  const FunctionDecl *getDecl() const {
-    return cast_or_null<FunctionDecl>(CallEvent::getDecl());
-  }
-
-  const Decl *getDefinition(bool &IsDynamicDispatch) const {
-    IsDynamicDispatch = false;
-    const FunctionDecl *FD = getDecl();
-    // Note that hasBody() will fill FD with the definition FunctionDecl.
-    if (FD && FD->hasBody(FD))
-      return FD;
-    return 0;
-  }
-
-  bool argumentsMayEscape() const;
-
-  SVal getArgSVal(unsigned Index) const;
-  SourceRange getArgSourceRange(unsigned Index) const;
-
-  param_iterator param_begin(bool UseDefinitionParams = false) const;
-  param_iterator param_end(bool UseDefinitionParams = false) const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() >= CE_BEG_FUNCTION_CALLS &&
-           CA->getKind() <= CE_END_FUNCTION_CALLS;
-  }
-};
-
-/// \brief Represents a call to a written as a CallExpr.
-class SimpleCall : public AnyFunctionCall {
-protected:
-  SimpleCall(const CallExpr *CE, ProgramStateRef St,
-             const LocationContext *LCtx, Kind K)
-    : AnyFunctionCall(CE, St, LCtx, K) {
-  }
-
-public:
-  const CallExpr *getOriginExpr() const {
-    return cast<CallExpr>(AnyFunctionCall::getOriginExpr());
-  }
-
-  const FunctionDecl *getDecl() const;
-
-  unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
-  SourceRange getSourceRange() const {
-    return getOriginExpr()->getSourceRange();
-  }
-  
-  const Expr *getArgExpr(unsigned Index) const {
-    return getOriginExpr()->getArg(Index);
-  }
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() >= CE_BEG_SIMPLE_CALLS &&
-           CA->getKind() <= CE_END_SIMPLE_CALLS;
-  }
-};
-
-/// \brief Represents a C function or static C++ member function call.
-///
-/// Example: \c fun()
-class FunctionCall : public SimpleCall {
-public:
-  FunctionCall(const CallExpr *CE, ProgramStateRef St,
-               const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx, CE_Function) {}
-
-  SVal getCXXThisVal() const { return UndefinedVal(); }
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_Function;
-  }
-};
-
-/// \brief Represents a non-static C++ member function call, no matter how
-/// it is written.
-class CXXInstanceCall : public SimpleCall {
-  friend class CallEvent;
-
-protected:
-  void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-  CXXInstanceCall(const CallExpr *CE, ProgramStateRef St,
-                  const LocationContext *LCtx, Kind K)
-    : SimpleCall(CE, St, LCtx, K) {}
-
-public:
-  const Decl *getDefinition(bool &IsDynamicDispatch) const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() >= CE_BEG_CXX_INSTANCE_CALLS &&
-           CA->getKind() <= CE_END_CXX_INSTANCE_CALLS;
-  }
-};
-
-/// \brief Represents a non-static C++ member function call.
-///
-/// Example: \c obj.fun()
-class CXXMemberCall : public CXXInstanceCall {
-public:
-  CXXMemberCall(const CXXMemberCallExpr *CE, ProgramStateRef St,
-                const LocationContext *LCtx)
-    : CXXInstanceCall(CE, St, LCtx, CE_CXXMember) {}
-
-  const CXXMemberCallExpr *getOriginExpr() const {
-    return cast<CXXMemberCallExpr>(SimpleCall::getOriginExpr());
-  }
-
-  SVal getCXXThisVal() const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXMember;
-  }
-};
-
-/// \brief Represents a C++ overloaded operator call where the operator is
-/// implemented as a non-static member function.
-///
-/// Example: <tt>iter + 1</tt>
-class CXXMemberOperatorCall : public CXXInstanceCall {
-public:
-  CXXMemberOperatorCall(const CXXOperatorCallExpr *CE, ProgramStateRef St,
-                        const LocationContext *LCtx)
-    : CXXInstanceCall(CE, St, LCtx, CE_CXXMemberOperator) {}
-
-  const CXXOperatorCallExpr *getOriginExpr() const {
-    return cast<CXXOperatorCallExpr>(SimpleCall::getOriginExpr());
-  }
-
-  unsigned getNumArgs() const { return getOriginExpr()->getNumArgs() - 1; }
-  const Expr *getArgExpr(unsigned Index) const {
-    return getOriginExpr()->getArg(Index + 1);
-  }
-
-  SVal getCXXThisVal() const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXMemberOperator;
-  }
-};
-
-/// \brief Represents a call to a block.
-///
-/// Example: <tt>^{ /* ... */ }()</tt>
-class BlockCall : public SimpleCall {
-  friend class CallEvent;
-
-protected:
-  void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-  QualType getDeclaredResultType() const;
-
-public:
-  BlockCall(const CallExpr *CE, ProgramStateRef St,
-            const LocationContext *LCtx)
-    : SimpleCall(CE, St, LCtx, CE_Block) {}
-
-  /// \brief Returns the region associated with this instance of the block.
-  ///
-  /// This may be NULL if the block's origin is unknown.
-  const BlockDataRegion *getBlockRegion() const;
-
-  /// \brief Gets the declaration of the block.
-  ///
-  /// This is not an override of getDecl() because AnyFunctionCall has already
-  /// assumed that it's a FunctionDecl.
-  const BlockDecl *getBlockDecl() const {
-    const BlockDataRegion *BR = getBlockRegion();
-    if (!BR)
-      return 0;
-    return BR->getDecl();
-  }
-
-  const Decl *getDefinition(bool &IsDynamicDispatch) const {
-    IsDynamicDispatch = false;
-    return getBlockDecl();
-  }
-
-  param_iterator param_begin(bool UseDefinitionParams = false) const;
-  param_iterator param_end(bool UseDefinitionParams = false) const;
-
-  SVal getCXXThisVal() const { return UndefinedVal(); }
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_Block;
-  }
-};
-
-/// \brief Represents a call to a C++ constructor.
-///
-/// Example: \c T(1)
-class CXXConstructorCall : public AnyFunctionCall {
-  friend class CallEvent;
-
-protected:
-  void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-public:
-  /// Represents a constructor call to a new or unknown region.
-  CXXConstructorCall(const CXXConstructExpr *CE, ProgramStateRef St,
-                     const LocationContext *LCtx)
-    : AnyFunctionCall(CE, St, LCtx, CE_CXXConstructor) {
-    Data = 0;
-  }
-
-  /// Represents a constructor call on an existing object region.
-  CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *target,
-                     ProgramStateRef St, const LocationContext *LCtx)
-    : AnyFunctionCall(CE, St, LCtx, CE_CXXConstructor) {
-    Data = target;
-  }
-
-  const CXXConstructExpr *getOriginExpr() const {
-    return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr());
-  }
-
-  SourceRange getSourceRange() const {
-    return getOriginExpr()->getSourceRange();
-  }
-
-  const CXXConstructorDecl *getDecl() const {
-    return getOriginExpr()->getConstructor();
-  }
-
-  unsigned getNumArgs() const { return getOriginExpr()->getNumArgs(); }
-
-  const Expr *getArgExpr(unsigned Index) const {
-    return getOriginExpr()->getArg(Index);
-  }
-
-  SVal getCXXThisVal() const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXConstructor;
-  }
-};
-
-/// \brief Represents an implicit call to a C++ destructor.
-///
-/// This can occur at the end of a scope (for automatic objects), at the end
-/// of a full-expression (for temporaries), or as part of a delete.
-class CXXDestructorCall : public AnyFunctionCall {
-  friend class CallEvent;
-
-protected:
-  void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-public:
-  /// Creates an implicit destructor.
-  ///
-  /// \param DD The destructor that will be called.
-  /// \param Trigger The statement whose completion causes this destructor call.
-  /// \param Target The object region to be destructed.
-  /// \param St The path-sensitive state at this point in the program.
-  /// \param LCtx The location context at this point in the program.
-  CXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger,
-                    const MemRegion *Target, ProgramStateRef St,
-                    const LocationContext *LCtx)
-    : AnyFunctionCall(DD, St, LCtx, CE_CXXDestructor) {
-    Data = Target;
-    Location = Trigger->getLocEnd();
-  }
-
-  SourceRange getSourceRange() const { return Location; }
-  unsigned getNumArgs() const { return 0; }
-
-  SVal getCXXThisVal() const;
-  const Decl *getDefinition(bool &IsDynamicDispatch) const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_CXXDestructor;
-  }
-};
-
-/// \brief Represents the memory allocation call in a C++ new-expression.
-///
-/// This is a call to "operator new".
-class CXXAllocatorCall : public AnyFunctionCall {
-public:
-  CXXAllocatorCall(const CXXNewExpr *E, ProgramStateRef St,
-                   const LocationContext *LCtx)
-    : AnyFunctionCall(E, St, LCtx, CE_CXXAllocator) {}
-
-  const CXXNewExpr *getOriginExpr() const {
-    return cast<CXXNewExpr>(AnyFunctionCall::getOriginExpr());
-  }
-
-  // FIXME: This isn't exactly the range of the allocator...
-  SourceRange getSourceRange() const {
-    return getOriginExpr()->getSourceRange();
-  }
-
-  const FunctionDecl *getDecl() const {
-    return getOriginExpr()->getOperatorNew();
-  }
-
-  unsigned getNumArgs() const {
-    return getOriginExpr()->getNumPlacementArgs() + 1;
-  }
-
-  const Expr *getArgExpr(unsigned Index) const {
-    // The first argument of an allocator call is the size of the allocation.
-    if (Index == 0)
-      return 0;
-    return getOriginExpr()->getPlacementArg(Index - 1);
-  }
-
-  SVal getCXXThisVal() const { return UndefinedVal(); }
-
-  static bool classof(const CallEvent *CE) {
-    return CE->getKind() == CE_CXXAllocator;
-  }
-};
-
-/// \brief Represents the ways an Objective-C message send can occur.
-//
-// Note to maintainers: OCM_Message should always be last, since it does not
-// need to fit in the Data field's low bits.
-enum ObjCMessageKind {
-  OCM_PropertyAccess,
-  OCM_Subscript,
-  OCM_Message
-};
-
-/// \brief Represents any expression that calls an Objective-C method.
-///
-/// This includes all of the kinds listed in ObjCMessageKind.
-class ObjCMethodCall : public CallEvent {
-  friend class CallEvent;
-
-  const PseudoObjectExpr *getContainingPseudoObjectExpr() const;
-
-protected:
-  void getExtraInvalidatedRegions(RegionList &Regions) const;
-
-  QualType getDeclaredResultType() const;
-
-public:
-  ObjCMethodCall(const ObjCMessageExpr *Msg, ProgramStateRef St,
-                 const LocationContext *LCtx)
-    : CallEvent(Msg, St, LCtx, CE_ObjCMessage) {
-    Data = 0;
-  }
-
-  const ObjCMessageExpr *getOriginExpr() const {
-    return cast<ObjCMessageExpr>(CallEvent::getOriginExpr());
-  }
-  const ObjCMethodDecl *getDecl() const {
-    return getOriginExpr()->getMethodDecl();
-  }
-  unsigned getNumArgs() const {
-    return getOriginExpr()->getNumArgs();
-  }
-  const Expr *getArgExpr(unsigned Index) const {
-    return getOriginExpr()->getArg(Index);
-  }
-
-  bool isInstanceMessage() const {
-    return getOriginExpr()->isInstanceMessage();
-  }
-  ObjCMethodFamily getMethodFamily() const {
-    return getOriginExpr()->getMethodFamily();
-  }
-  Selector getSelector() const {
-    return getOriginExpr()->getSelector();
-  }
-
-  SourceRange getSourceRange() const;
-
-  /// \brief Returns the value of the receiver at the time of this call.
-  SVal getReceiverSVal() const;
-
-  /// \brief Get the interface for the receiver.
-  ///
-  /// This works whether this is an instance message or a class message.
-  /// However, it currently just uses the static type of the receiver.
-  const ObjCInterfaceDecl *getReceiverInterface() const {
-    return getOriginExpr()->getReceiverInterface();
-  }
-
-  ObjCMessageKind getMessageKind() const;
-
-  bool isSetter() const {
-    switch (getMessageKind()) {
-    case OCM_Message:
-      llvm_unreachable("This is not a pseudo-object access!");
-    case OCM_PropertyAccess:
-      return getNumArgs() > 0;
-    case OCM_Subscript:
-      return getNumArgs() > 1;
-    }
-    llvm_unreachable("Unknown message kind");
-  }
-
-  const Decl *getDefinition(bool &IsDynamicDispatch) const {
-    IsDynamicDispatch = true;
-    
-    const ObjCMethodDecl *MD = getDecl();
-    if (!MD)
-      return 0;
-
-    for (Decl::redecl_iterator I = MD->redecls_begin(), E = MD->redecls_end();
-         I != E; ++I) {
-      if (cast<ObjCMethodDecl>(*I)->isThisDeclarationADefinition())
-        return *I;
-    }
-    return 0;
-  }
-
-  SVal getCXXThisVal() const { return UndefinedVal(); }
-
-  bool argumentsMayEscape() const {
-    return hasNonZeroCallbackArg();
-  }
-  
-  SVal getArgSVal(unsigned Index) const { return getSVal(getArgExpr(Index)); }
-  SourceRange getArgSourceRange(unsigned Index) const {
-    return getArgExpr(Index)->getSourceRange();
-  }
-
-  param_iterator param_begin(bool UseDefinitionParams = false) const;
-  param_iterator param_end(bool UseDefinitionParams = false) const;
-
-  static bool classof(const CallEvent *CA) {
-    return CA->getKind() == CE_ObjCMessage;
-  }
-};
-
-
-// FIXME: Use a .def or .td file for this.
-#define DISPATCH(fn) \
-  switch (getKind()) { \
-  case CE_Function: \
-    return cast<FunctionCall>(this)->fn(); \
-  case CE_CXXMember: \
-    return cast<CXXMemberCall>(this)->fn(); \
-  case CE_CXXMemberOperator: \
-    return cast<CXXMemberOperatorCall>(this)->fn(); \
-  case CE_Block: \
-    return cast<BlockCall>(this)->fn(); \
-  case CE_CXXConstructor: \
-    return cast<CXXConstructorCall>(this)->fn(); \
-  case CE_CXXDestructor: \
-    return cast<CXXDestructorCall>(this)->fn(); \
-  case CE_CXXAllocator: \
-    return cast<CXXAllocatorCall>(this)->fn(); \
-  case CE_ObjCMessage: \
-    return cast<ObjCMethodCall>(this)->fn(); \
-  } \
-  llvm_unreachable("unknown CallEvent kind");
-
-#define DISPATCH_ARG(fn, arg) \
-  switch (getKind()) { \
-  case CE_Function: \
-    return cast<FunctionCall>(this)->fn(arg); \
-  case CE_CXXMember: \
-    return cast<CXXMemberCall>(this)->fn(arg); \
-  case CE_CXXMemberOperator: \
-    return cast<CXXMemberOperatorCall>(this)->fn(arg); \
-  case CE_Block: \
-    return cast<BlockCall>(this)->fn(arg); \
-  case CE_CXXConstructor: \
-    return cast<CXXConstructorCall>(this)->fn(arg); \
-  case CE_CXXDestructor: \
-    return cast<CXXDestructorCall>(this)->fn(arg); \
-  case CE_CXXAllocator: \
-    return cast<CXXAllocatorCall>(this)->fn(arg); \
-  case CE_ObjCMessage: \
-    return cast<ObjCMethodCall>(this)->fn(arg); \
-  } \
-  llvm_unreachable("unknown CallEvent kind");
-
-inline void CallEvent::getExtraInvalidatedRegions(RegionList &Regions) const {
-  DISPATCH_ARG(getExtraInvalidatedRegions, Regions);
-}
-
-inline QualType CallEvent::getDeclaredResultType() const {
-  DISPATCH(getDeclaredResultType);
-}
-
-inline const Decl *CallEvent::getDecl() const {
-  if (const Decl *D = Origin.dyn_cast<const Decl *>())
-    return D;
-  DISPATCH(getDecl);
-}
-
-inline const Decl *CallEvent::getDefinition(bool &IsDynamicDispatch) const {
-  DISPATCH_ARG(getDefinition, IsDynamicDispatch);
-}
-
-inline unsigned CallEvent::getNumArgs() const {
-  DISPATCH(getNumArgs);
-}
-
-inline SourceRange CallEvent::getSourceRange() const {
-  DISPATCH(getSourceRange);
-}
-
-inline SVal CallEvent::getArgSVal(unsigned Index) const {
-  DISPATCH_ARG(getArgSVal, Index);
-}
-
-inline const Expr *CallEvent::getArgExpr(unsigned Index) const {
-  DISPATCH_ARG(getArgExpr, Index);
-}
-
-inline SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
-  DISPATCH_ARG(getArgSourceRange, Index);
-}
-
-inline SVal CallEvent::getCXXThisVal() const {
-  DISPATCH(getCXXThisVal);
-}
-
-
-inline bool CallEvent::argumentsMayEscape() const {
-  DISPATCH(argumentsMayEscape);
-}
-
-inline CallEvent::param_iterator
-CallEvent::param_begin(bool UseDefinitionParams) const {
-  DISPATCH_ARG(param_begin, UseDefinitionParams);
-}
-
-inline CallEvent::param_iterator
-CallEvent::param_end(bool UseDefinitionParams) const {
-  DISPATCH_ARG(param_end, UseDefinitionParams);
-}
-
-#undef DISPATCH
-#undef DISPATCH_ARG
-
-} // end namespace ento
-} // end namespace clang
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index b051d33..95974d1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -92,6 +92,10 @@
     return Pred->getLocationContext();
   }
 
+  const StackFrameContext *getStackFrame() const {
+    return Pred->getStackFrame();
+  }
+
   BugReporter &getBugReporter() {
     return Eng.getBugReporter();
   }
@@ -132,23 +136,23 @@
     return 0;
   }
 
+  /// \brief Get the value of arbitrary expressions at this point in the path.
+  SVal getSVal(const Stmt *S) const {
+    return getState()->getSVal(S, getLocationContext());
+  }
+
   /// \brief Generates a new transition in the program state graph
   /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
   ///
-  /// @param State The state of the generated node.
+  /// @param State The state of the generated node. If not specified, the state
+  ///        will not be changed, but the new node will have the checker's tag.
   /// @param Tag The tag is used to uniquely identify the creation site. If no
   ///        tag is specified, a default tag, unique to the given checker,
   ///        will be used. Tags are used to prevent states generated at
   ///        different sites from caching out.
-  ExplodedNode *addTransition(ProgramStateRef State,
+  ExplodedNode *addTransition(ProgramStateRef State = 0,
                               const ProgramPointTag *Tag = 0) {
-    return addTransitionImpl(State, false, 0, Tag);
-  }
-
-  /// \brief Generates a default transition (containing checker tag but no
-  /// checker state changes).
-  ExplodedNode *addTransition() {
-    return addTransition(getState());
+    return addTransitionImpl(State ? State : getState(), false, 0, Tag);
   }
 
   /// \brief Generates a new transition with the given predecessor.
@@ -161,16 +165,17 @@
   /// @param IsSink Mark the new node as sink, which will stop exploration of
   ///               the given path.
   ExplodedNode *addTransition(ProgramStateRef State,
-                             ExplodedNode *Pred,
-                             const ProgramPointTag *Tag = 0,
-                             bool IsSink = false) {
-    return addTransitionImpl(State, IsSink, Pred, Tag);
+                              ExplodedNode *Pred,
+                              const ProgramPointTag *Tag = 0) {
+    return addTransitionImpl(State, false, Pred, Tag);
   }
 
-  /// \brief Generate a sink node. Generating sink stops exploration of the
+  /// \brief Generate a sink node. Generating a sink stops exploration of the
   /// given path.
-  ExplodedNode *generateSink(ProgramStateRef state = 0) {
-    return addTransitionImpl(state ? state : getState(), true);
+  ExplodedNode *generateSink(ProgramStateRef State = 0,
+                             ExplodedNode *Pred = 0,
+                             const ProgramPointTag *Tag = 0) {
+    return addTransitionImpl(State ? State : getState(), true, Pred, Tag);
   }
 
   /// \brief Emit the diagnostics report.
@@ -217,9 +222,15 @@
       return Pred;
 
     Changed = true;
-    ExplodedNode *node = NB.generateNode(Tag ? Location.withTag(Tag) : Location,
-                                        State,
-                                        P ? P : Pred, MarkAsSink);
+    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
+    if (!P)
+      P = Pred;
+
+    ExplodedNode *node;
+    if (MarkAsSink)
+      node = NB.generateSink(LocalLoc, State, P);
+    else
+      node = NB.generateNode(LocalLoc, State, P);
     return node;
   }
 };
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index e75cdd8..16bd45c 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -265,14 +265,21 @@
   virtual ~NodeBuilder() {}
 
   /// \brief Generates a node in the ExplodedGraph.
-  ///
-  /// When a node is marked as sink, the exploration from the node is stopped -
-  /// the node becomes the last node on the path.
   ExplodedNode *generateNode(const ProgramPoint &PP,
                              ProgramStateRef State,
-                             ExplodedNode *Pred,
-                             bool MarkAsSink = false) {
-    return generateNodeImpl(PP, State, Pred, MarkAsSink);
+                             ExplodedNode *Pred) {
+    return generateNodeImpl(PP, State, Pred, false);
+  }
+
+  /// \brief Generates a sink in the ExplodedGraph.
+  ///
+  /// When a node is marked as sink, the exploration from the node is stopped -
+  /// the node becomes the last node on the path and certain kinds of bugs are
+  /// suppressed.
+  ExplodedNode *generateSink(const ProgramPoint &PP,
+                             ProgramStateRef State,
+                             ExplodedNode *Pred) {
+    return generateNodeImpl(PP, State, Pred, true);
   }
 
   const ExplodedNodeSet &getResults() {
@@ -317,13 +324,18 @@
   NodeBuilderWithSinks(ExplodedNode *Pred, ExplodedNodeSet &DstSet,
                        const NodeBuilderContext &Ctx, ProgramPoint &L)
     : NodeBuilder(Pred, DstSet, Ctx), Location(L) {}
+
   ExplodedNode *generateNode(ProgramStateRef State,
                              ExplodedNode *Pred,
-                             const ProgramPointTag *Tag = 0,
-                             bool MarkAsSink = false) {
-    ProgramPoint LocalLoc = (Tag ? Location.withTag(Tag): Location);
+                             const ProgramPointTag *Tag = 0) {
+    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
+    return NodeBuilder::generateNode(LocalLoc, State, Pred);
+  }
 
-    ExplodedNode *N = generateNodeImpl(LocalLoc, State, Pred, MarkAsSink);
+  ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred,
+                             const ProgramPointTag *Tag = 0) {
+    const ProgramPoint &LocalLoc = (Tag ? Location.withTag(Tag) : Location);
+    ExplodedNode *N = NodeBuilder::generateSink(LocalLoc, State, Pred);
     if (N && N->isSink())
       sinksGenerated.push_back(N);
     return N;
@@ -336,7 +348,7 @@
 
 /// \class StmtNodeBuilder
 /// \brief This builder class is useful for generating nodes that resulted from
-/// visiting a statement. The main difference from it's parent NodeBuilder is
+/// visiting a statement. The main difference from its parent NodeBuilder is
 /// that it creates a statement specific ProgramPoint.
 class StmtNodeBuilder: public NodeBuilder {
   NodeBuilder *EnclosingBldr;
@@ -363,22 +375,27 @@
 
   virtual ~StmtNodeBuilder();
 
+  using NodeBuilder::generateNode;
+  using NodeBuilder::generateSink;
+
   ExplodedNode *generateNode(const Stmt *S,
                              ExplodedNode *Pred,
                              ProgramStateRef St,
-                             bool MarkAsSink = false,
                              const ProgramPointTag *tag = 0,
                              ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
     const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                   Pred->getLocationContext(), tag);
-    return generateNodeImpl(L, St, Pred, MarkAsSink);
+    return NodeBuilder::generateNode(L, St, Pred);
   }
 
-  ExplodedNode *generateNode(const ProgramPoint &PP,
+  ExplodedNode *generateSink(const Stmt *S,
                              ExplodedNode *Pred,
-                             ProgramStateRef State,
-                             bool MarkAsSink = false) {
-    return generateNodeImpl(PP, State, Pred, MarkAsSink);
+                             ProgramStateRef St,
+                             const ProgramPointTag *tag = 0,
+                             ProgramPoint::Kind K = ProgramPoint::PostStmtKind){
+    const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
+                                  Pred->getLocationContext(), tag);
+    return NodeBuilder::generateSink(L, St, Pred);
   }
 };
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index 40969d3..5ce219b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -60,45 +60,50 @@
   friend class SwitchNodeBuilder;
   friend class EndOfFunctionNodeBuilder;
 
+  /// Efficiently stores a list of ExplodedNodes, or an optional flag.
+  ///
+  /// NodeGroup provides opaque storage for a list of ExplodedNodes, optimizing
+  /// for the case when there is only one node in the group. This is a fairly
+  /// common case in an ExplodedGraph, where most nodes have only one
+  /// predecessor and many have only one successor. It can also be used to
+  /// store a flag rather than a node list, which ExplodedNode uses to mark
+  /// whether a node is a sink. If the flag is set, the group is implicitly
+  /// empty and no nodes may be added.
   class NodeGroup {
-    enum { Size1 = 0x0, SizeOther = 0x1, AuxFlag = 0x2, Mask = 0x3 };
+    // Conceptually a discriminated union. If the low bit is set, the node is
+    // a sink. If the low bit is not set, the pointer refers to the storage
+    // for the nodes in the group.
+    // This is not a PointerIntPair in order to keep the storage type opaque.
     uintptr_t P;
-
-    unsigned getKind() const {
-      return P & 0x1;
-    }
-
-    void *getPtr() const {
-      assert (!getFlag());
-      return reinterpret_cast<void*>(P & ~Mask);
-    }
-
-    ExplodedNode *getNode() const {
-      return reinterpret_cast<ExplodedNode*>(getPtr());
-    }
     
   public:
-    NodeGroup() : P(0) {}
+    NodeGroup(bool Flag = false) : P(Flag) {
+      assert(getFlag() == Flag);
+    }
 
-    ExplodedNode **begin() const;
+    ExplodedNode * const *begin() const;
 
-    ExplodedNode **end() const;
+    ExplodedNode * const *end() const;
 
     unsigned size() const;
 
-    bool empty() const { return (P & ~Mask) == 0; }
+    bool empty() const { return P == 0 || getFlag() != 0; }
 
+    /// Adds a node to the list.
+    ///
+    /// The group must not have been created with its flag set.
     void addNode(ExplodedNode *N, ExplodedGraph &G);
 
+    /// Replaces the single node in this group with a new node.
+    ///
+    /// Note that this should only be used when you know the group was not
+    /// created with its flag set, and that the group is empty or contains
+    /// only a single node.
     void replaceNode(ExplodedNode *node);
 
-    void setFlag() {
-      assert(P == 0);
-      P = AuxFlag;
-    }
-
+    /// Returns whether this group was created with its flag set.
     bool getFlag() const {
-      return P & AuxFlag ? true : false;
+      return (P & 1);
     }
   };
 
@@ -119,9 +124,8 @@
 
   explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state,
                         bool IsSink)
-    : Location(loc), State(state) {
-    if (IsSink)
-      Succs.setFlag();
+    : Location(loc), State(state), Succs(IsSink) {
+    assert(isSink() == IsSink);
   }
   
   ~ExplodedNode() {}
@@ -133,6 +137,10 @@
     return getLocation().getLocationContext();
   }
 
+  const StackFrameContext *getStackFrame() const {
+    return getLocationContext()->getCurrentStackFrame();
+  }
+
   const Decl &getCodeDecl() const { return *getLocationContext()->getDecl(); }
 
   CFG &getCFG() const { return *getLocationContext()->getCFG(); }
@@ -186,9 +194,9 @@
   }
 
   // Iterators over successor and predecessor vertices.
-  typedef ExplodedNode**       succ_iterator;
+  typedef ExplodedNode*       const *       succ_iterator;
   typedef const ExplodedNode* const * const_succ_iterator;
-  typedef ExplodedNode**       pred_iterator;
+  typedef ExplodedNode*       const *       pred_iterator;
   typedef const ExplodedNode* const * const_pred_iterator;
 
   pred_iterator pred_begin() { return Preds.begin(); }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index eeb4c57..4addb9d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -43,7 +43,6 @@
 class AnalysisManager;
 class CallEvent;
 class SimpleCall;
-class ObjCMethodCall;
 
 class ExprEngine : public SubEngine {
   AnalysisManager &AMgr;
@@ -348,7 +347,7 @@
   void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, 
                                   ExplodedNode *Pred, ExplodedNodeSet &Dst);
 
-  void VisitObjCMessage(const ObjCMethodCall &Msg, ExplodedNode *Pred,
+  void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred,
                         ExplodedNodeSet &Dst);
 
   /// VisitReturnStmt - Transfer function logic for return statements.
@@ -378,10 +377,10 @@
   void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, 
                         ExplodedNodeSet & Dst);
 
-  void VisitCXXConstructExpr(const CXXConstructExpr *E, const MemRegion *Dest,
-                             ExplodedNode *Pred, ExplodedNodeSet &Dst);
+  void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred,
+                             ExplodedNodeSet &Dst);
 
-  void VisitCXXDestructor(const CXXDestructorDecl *DD,
+  void VisitCXXDestructor(QualType ObjectType,
                           const MemRegion *Dest, const Stmt *S,
                           ExplodedNode *Pred, ExplodedNodeSet &Dst);
 
@@ -431,15 +430,6 @@
   }
   
 protected:
-  void evalObjCMessage(StmtNodeBuilder &Bldr, const ObjCMethodCall &Msg,
-                       ExplodedNode *Pred, ProgramStateRef state,
-                       bool GenSink);
-
-  ProgramStateRef MarkBranch(ProgramStateRef state,
-                                 const Stmt *Terminator,
-                                 const LocationContext *LCtx,
-                                 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, const Stmt *StoreE, ExplodedNode *Pred,
@@ -473,10 +463,12 @@
                                   const LocationContext *LCtx,
                                   ProgramStateRef State);
 
+  /// Evaluate a call, running pre- and post-call checks and allowing checkers
+  /// to be responsible for handling the evaluation of the call itself.
   void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
-                const SimpleCall &Call);
+                const CallEvent &Call);
 
-  /// \bried Default implementation of call evaluation.
+  /// \brief Default implementation of call evaluation.
   void defaultEvalCall(NodeBuilder &B, ExplodedNode *Pred,
                        const CallEvent &Call);
 private:
@@ -499,7 +491,19 @@
                     const ProgramPointTag *tag, bool isLoad);
 
   bool shouldInlineDecl(const Decl *D, ExplodedNode *Pred);
-  bool inlineCall(const CallEvent &Call, ExplodedNode *Pred);
+  bool inlineCall(const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
+                  ExplodedNode *Pred, ProgramStateRef State);
+
+  /// \brief Conservatively evaluate call by invalidating regions and binding
+  /// a conjured return value.
+  void conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
+                            ExplodedNode *Pred, ProgramStateRef State);
+
+  /// \brief Either inline or process the call conservatively (or both), based
+  /// on DynamicDispatchBifurcation data.
+  void BifurcateCall(const MemRegion *BifurReg,
+                     const CallEvent &Call, const Decl *D, NodeBuilder &Bldr,
+                     ExplodedNode *Pred);
 
   bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
 };
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 2e922c0..df8fb43 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -52,11 +52,23 @@
   int64_t Offset;
 
 public:
-  RegionOffset(const MemRegion *r) : R(r), Offset(0) {}
+  // We're using a const instead of an enumeration due to the size required;
+  // Visual Studio will only create enumerations of size int, not long long.
+  static const int64_t Symbolic = INT64_MAX;
+
+  RegionOffset() : R(0) {}
   RegionOffset(const MemRegion *r, int64_t off) : R(r), Offset(off) {}
 
   const MemRegion *getRegion() const { return R; }
-  int64_t getOffset() const { return Offset; }
+
+  bool hasSymbolicOffset() const { return Offset == Symbolic; }
+
+  int64_t getOffset() const {
+    assert(!hasSymbolicOffset());
+    return Offset;
+  }
+
+  bool isValid() const { return R; }
 };
 
 //===----------------------------------------------------------------------===//
@@ -87,11 +99,11 @@
     // Untyped regions.
     SymbolicRegionKind,
     AllocaRegionKind,
-    BlockDataRegionKind,
     // Typed regions.
     BEG_TYPED_REGIONS,
     FunctionTextRegionKind = BEG_TYPED_REGIONS,
     BlockTextRegionKind,
+    BlockDataRegionKind,
     BEG_TYPED_VALUE_REGIONS,
     CompoundLiteralRegionKind = BEG_TYPED_VALUE_REGIONS,
     CXXThisRegionKind,
@@ -128,7 +140,7 @@
 
   const MemRegion *getBaseRegion() const;
 
-  const MemRegion *StripCasts() const;
+  const MemRegion *StripCasts(bool StripBaseCasts = true) const;
 
   bool hasGlobalsOrParametersStorage() const;
 
@@ -148,8 +160,11 @@
 
   void dump() const;
 
+  /// \brief Returns true if this region can be printed in a user-friendly way.
+  virtual bool canPrintPretty() const;
+
   /// \brief Print the region for use in diagnostics.
-  virtual void dumpPretty(raw_ostream &os) const;
+  virtual void printPretty(raw_ostream &os) const;
 
   Kind getKind() const { return kind; }
 
@@ -490,6 +505,8 @@
     return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T;
   }
 
+  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
+
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
     return k >= BEG_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS;
@@ -586,7 +603,7 @@
 ///  which correspond to "code+data".  The distinction is important, because
 ///  like a closure a block captures the values of externally referenced
 ///  variables.
-class BlockDataRegion : public SubRegion {
+class BlockDataRegion : public TypedRegion {
   friend class MemRegionManager;
   const BlockTextRegion *BC;
   const LocationContext *LC; // Can be null */
@@ -595,13 +612,15 @@
 
   BlockDataRegion(const BlockTextRegion *bc, const LocationContext *lc,
                   const MemRegion *sreg)
-  : SubRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
+  : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
     ReferencedVars(0), OriginalVars(0) {}
 
 public:
   const BlockTextRegion *getCodeRegion() const { return BC; }
   
   const BlockDecl *getDecl() const { return BC->getDecl(); }
+
+  QualType getLocationType() const { return BC->getLocationType(); }
   
   class referenced_vars_iterator {
     const MemRegion * const *R;
@@ -806,8 +825,6 @@
   const Decl *getDecl() const { return D; }
   void Profile(llvm::FoldingSetNodeID& ID) const;
 
-  DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const;
-
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
     return k >= BEG_DECL_REGIONS && k <= END_DECL_REGIONS;
@@ -844,7 +861,8 @@
     return R->getKind() == VarRegionKind;
   }
 
-  void dumpPretty(raw_ostream &os) const;
+  bool canPrintPretty() const;
+  void printPretty(raw_ostream &os) const;
 };
   
 /// CXXThisRegion - Represents the region for the implicit 'this' parameter
@@ -903,7 +921,9 @@
   }
 
   void dumpToStream(raw_ostream &os) const;
-  void dumpPretty(raw_ostream &os) const;
+
+  bool canPrintPretty() const;
+  void printPretty(raw_ostream &os) const;
 };
 
 class ObjCIvarRegion : public DeclRegion {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index fd5f437..b0c51dd 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -36,6 +36,7 @@
 namespace ento {
 
 class CallEvent;
+class CallEventManager;
 
 typedef ConstraintManager* (*ConstraintManagerCreator)(ProgramStateManager&,
                                                        SubEngine&);
@@ -55,6 +56,32 @@
   }
 };
 
+/// \class Stores the dynamic type information.
+/// Information about type of an object at runtime. This is used by dynamic
+/// dispatch implementation.
+class DynamicTypeInfo {
+  QualType T;
+  bool CanBeASubClass;
+
+public:
+  DynamicTypeInfo() : T(QualType()) {}
+  DynamicTypeInfo(QualType WithType, bool CanBeSub = true)
+    : T(WithType), CanBeASubClass(CanBeSub) {}
+
+  bool isValid() const { return !T.isNull(); }
+
+  QualType getType() const { return T; }
+  bool canBeASubClass() const { return CanBeASubClass; }
+  
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    T.Profile(ID);
+    ID.AddInteger((unsigned)CanBeASubClass);
+  }
+  bool operator==(const DynamicTypeInfo &X) const {
+    return T == X.T && CanBeASubClass == X.CanBeASubClass;
+  }
+};
+
 /// \class ProgramState
 /// ProgramState - This class encapsulates:
 ///
@@ -238,6 +265,9 @@
   /// Get the lvalue for a field reference.
   SVal getLValue(const FieldDecl *decl, SVal Base) const;
 
+  /// Get the lvalue for an indirect field reference.
+  SVal getLValue(const IndirectFieldDecl *decl, SVal Base) const;
+
   /// Get the lvalue for an array index.
   SVal getLValue(QualType ElementType, SVal Idx, SVal Base) const;
 
@@ -309,6 +339,20 @@
   bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const;
   bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const;
 
+  /// \brief Get dynamic type information for a region.
+  DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const;
+
+  /// \brief Set dynamic type information of the region; return the new state.
+  ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg,
+                                     DynamicTypeInfo NewTy) const;
+
+  /// \brief Set dynamic type information of the region; return the new state.
+  ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg,
+                                     QualType NewTy,
+                                     bool CanBeSubClassed = true) const {
+    return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed));
+  }
+
   //==---------------------------------------------------------------------==//
   // Accessing the Generic Data Map (GDM).
   //==---------------------------------------------------------------------==//
@@ -411,6 +455,9 @@
   /// Object that manages the data for all created SVals.
   OwningPtr<SValBuilder> svalBuilder;
 
+  /// Manages memory for created CallEvents.
+  OwningPtr<CallEventManager> CallEventMgr;
+
   /// A BumpPtrAllocator to allocate states.
   llvm::BumpPtrAllocator &Alloc;
   
@@ -422,28 +469,7 @@
                  StoreManagerCreator CreateStoreManager,
                  ConstraintManagerCreator CreateConstraintManager,
                  llvm::BumpPtrAllocator& alloc,
-                 SubEngine &subeng)
-    : Eng(&subeng),
-      EnvMgr(alloc),
-      GDMFactory(alloc),
-      svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
-      Alloc(alloc) {
-    StoreMgr.reset((*CreateStoreManager)(*this));
-    ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng));
-  }
-
-  ProgramStateManager(ASTContext &Ctx,
-                 StoreManagerCreator CreateStoreManager,
-                 ConstraintManager* ConstraintManagerPtr,
-                 llvm::BumpPtrAllocator& alloc)
-    : Eng(0),
-      EnvMgr(alloc),
-      GDMFactory(alloc),
-      svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
-      Alloc(alloc) {
-    StoreMgr.reset((*CreateStoreManager)(*this));
-    ConstraintMgr.reset(ConstraintManagerPtr);
-  }
+                 SubEngine &subeng);
 
   ~ProgramStateManager();
 
@@ -479,6 +505,8 @@
     return svalBuilder->getRegionManager();
   }
 
+  CallEventManager &getCallEventManager() { return *CallEventMgr; }
+
   StoreManager& getStoreManager() { return *StoreMgr; }
   ConstraintManager& getConstraintManager() { return *ConstraintMgr; }
   SubEngine* getOwningEngine() { return Eng; }
@@ -649,6 +677,18 @@
   return getStateManager().StoreMgr->getLValueField(D, Base);
 }
 
+inline SVal ProgramState::getLValue(const IndirectFieldDecl *D,
+                                    SVal Base) const {
+  StoreManager &SM = *getStateManager().StoreMgr;
+  for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
+                                         E = D->chain_end();
+       I != E; ++I) {
+    Base = SM.getLValueField(cast<FieldDecl>(*I), Base);
+  }
+
+  return Base;
+}
+
 inline SVal ProgramState::getLValue(QualType ElementType, SVal Idx, SVal Base) const{
   if (NonLoc *N = dyn_cast<NonLoc>(&Idx))
     return getStateManager().StoreMgr->getLValueElement(ElementType, *N, Base);
@@ -764,14 +804,12 @@
 /// \class ScanReachableSymbols
 /// A Utility class that allows to visit the reachable symbols using a custom
 /// SymbolVisitor.
-class ScanReachableSymbols : public SubRegionMap::Visitor  {
-  virtual void anchor();
+class ScanReachableSymbols {
   typedef llvm::DenseMap<const void*, unsigned> VisitedItems;
 
   VisitedItems visited;
   ProgramStateRef state;
   SymbolVisitor &visitor;
-  OwningPtr<SubRegionMap> SRM;
 public:
 
   ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v)
@@ -781,11 +819,6 @@
   bool scan(SVal val);
   bool scan(const MemRegion *R);
   bool scan(const SymExpr *sym);
-
-  // From SubRegionMap::Visitor.
-  bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) {
-    return scan(SubRegion);
-  }
 };
 
 } // end GR namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index e495d15..e0b5f64 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -163,13 +163,10 @@
 class UndefinedVal : public SVal {
 public:
   UndefinedVal() : SVal(UndefinedKind) {}
-  UndefinedVal(const void *D) : SVal(UndefinedKind, D) {}
 
   static inline bool classof(const SVal* V) {
     return V->getBaseKind() == UndefinedKind;
   }
-
-  const void *getData() const { return Data; }
 };
 
 class DefinedOrUnknownSVal : public SVal {
@@ -436,7 +433,7 @@
   }
 
   /// \brief Get the underlining region and strip casts.
-  const MemRegion* stripCasts() const;
+  const MemRegion* stripCasts(bool StripBaseCasts = true) const;
 
   template <typename REGION>
   const REGION* getRegionAs() const {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 8283472..138a590 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -32,7 +32,7 @@
 class CallEvent;
 class ProgramState;
 class ProgramStateManager;
-class SubRegionMap;
+class ScanReachableSymbols;
 
 class StoreManager {
 protected:
@@ -85,11 +85,6 @@
   ///  used to query and manipulate MemRegion objects.
   MemRegionManager& getRegionManager() { return MRMgr; }
 
-  /// getSubRegionMap - Returns an opaque map object that clients can query
-  ///  to get the subregions of a given MemRegion object.  It is the
-  //   caller's responsibility to 'delete' the returned map.
-  virtual SubRegionMap *getSubRegionMap(Store store) = 0;
-
   virtual Loc getLValueVar(const VarDecl *VD, const LocationContext *LC) {
     return svalBuilder.makeLoc(MRMgr.getVarRegion(VD, LC));
   }
@@ -120,7 +115,10 @@
   virtual SVal ArrayToPointer(Loc Array) = 0;
 
   /// Evaluates DerivedToBase casts.
-  virtual SVal evalDerivedToBase(SVal derived, QualType basePtrType) = 0;
+  SVal evalDerivedToBase(SVal derived, const CastExpr *Cast);
+
+  /// Evaluates a derived-to-base cast through a single level of derivation.
+  virtual SVal evalDerivedToBase(SVal derived, QualType derivedPtrType) = 0;
 
   /// \brief Evaluates C++ dynamic_cast cast.
   /// The callback may result in the following 3 scenarios:
@@ -133,15 +131,6 @@
   virtual SVal evalDynamicCast(SVal base, QualType derivedPtrType,
                                  bool &Failed) = 0;
 
-  class CastResult {
-    ProgramStateRef state;
-    const MemRegion *region;
-  public:
-    ProgramStateRef getState() const { return state; }
-    const MemRegion* getRegion() const { return region; }
-    CastResult(ProgramStateRef s, const MemRegion* r = 0) : state(s), region(r){}
-  };
-
   const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
 
   /// castRegion - Used by ExprEngine::VisitCast to handle casts from
@@ -203,6 +192,12 @@
                            const CallEvent &Call,
                            const StackFrameContext *CalleeCtx);
 
+  /// Finds the transitive closure of symbols within the given region.
+  ///
+  /// Returns false if the visitor aborted the scan.
+  virtual bool scanReachableSymbols(Store S, const MemRegion *R,
+                                    ScanReachableSymbols &Visitor) = 0;
+
   virtual void print(Store store, raw_ostream &Out,
                      const char* nl, const char *sep) = 0;
 
@@ -274,24 +269,6 @@
   return *this;
 }
 
-// FIXME: Do we still need this?
-/// SubRegionMap - An abstract interface that represents a queryable map
-///  between MemRegion objects and their subregions.
-class SubRegionMap {
-  virtual void anchor();
-public:
-  virtual ~SubRegionMap() {}
-
-  class Visitor {
-    virtual void anchor();
-  public:
-    virtual ~Visitor() {}
-    virtual bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) = 0;
-  };
-
-  virtual bool iterSubRegions(const MemRegion *region, Visitor& V) const = 0;
-};
-
 // FIXME: Do we need to pass ProgramStateManager anymore?
 StoreManager *CreateRegionStoreManager(ProgramStateManager& StMgr);
 StoreManager *CreateFieldsOnlyRegionStoreManager(ProgramStateManager& StMgr);
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index dd9461b..14e13ba 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -91,11 +91,40 @@
 
 class CaptureDiagnosticConsumer : public DiagnosticConsumer {
   DiagnosticsEngine &Diags;
+  DiagnosticConsumer &DiagClient;
   CapturedDiagList &CapturedDiags;
+  bool HasBegunSourceFile;
 public:
   CaptureDiagnosticConsumer(DiagnosticsEngine &diags,
-                           CapturedDiagList &capturedDiags)
-    : Diags(diags), CapturedDiags(capturedDiags) { }
+                            DiagnosticConsumer &client,
+                            CapturedDiagList &capturedDiags)
+    : Diags(diags), DiagClient(client), CapturedDiags(capturedDiags),
+      HasBegunSourceFile(false) { }
+
+  virtual void BeginSourceFile(const LangOptions &Opts,
+                               const Preprocessor *PP) {
+    // Pass BeginSourceFile message onto DiagClient on first call.
+    // The corresponding EndSourceFile call will be made from an
+    // explicit call to FinishCapture.
+    if (!HasBegunSourceFile) {
+      DiagClient.BeginSourceFile(Opts, PP);
+      HasBegunSourceFile = true;
+    }
+  }
+
+  void FinishCapture() {
+    // Call EndSourceFile on DiagClient on completion of capture to
+    // enable VerifyDiagnosticConsumer to check diagnostics *after*
+    // it has received the diagnostic list.
+    if (HasBegunSourceFile) {
+      DiagClient.EndSourceFile();
+      HasBegunSourceFile = false;
+    }
+  }
+
+  virtual ~CaptureDiagnosticConsumer() {
+    assert(!HasBegunSourceFile && "FinishCapture not called!");
+  }
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
                                 const Diagnostic &Info) {
@@ -208,7 +237,7 @@
   WarnOpts.push_back("error=arc-unsafe-retained-assign");
   CInvok->getDiagnosticOpts().Warnings = llvm_move(WarnOpts);
 
-  CInvok->getLangOpts()->ObjCRuntimeHasWeak = HasARCRuntime(origCI);
+  CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI);
 
   return CInvok.take();
 }
@@ -260,13 +289,15 @@
       new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
 
   // Filter of all diagnostics.
-  CaptureDiagnosticConsumer errRec(*Diags, capturedDiags);
+  CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
   Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
 
   OwningPtr<ASTUnit> Unit(
       ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags));
-  if (!Unit)
+  if (!Unit) {
+    errRec.FinishCapture();
     return true;
+  }
 
   // Don't filter diagnostics anymore.
   Diags->setClient(DiagClient, /*ShouldOwnClient=*/false);
@@ -278,6 +309,7 @@
     DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
     capturedDiags.reportDiagnostics(*Diags);
     DiagClient->EndSourceFile();
+    errRec.FinishCapture();
     return true;
   }
 
@@ -315,6 +347,7 @@
   capturedDiags.reportDiagnostics(*Diags);
 
   DiagClient->EndSourceFile();
+  errRec.FinishCapture();
 
   // If we are migrating code that gets the '-fobjc-arc' flag, make sure
   // to remove it so that we don't get errors from normal compilation.
@@ -563,7 +596,7 @@
       new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
 
   // Filter of all diagnostics.
-  CaptureDiagnosticConsumer errRec(*Diags, capturedDiags);
+  CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
   Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
 
   OwningPtr<ARCMTMacroTrackerAction> ASTAction;
@@ -572,8 +605,10 @@
   OwningPtr<ASTUnit> Unit(
       ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags,
                                                 ASTAction.get()));
-  if (!Unit)
+  if (!Unit) {
+    errRec.FinishCapture();
     return true;
+  }
   Unit->setOwnsRemappedFileBuffers(false); // FileRemapper manages that.
 
   // Don't filter diagnostics anymore.
@@ -586,6 +621,7 @@
     DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
     capturedDiags.reportDiagnostics(*Diags);
     DiagClient->EndSourceFile();
+    errRec.FinishCapture();
     return true;
   }
 
@@ -609,6 +645,7 @@
   }
 
   DiagClient->EndSourceFile();
+  errRec.FinishCapture();
 
   if (DiagClient->getNumErrors())
     return true;
diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt
index 2cce53d..f602fc8 100644
--- a/lib/ARCMigrate/CMakeLists.txt
+++ b/lib/ARCMigrate/CMakeLists.txt
@@ -23,9 +23,14 @@
 add_dependencies(clangARCMigrate
   ClangAttrClasses
   ClangAttrList
+  ClangAttrParsedAttrList
   ClangCommentNodes
   ClangDeclNodes
-  ClangStmtNodes)
+  ClangDiagnosticCommon
+  ClangDiagnosticGroups
+  ClangDiagnosticSema
+  ClangStmtNodes
+  )
 
 target_link_libraries(clangARCMigrate
   clangBasic
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 1175c36..f01dfa9 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -40,7 +40,7 @@
 
 bool trans::canApplyWeak(ASTContext &Ctx, QualType type,
                          bool AllowOnUnknownClass) {
-  if (!Ctx.getLangOpts().ObjCRuntimeHasWeak)
+  if (!Ctx.getLangOpts().ObjCARCWeak)
     return false;
 
   QualType T = type;
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index a74ef14..2d7c9bd 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -367,8 +367,7 @@
       if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
         Out << *VD;
       else
-        Base.get<const Expr*>()->printPretty(Out, Ctx, 0,
-                                             Ctx.getPrintingPolicy());
+        Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy());
       if (!O.isZero()) {
         Out << " + " << (O / S);
         if (IsReference)
@@ -389,7 +388,7 @@
       ElemTy = VD->getType();
     } else {
       const Expr *E = Base.get<const Expr*>();
-      E->printPretty(Out, Ctx, 0,Ctx.getPrintingPolicy());
+      E->printPretty(Out, 0, Ctx.getPrintingPolicy());
       ElemTy = E->getType();
     }
 
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 2e13d0c..7c685cf 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -13,9 +13,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
-#include "clang/AST/CommentLexer.h"
-#include "clang/AST/CommentSema.h"
-#include "clang/AST/CommentParser.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
@@ -68,10 +66,41 @@
   if (D->isImplicit())
     return NULL;
 
+  // User can not attach documentation to implicit instantiations.
+  // FIXME: all these implicit instantiations shoud be marked as implicit
+  // declarations and get caught by condition above.
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return NULL;
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (VD->isStaticDataMember() &&
+        VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return NULL;
+  }
+
+  if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
+    if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return NULL;
+  }
+
+  if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+    if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return NULL;
+  }
+
   // TODO: handle comments for function parameters properly.
   if (isa<ParmVarDecl>(D))
     return NULL;
 
+  // TODO: we could look up template parameter documentation in the template
+  // documentation.
+  if (isa<TemplateTypeParmDecl>(D) ||
+      isa<NonTypeTemplateParmDecl>(D) ||
+      isa<TemplateTemplateParmDecl>(D))
+    return NULL;
+
   ArrayRef<RawComment *> RawComments = Comments.getComments();
 
   // If there are no comments anywhere, we won't find anything.
@@ -86,7 +115,9 @@
   // so we use the location of the identifier as the "declaration location".
   SourceLocation DeclLoc;
   if (isa<ObjCMethodDecl>(D) || isa<ObjCContainerDecl>(D) ||
-      isa<ObjCPropertyDecl>(D))
+      isa<ObjCPropertyDecl>(D) ||
+      isa<RedeclarableTemplateDecl>(D) ||
+      isa<ClassTemplateSpecializationDecl>(D))
     DeclLoc = D->getLocStart();
   else
     DeclLoc = D->getLocation();
@@ -180,52 +211,113 @@
   return *Comment;
 }
 
-const RawComment *ASTContext::getRawCommentForDecl(const Decl *D) const {
-  // Check whether we have cached a comment string for this declaration
-  // already.
-  llvm::DenseMap<const Decl *, RawAndParsedComment>::iterator Pos
-      = DeclComments.find(D);
-  if (Pos != DeclComments.end()) {
-    RawAndParsedComment C = Pos->second;
-    return C.first;
+namespace {
+/// If we have a 'templated' declaration for a template, adjust 'D' to
+/// refer to the actual template.
+const Decl *adjustDeclToTemplate(const Decl *D) {
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
+      D = FTD;
+  } else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+    if (const ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
+      D = CTD;
+  }
+  // FIXME: Alias templates?
+  return D;
+}
+} // unnamed namespace
+
+const RawComment *ASTContext::getRawCommentForAnyRedecl(
+                                                const Decl *D,
+                                                const Decl **OriginalDecl) const {
+  D = adjustDeclToTemplate(D);
+
+  // Check whether we have cached a comment for this declaration already.
+  {
+    llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
+        RedeclComments.find(D);
+    if (Pos != RedeclComments.end()) {
+      const RawCommentAndCacheFlags &Raw = Pos->second;
+      if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
+        if (OriginalDecl)
+          *OriginalDecl = Raw.getOriginalDecl();
+        return Raw.getRaw();
+      }
+    }
   }
 
-  RawComment *RC = getRawCommentForDeclNoCache(D);
+  // Search for comments attached to declarations in the redeclaration chain.
+  const RawComment *RC = NULL;
+  const Decl *OriginalDeclForRC = NULL;
+  for (Decl::redecl_iterator I = D->redecls_begin(),
+                             E = D->redecls_end();
+       I != E; ++I) {
+    llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
+        RedeclComments.find(*I);
+    if (Pos != RedeclComments.end()) {
+      const RawCommentAndCacheFlags &Raw = Pos->second;
+      if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
+        RC = Raw.getRaw();
+        OriginalDeclForRC = Raw.getOriginalDecl();
+        break;
+      }
+    } else {
+      RC = getRawCommentForDeclNoCache(*I);
+      OriginalDeclForRC = *I;
+      RawCommentAndCacheFlags Raw;
+      if (RC) {
+        Raw.setRaw(RC);
+        Raw.setKind(RawCommentAndCacheFlags::FromDecl);
+      } else
+        Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
+      Raw.setOriginalDecl(*I);
+      RedeclComments[*I] = Raw;
+      if (RC)
+        break;
+    }
+  }
+
   // If we found a comment, it should be a documentation comment.
   assert(!RC || RC->isDocumentation());
-  DeclComments[D] =
-      RawAndParsedComment(RC, static_cast<comments::FullComment *>(NULL));
-  if (RC)
-    RC->setAttached();
+
+  if (OriginalDecl)
+    *OriginalDecl = OriginalDeclForRC;
+
+  // Update cache for every declaration in the redeclaration chain.
+  RawCommentAndCacheFlags Raw;
+  Raw.setRaw(RC);
+  Raw.setKind(RawCommentAndCacheFlags::FromRedecl);
+  Raw.setOriginalDecl(OriginalDeclForRC);
+
+  for (Decl::redecl_iterator I = D->redecls_begin(),
+                             E = D->redecls_end();
+       I != E; ++I) {
+    RawCommentAndCacheFlags &R = RedeclComments[*I];
+    if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl)
+      R = Raw;
+  }
+
   return RC;
 }
 
 comments::FullComment *ASTContext::getCommentForDecl(const Decl *D) const {
-  llvm::DenseMap<const Decl *, RawAndParsedComment>::iterator Pos
-      = DeclComments.find(D);
-  const RawComment *RC;
-  if (Pos != DeclComments.end()) {
-    RawAndParsedComment C = Pos->second;
-    if (comments::FullComment *FC = C.second)
-      return FC;
-    RC = C.first;
-  } else
-    RC = getRawCommentForDecl(D);
+  D = adjustDeclToTemplate(D);
+  const Decl *Canonical = D->getCanonicalDecl();
+  llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =
+      ParsedComments.find(Canonical);
+  if (Pos != ParsedComments.end())
+    return Pos->second;
 
+  const Decl *OriginalDecl;
+  const RawComment *RC = getRawCommentForAnyRedecl(D, &OriginalDecl);
   if (!RC)
     return NULL;
 
-  const StringRef RawText = RC->getRawText(SourceMgr);
-  comments::Lexer L(RC->getSourceRange().getBegin(), comments::CommentOptions(),
-                    RawText.begin(), RawText.end());
+  if (D != OriginalDecl)
+    return getCommentForDecl(OriginalDecl);
 
-  comments::Sema S(getAllocator(), getSourceManager(), getDiagnostics());
-  S.setDecl(D);
-  comments::Parser P(L, S, getAllocator(), getSourceManager(),
-                     getDiagnostics());
-
-  comments::FullComment *FC = P.parseFullComment();
-  DeclComments[D].second = FC;
+  comments::FullComment *FC = RC->parse(*this, D);
+  ParsedComments[Canonical] = FC;
   return FC;
 }
 
@@ -988,6 +1080,27 @@
   return toCharUnitsFromBits(Align);
 }
 
+// getTypeInfoDataSizeInChars - Return the size of a type, in
+// chars. If the type is a record, its data size is returned.  This is
+// the size of the memcpy that's performed when assigning this type
+// using a trivial copy/move assignment operator.
+std::pair<CharUnits, CharUnits>
+ASTContext::getTypeInfoDataSizeInChars(QualType T) const {
+  std::pair<CharUnits, CharUnits> sizeAndAlign = getTypeInfoInChars(T);
+
+  // In C++, objects can sometimes be allocated into the tail padding
+  // of a base-class subobject.  We decide whether that's possible
+  // during class layout, so here we can just trust the layout results.
+  if (getLangOpts().CPlusPlus) {
+    if (const RecordType *RT = T->getAs<RecordType>()) {
+      const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl());
+      sizeAndAlign.first = layout.getDataSize();
+    }
+  }
+
+  return sizeAndAlign;
+}
+
 std::pair<CharUnits, CharUnits>
 ASTContext::getTypeInfoInChars(const Type *T) const {
   std::pair<uint64_t, unsigned> Info = getTypeInfo(T);
@@ -2367,15 +2480,18 @@
   //  - exception types
   //  - consumed-arguments flags
   // Instead of the exception types, there could be a noexcept
-  // expression.
+  // expression, or information used to resolve the exception
+  // specification.
   size_t Size = sizeof(FunctionProtoType) +
                 NumArgs * sizeof(QualType);
-  if (EPI.ExceptionSpecType == EST_Dynamic)
+  if (EPI.ExceptionSpecType == EST_Dynamic) {
     Size += EPI.NumExceptions * sizeof(QualType);
-  else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
+  } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) {
     Size += sizeof(Expr*);
   } else if (EPI.ExceptionSpecType == EST_Uninstantiated) {
     Size += 2 * sizeof(FunctionDecl*);
+  } else if (EPI.ExceptionSpecType == EST_Unevaluated) {
+    Size += sizeof(FunctionDecl*);
   }
   if (EPI.ConsumedArguments)
     Size += NumArgs * sizeof(bool);
@@ -3137,7 +3253,7 @@
     if (Canon) {
       // We already have a "canonical" version of an equivalent, dependent
       // decltype type. Use that as our canonical type.
-      dt = new (*this, TypeAlignment) DecltypeType(e, DependentTy,
+      dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
                                        QualType((DecltypeType*)Canon, 0));
     } else {
       // Build a new, canonical typeof(expr) type.
@@ -5397,7 +5513,8 @@
   QualifiedTemplateName *QTN =
     QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
   if (!QTN) {
-    QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template);
+    QTN = new (*this, llvm::alignOf<QualifiedTemplateName>())
+        QualifiedTemplateName(NNS, TemplateKeyword, Template);
     QualifiedTemplateNames.InsertNode(QTN, InsertPos);
   }
 
@@ -5424,10 +5541,12 @@
 
   NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
   if (CanonNNS == NNS) {
-    QTN = new (*this,4) DependentTemplateName(NNS, Name);
+    QTN = new (*this, llvm::alignOf<DependentTemplateName>())
+        DependentTemplateName(NNS, Name);
   } else {
     TemplateName Canon = getDependentTemplateName(CanonNNS, Name);
-    QTN = new (*this,4) DependentTemplateName(NNS, Name, Canon);
+    QTN = new (*this, llvm::alignOf<DependentTemplateName>())
+        DependentTemplateName(NNS, Name, Canon);
     DependentTemplateName *CheckQTN =
       DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
     assert(!CheckQTN && "Dependent type name canonicalization broken");
@@ -5458,10 +5577,12 @@
   
   NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
   if (CanonNNS == NNS) {
-    QTN = new (*this,4) DependentTemplateName(NNS, Operator);
+    QTN = new (*this, llvm::alignOf<DependentTemplateName>())
+        DependentTemplateName(NNS, Operator);
   } else {
     TemplateName Canon = getDependentTemplateName(CanonNNS, Operator);
-    QTN = new (*this,4) DependentTemplateName(NNS, Operator, Canon);
+    QTN = new (*this, llvm::alignOf<DependentTemplateName>())
+        DependentTemplateName(NNS, Operator, Canon);
     
     DependentTemplateName *CheckQTN
       = DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 35fcd41..a605f1a 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -1149,7 +1149,7 @@
     if (!E)
       OS << "(no argument)";
     else
-      E->printPretty(OS, Context, 0, Policy); return;
+      E->printPretty(OS, 0, Policy); return;
   }
 
   /// PrintTemplateTemplate - Handles printing of template template arguments,
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 5f6a099..bcc96f9 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -10,6 +10,7 @@
   CXXInheritance.cpp
   Comment.cpp
   CommentBriefParser.cpp
+  CommentCommandTraits.cpp
   CommentDumper.cpp
   CommentLexer.cpp
   CommentParser.cpp
@@ -63,10 +64,12 @@
   ClangAttrClasses
   ClangAttrList
   ClangAttrImpl
-  ClangDiagnosticAST
-  ClangDiagnosticComment
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticAST
+  ClangDiagnosticComment
+  ClangDiagnosticCommon
+  ClangDiagnosticSema
   ClangStmtNodes
   )
 
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index f9aa912..cf3913b 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -97,7 +97,7 @@
                        Paths);
 }
 
-bool CXXRecordDecl::isVirtuallyDerivedFrom(CXXRecordDecl *Base) const {
+bool CXXRecordDecl::isVirtuallyDerivedFrom(const CXXRecordDecl *Base) const {
   if (!getNumVBases())
     return false;
 
@@ -107,8 +107,12 @@
   if (getCanonicalDecl() == Base->getCanonicalDecl())
     return false;
   
-  Paths.setOrigin(const_cast<CXXRecordDecl*>(this));  
-  return lookupInBases(&FindVirtualBaseClass, Base->getCanonicalDecl(), Paths);
+  Paths.setOrigin(const_cast<CXXRecordDecl*>(this));
+
+  const void *BasePtr = static_cast<const void*>(Base->getCanonicalDecl());
+  return lookupInBases(&FindVirtualBaseClass,
+                       const_cast<void *>(BasePtr),
+                       Paths);
 }
 
 static bool BaseIsNot(const CXXRecordDecl *Base, void *OpaqueTarget) {
@@ -161,7 +165,7 @@
   return AllMatches;
 }
 
-bool CXXBasePaths::lookupInBases(ASTContext &Context, 
+bool CXXBasePaths::lookupInBases(ASTContext &Context,
                                  const CXXRecordDecl *Record,
                                CXXRecordDecl::BaseMatchesCallback *BaseMatches, 
                                  void *UserData) {
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index 82dbed4..8a711f0 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -8,6 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/Comment.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -134,5 +137,128 @@
   llvm_unreachable("unknown PassDirection");
 }
 
+void DeclInfo::fill() {
+  assert(!IsFilled);
+
+  // Set defaults.
+  Kind = OtherKind;
+  TemplateKind = NotTemplate;
+  IsObjCMethod = false;
+  IsInstanceMethod = false;
+  IsClassMethod = false;
+  ParamVars = ArrayRef<const ParmVarDecl *>();
+  TemplateParameters = NULL;
+
+  if (!ThisDecl) {
+    // If there is no declaration, the defaults is our only guess.
+    IsFilled = true;
+    return;
+  }
+
+  Decl::Kind K = ThisDecl->getKind();
+  switch (K) {
+  default:
+    // Defaults are should be good for declarations we don't handle explicitly.
+    break;
+  case Decl::Function:
+  case Decl::CXXMethod:
+  case Decl::CXXConstructor:
+  case Decl::CXXDestructor:
+  case Decl::CXXConversion: {
+    const FunctionDecl *FD = cast<FunctionDecl>(ThisDecl);
+    Kind = FunctionKind;
+    ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
+                                              FD->getNumParams());
+    ResultType = FD->getResultType();
+    unsigned NumLists = FD->getNumTemplateParameterLists();
+    if (NumLists != 0) {
+      TemplateKind = TemplateSpecialization;
+      TemplateParameters =
+          FD->getTemplateParameterList(NumLists - 1);
+    }
+
+    if (K == Decl::CXXMethod || K == Decl::CXXConstructor ||
+        K == Decl::CXXDestructor || K == Decl::CXXConversion) {
+      const CXXMethodDecl *MD = cast<CXXMethodDecl>(ThisDecl);
+      IsInstanceMethod = MD->isInstance();
+      IsClassMethod = !IsInstanceMethod;
+    }
+    break;
+  }
+  case Decl::ObjCMethod: {
+    const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(ThisDecl);
+    Kind = FunctionKind;
+    ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
+                                              MD->param_size());
+    ResultType = MD->getResultType();
+    IsObjCMethod = true;
+    IsInstanceMethod = MD->isInstanceMethod();
+    IsClassMethod = !IsInstanceMethod;
+    break;
+  }
+  case Decl::FunctionTemplate: {
+    const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(ThisDecl);
+    Kind = FunctionKind;
+    TemplateKind = Template;
+    const FunctionDecl *FD = FTD->getTemplatedDecl();
+    ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
+                                              FD->getNumParams());
+    ResultType = FD->getResultType();
+    TemplateParameters = FTD->getTemplateParameters();
+    break;
+  }
+  case Decl::ClassTemplate: {
+    const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(ThisDecl);
+    Kind = ClassKind;
+    TemplateKind = Template;
+    TemplateParameters = CTD->getTemplateParameters();
+    break;
+  }
+  case Decl::ClassTemplatePartialSpecialization: {
+    const ClassTemplatePartialSpecializationDecl *CTPSD =
+        cast<ClassTemplatePartialSpecializationDecl>(ThisDecl);
+    Kind = ClassKind;
+    TemplateKind = TemplatePartialSpecialization;
+    TemplateParameters = CTPSD->getTemplateParameters();
+    break;
+  }
+  case Decl::ClassTemplateSpecialization:
+    Kind = ClassKind;
+    TemplateKind = TemplateSpecialization;
+    break;
+  case Decl::Record:
+  case Decl::CXXRecord:
+    Kind = ClassKind;
+    break;
+  case Decl::Var:
+  case Decl::Field:
+  case Decl::EnumConstant:
+  case Decl::ObjCIvar:
+  case Decl::ObjCAtDefsField:
+    Kind = VariableKind;
+    break;
+  case Decl::Namespace:
+    Kind = NamespaceKind;
+    break;
+  case Decl::Typedef:
+  case Decl::TypeAlias:
+    Kind = TypedefKind;
+    break;
+  case Decl::TypeAliasTemplate: {
+    const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(ThisDecl);
+    Kind = TypedefKind;
+    TemplateKind = Template;
+    TemplateParameters = TAT->getTemplateParameters();
+    break;
+  }
+  case Decl::Enum:
+    Kind = EnumKind;
+    break;
+  }
+
+  IsFilled = true;
+}
+
 } // end namespace comments
 } // end namespace clang
+
diff --git a/lib/AST/CommentBriefParser.cpp b/lib/AST/CommentBriefParser.cpp
index 47d52e1..5a9b10d 100644
--- a/lib/AST/CommentBriefParser.cpp
+++ b/lib/AST/CommentBriefParser.cpp
@@ -8,12 +8,18 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/CommentBriefParser.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/StringSwitch.h"
 
 namespace clang {
 namespace comments {
 
 namespace {
+inline bool isWhitespace(char C) {
+  return C == ' ' || C == '\n' || C == '\r' ||
+         C == '\t' || C == '\f' || C == '\v';
+}
+
 /// Convert all whitespace into spaces, remove leading and trailing spaces,
 /// compress multiple spaces into one.
 void cleanupBrief(std::string &S) {
@@ -22,8 +28,7 @@
   for (std::string::iterator I = S.begin(), E = S.end();
        I != E; ++I) {
     const char C = *I;
-    if (C == ' ' || C == '\n' || C == '\r' ||
-        C == '\t' || C == '\v' || C == '\f') {
+    if (isWhitespace(C)) {
       if (!PrevWasSpace) {
         *O++ = ' ';
         PrevWasSpace = true;
@@ -40,18 +45,22 @@
   S.resize(O - S.begin());
 }
 
-bool isBlockCommand(StringRef Name) {
-  return llvm::StringSwitch<bool>(Name)
-      .Cases("brief", "short", true)
-      .Cases("result", "return", "returns", true)
-      .Cases("author", "authors", true)
-      .Case("pre", true)
-      .Case("post", true)
-      .Cases("param", "arg", true)
-      .Default(false);
+bool isWhitespace(StringRef Text) {
+  for (StringRef::const_iterator I = Text.begin(), E = Text.end();
+       I != E; ++I) {
+    if (!isWhitespace(*I))
+      return false;
+  }
+  return true;
 }
 } // unnamed namespace
 
+BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
+    L(L), Traits(Traits) {
+  // Get lookahead token.
+  ConsumeToken();
+}
+
 std::string BriefParser::Parse() {
   std::string FirstParagraphOrBrief;
   std::string ReturnsParagraph;
@@ -71,18 +80,22 @@
 
     if (Tok.is(tok::command)) {
       StringRef Name = Tok.getCommandName();
-      if (Name == "brief" || Name == "short") {
+      if (Traits.isBriefCommand(Name)) {
         FirstParagraphOrBrief.clear();
         InBrief = true;
         ConsumeToken();
         continue;
       }
-      if (Name == "result" || Name == "return" || Name == "returns") {
+      if (Traits.isReturnsCommand(Name)) {
         InReturns = true;
+        InBrief = false;
+        InFirstParagraph = false;
         ReturnsParagraph += "Returns ";
+        ConsumeToken();
+        continue;
       }
       // Block commands implicitly start a new paragraph.
-      if (isBlockCommand(Name)) {
+      if (Traits.isBlockCommand(Name)) {
         // We found an implicit paragraph end.
         InFirstParagraph = false;
         if (InBrief)
@@ -97,13 +110,29 @@
         ReturnsParagraph += ' ';
       ConsumeToken();
 
+      // If the next token is a whitespace only text, ignore it.  Thus we allow
+      // two paragraphs to be separated by line that has only whitespace in it.
+      //
+      // We don't need to add a space to the parsed text because we just added
+      // a space for the newline.
+      if (Tok.is(tok::text)) {
+        if (isWhitespace(Tok.getText()))
+          ConsumeToken();
+      }
+
       if (Tok.is(tok::newline)) {
         ConsumeToken();
-        // We found a paragraph end.
-        InFirstParagraph = false;
-        InReturns = false;
+        // We found a paragraph end.  This ends the brief description if
+        // \\brief command or its equivalent was explicitly used.
+        // Stop scanning text because an explicit \\brief paragraph is the
+        // preffered one.
         if (InBrief)
           break;
+        // End first paragraph if we found some non-whitespace text.
+        if (InFirstParagraph && !isWhitespace(FirstParagraphOrBrief))
+          InFirstParagraph = false;
+        // End the \\returns paragraph because we found the paragraph end.
+        InReturns = false;
       }
       continue;
     }
@@ -120,11 +149,6 @@
   return ReturnsParagraph;
 }
 
-BriefParser::BriefParser(Lexer &L) : L(L) {
-  // Get lookahead token.
-  ConsumeToken();
-}
-
 } // end namespace comments
 } // end namespace clang
 
diff --git a/lib/AST/CommentCommandTraits.cpp b/lib/AST/CommentCommandTraits.cpp
new file mode 100644
index 0000000..dc7a0bd
--- /dev/null
+++ b/lib/AST/CommentCommandTraits.cpp
@@ -0,0 +1,134 @@
+//===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/CommentCommandTraits.h"
+#include "llvm/ADT/StringSwitch.h"
+
+namespace clang {
+namespace comments {
+
+// TODO: tablegen
+
+bool CommandTraits::isVerbatimBlockCommand(StringRef StartName,
+                                           StringRef &EndName) const {
+  const char *Result = llvm::StringSwitch<const char *>(StartName)
+    .Case("code", "endcode")
+    .Case("verbatim", "endverbatim")
+    .Case("htmlonly", "endhtmlonly")
+    .Case("latexonly", "endlatexonly")
+    .Case("xmlonly", "endxmlonly")
+    .Case("manonly", "endmanonly")
+    .Case("rtfonly", "endrtfonly")
+
+    .Case("dot", "enddot")
+    .Case("msc", "endmsc")
+
+    .Case("f$", "f$") // Inline LaTeX formula
+    .Case("f[", "f]") // Displayed LaTeX formula
+    .Case("f{", "f}") // LaTeX environment
+
+    .Default(NULL);
+
+  if (Result) {
+    EndName = Result;
+    return true;
+  }
+
+  for (VerbatimBlockCommandVector::const_iterator
+           I = VerbatimBlockCommands.begin(),
+           E = VerbatimBlockCommands.end();
+       I != E; ++I)
+    if (I->StartName == StartName) {
+      EndName = I->EndName;
+      return true;
+    }
+
+  return false;
+}
+
+bool CommandTraits::isVerbatimLineCommand(StringRef Name) const {
+  bool Result = isDeclarationCommand(Name) || llvm::StringSwitch<bool>(Name)
+  .Case("defgroup", true)
+  .Case("ingroup", true)
+  .Case("addtogroup", true)
+  .Case("weakgroup", true)
+  .Case("name", true)
+
+  .Case("section", true)
+  .Case("subsection", true)
+  .Case("subsubsection", true)
+  .Case("paragraph", true)
+
+  .Case("mainpage", true)
+  .Case("subpage", true)
+  .Case("ref", true)
+
+  .Default(false);
+
+  if (Result)
+    return true;
+
+  for (VerbatimLineCommandVector::const_iterator
+           I = VerbatimLineCommands.begin(),
+           E = VerbatimLineCommands.end();
+       I != E; ++I)
+    if (I->Name == Name)
+      return true;
+
+  return false;
+}
+
+bool CommandTraits::isDeclarationCommand(StringRef Name) const {
+  return llvm::StringSwitch<bool>(Name)
+      // Doxygen commands.
+      .Case("fn", true)
+      .Case("var", true)
+      .Case("property", true)
+      .Case("typedef", true)
+
+      .Case("overload", true)
+
+      // HeaderDoc commands.
+      .Case("class", true)
+      .Case("interface", true)
+      .Case("protocol", true)
+      .Case("category", true)
+      .Case("template", true)
+      .Case("function", true)
+      .Case("method", true)
+      .Case("callback", true)
+      .Case("var", true)
+      .Case("const", true)
+      .Case("constant", true)
+      .Case("property", true)
+      .Case("struct", true)
+      .Case("union", true)
+      .Case("typedef", true)
+      .Case("enum", true)
+
+      .Default(false);
+}
+
+void CommandTraits::addVerbatimBlockCommand(StringRef StartName,
+                                            StringRef EndName) {
+  VerbatimBlockCommand VBC;
+  VBC.StartName = StartName;
+  VBC.EndName = EndName;
+  VerbatimBlockCommands.push_back(VBC);
+}
+
+void CommandTraits::addVerbatimLineCommand(StringRef Name) {
+  VerbatimLineCommand VLC;
+  VLC.Name = Name;
+  VerbatimLineCommands.push_back(VLC);
+}
+
+} // end namespace comments
+} // end namespace clang
+
diff --git a/lib/AST/CommentDumper.cpp b/lib/AST/CommentDumper.cpp
index c930b24..dffc823 100644
--- a/lib/AST/CommentDumper.cpp
+++ b/lib/AST/CommentDumper.cpp
@@ -50,6 +50,7 @@
   void visitParagraphComment(const ParagraphComment *C);
   void visitBlockCommandComment(const BlockCommandComment *C);
   void visitParamCommandComment(const ParamCommandComment *C);
+  void visitTParamCommandComment(const TParamCommandComment *C);
   void visitVerbatimBlockComment(const VerbatimBlockComment *C);
   void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
   void visitVerbatimLineComment(const VerbatimLineComment *C);
@@ -75,7 +76,7 @@
 void CommentDumper::dumpComment(const Comment *C) {
   dumpIndent();
   OS << "(" << C->getCommentKindName()
-     << " " << (void *) C;
+     << " " << (const void *) C;
   dumpSourceRange(C);
 }
 
@@ -169,9 +170,29 @@
   else
     OS << " implicitly";
 
+  if (C->hasParamName())
+    OS << " Param=\"" << C->getParamName() << "\"";
+
+  if (C->isParamIndexValid())
+    OS << " ParamIndex=" << C->getParamIndex();
+}
+
+void CommentDumper::visitTParamCommandComment(const TParamCommandComment *C) {
+  dumpComment(C);
+
   if (C->hasParamName()) {
     OS << " Param=\"" << C->getParamName() << "\"";
   }
+
+  if (C->isPositionValid()) {
+    OS << " Position=<";
+    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
+      OS << C->getIndex(i);
+      if (i != e - 1)
+        OS << ", ";
+    }
+    OS << ">";
+  }
 }
 
 void CommentDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index 3146832..b6516ec 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -1,4 +1,6 @@
 #include "clang/AST/CommentLexer.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/Basic/ConvertUTF.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 
@@ -11,80 +13,69 @@
   llvm::errs() << " " << Length << " \"" << L.getSpelling(*this, SM) << "\"\n";
 }
 
-bool Lexer::isVerbatimBlockCommand(StringRef BeginName,
-                                  StringRef &EndName) const {
-  const char *Result = llvm::StringSwitch<const char *>(BeginName)
-    .Case("code", "endcode")
-    .Case("verbatim", "endverbatim")
-    .Case("htmlonly", "endhtmlonly")
-    .Case("latexonly", "endlatexonly")
-    .Case("xmlonly", "endxmlonly")
-    .Case("manonly", "endmanonly")
-    .Case("rtfonly", "endrtfonly")
-
-    .Case("dot", "enddot")
-    .Case("msc", "endmsc")
-
-    .Case("f$", "f$") // Inline LaTeX formula
-    .Case("f[", "f]") // Displayed LaTeX formula
-    .Case("f{", "f}") // LaTeX environment
-
-    .Default(NULL);
-
-  if (Result) {
-    EndName = Result;
-    return true;
-  }
-
-  for (VerbatimBlockCommandVector::const_iterator
-           I = VerbatimBlockCommands.begin(),
-           E = VerbatimBlockCommands.end();
-       I != E; ++I)
-    if (I->BeginName == BeginName) {
-      EndName = I->EndName;
-      return true;
-    }
-
-  return false;
+namespace {
+bool isHTMLNamedCharacterReferenceCharacter(char C) {
+  return (C >= 'a' && C <= 'z') ||
+         (C >= 'A' && C <= 'Z');
 }
 
-bool Lexer::isVerbatimLineCommand(StringRef Name) const {
-  bool Result = llvm::StringSwitch<bool>(Name)
-  .Case("fn", true)
-  .Case("var", true)
-  .Case("property", true)
-  .Case("typedef", true)
+bool isHTMLDecimalCharacterReferenceCharacter(char C) {
+  return C >= '0' && C <= '9';
+}
 
-  .Case("overload", true)
+bool isHTMLHexCharacterReferenceCharacter(char C) {
+  return (C >= '0' && C <= '9') ||
+         (C >= 'a' && C <= 'f') ||
+         (C >= 'A' && C <= 'F');
+}
+} // unnamed namespace
 
-  .Case("defgroup", true)
-  .Case("ingroup", true)
-  .Case("addtogroup", true)
-  .Case("weakgroup", true)
-  .Case("name", true)
+StringRef Lexer::resolveHTMLNamedCharacterReference(StringRef Name) const {
+  return llvm::StringSwitch<StringRef>(Name)
+      .Case("amp", "&")
+      .Case("lt", "<")
+      .Case("gt", ">")
+      .Case("quot", "\"")
+      .Case("apos", "\'")
+      .Default("");
+}
 
-  .Case("section", true)
-  .Case("subsection", true)
-  .Case("subsubsection", true)
-  .Case("paragraph", true)
+StringRef Lexer::resolveHTMLDecimalCharacterReference(StringRef Name) const {
+  unsigned CodePoint = 0;
+  for (unsigned i = 0, e = Name.size(); i != e; ++i) {
+    assert(isHTMLDecimalCharacterReferenceCharacter(Name[i]));
+    CodePoint *= 10;
+    CodePoint += Name[i] - '0';
+  }
 
-  .Case("mainpage", true)
-  .Case("subpage", true)
-  .Case("ref", true)
+  char *Resolved = Allocator.Allocate<char>(UNI_MAX_UTF8_BYTES_PER_CODE_POINT);
+  char *ResolvedPtr = Resolved;
+  if (ConvertCodePointToUTF8(CodePoint, ResolvedPtr))
+    return StringRef(Resolved, ResolvedPtr - Resolved);
+  else
+    return StringRef();
+}
 
-  .Default(false);
+StringRef Lexer::resolveHTMLHexCharacterReference(StringRef Name) const {
+  unsigned CodePoint = 0;
+  for (unsigned i = 0, e = Name.size(); i != e; ++i) {
+    CodePoint *= 16;
+    const char C = Name[i];
+    assert(isHTMLHexCharacterReferenceCharacter(C));
+    if (C >= '0' && C <= '9')
+      CodePoint += Name[i] - '0';
+    else if (C >= 'a' && C <= 'f')
+      CodePoint += Name[i] - 'a' + 10;
+    else
+      CodePoint += Name[i] - 'A' + 10;
+  }
 
-  if (Result)
-    return true;
-
-  for (VerbatimLineCommandVector::const_iterator
-           I = VerbatimLineCommands.begin(),
-           E = VerbatimLineCommands.end();
-       I != E; ++I)
-    if (I->Name == Name)
-      return true;
-
-  return false;
+  char *Resolved = Allocator.Allocate<char>(UNI_MAX_UTF8_BYTES_PER_CODE_POINT);
+  char *ResolvedPtr = Resolved;
+  if (ConvertCodePointToUTF8(CodePoint, ResolvedPtr))
+    return StringRef(Resolved, ResolvedPtr - Resolved);
+  else
+    return StringRef();
 }
 
 void Lexer::skipLineStartingDecorations() {
@@ -147,6 +138,33 @@
   return BufferPtr;
 }
 
+const char *skipNamedCharacterReference(const char *BufferPtr,
+                                        const char *BufferEnd) {
+  for ( ; BufferPtr != BufferEnd; ++BufferPtr) {
+    if (!isHTMLNamedCharacterReferenceCharacter(*BufferPtr))
+      return BufferPtr;
+  }
+  return BufferEnd;
+}
+
+const char *skipDecimalCharacterReference(const char *BufferPtr,
+                                          const char *BufferEnd) {
+  for ( ; BufferPtr != BufferEnd; ++BufferPtr) {
+    if (!isHTMLDecimalCharacterReferenceCharacter(*BufferPtr))
+      return BufferPtr;
+  }
+  return BufferEnd;
+}
+
+const char *skipHexCharacterReference(const char *BufferPtr,
+                                          const char *BufferEnd) {
+  for ( ; BufferPtr != BufferEnd; ++BufferPtr) {
+    if (!isHTMLHexCharacterReferenceCharacter(*BufferPtr))
+      return BufferPtr;
+  }
+  return BufferEnd;
+}
+
 bool isHTMLIdentifierStartingCharacter(char C) {
   return (C >= 'a' && C <= 'z') ||
          (C >= 'A' && C <= 'Z');
@@ -295,9 +313,7 @@
       case '@': {
         TokenPtr++;
         if (TokenPtr == CommentEnd) {
-          StringRef Text(BufferPtr, TokenPtr - BufferPtr);
-          formTokenWithChars(T, TokenPtr, tok::text);
-          T.setText(Text);
+          formTextToken(T, TokenPtr);
           return;
         }
         char C = *TokenPtr;
@@ -322,9 +338,7 @@
 
         // Don't make zero-length commands.
         if (!isCommandNameCharacter(*TokenPtr)) {
-          StringRef Text(BufferPtr, TokenPtr - BufferPtr);
-          formTokenWithChars(T, TokenPtr, tok::text);
-          T.setText(Text);
+          formTextToken(T, TokenPtr);
           return;
         }
 
@@ -344,11 +358,11 @@
         const StringRef CommandName(BufferPtr + 1, Length);
         StringRef EndName;
 
-        if (isVerbatimBlockCommand(CommandName, EndName)) {
+        if (Traits.isVerbatimBlockCommand(CommandName, EndName)) {
           setupAndLexVerbatimBlock(T, TokenPtr, *BufferPtr, EndName);
           return;
         }
-        if (isVerbatimLineCommand(CommandName)) {
+        if (Traits.isVerbatimLineCommand(CommandName)) {
           setupAndLexVerbatimLine(T, TokenPtr);
           return;
         }
@@ -357,12 +371,14 @@
         return;
       }
 
+      case '&':
+        lexHTMLCharacterReference(T);
+        return;
+
       case '<': {
         TokenPtr++;
         if (TokenPtr == CommentEnd) {
-          StringRef Text(BufferPtr, TokenPtr - BufferPtr);
-          formTokenWithChars(T, TokenPtr, tok::text);
-          T.setText(Text);
+          formTextToken(T, TokenPtr);
           return;
         }
         const char C = *TokenPtr;
@@ -370,11 +386,9 @@
           setupAndLexHTMLStartTag(T);
         else if (C == '/')
           setupAndLexHTMLEndTag(T);
-        else {
-          StringRef Text(BufferPtr, TokenPtr - BufferPtr);
-          formTokenWithChars(T, TokenPtr, tok::text);
-          T.setText(Text);
-        }
+        else
+          formTextToken(T, TokenPtr);
+
         return;
       }
 
@@ -394,12 +408,10 @@
             break;
           const char C = *TokenPtr;
           if(C == '\n' || C == '\r' ||
-             C == '\\' || C == '@' || C == '<')
+             C == '\\' || C == '@' || C == '&' || C == '<')
             break;
         }
-        StringRef Text(BufferPtr, TokenPtr - BufferPtr);
-        formTokenWithChars(T, TokenPtr, tok::text);
-        T.setText(Text);
+        formTextToken(T, TokenPtr);
         return;
       }
     }
@@ -506,6 +518,69 @@
   State = LS_Normal;
 }
 
+void Lexer::lexHTMLCharacterReference(Token &T) {
+  const char *TokenPtr = BufferPtr;
+  assert(*TokenPtr == '&');
+  TokenPtr++;
+  if (TokenPtr == CommentEnd) {
+    formTextToken(T, TokenPtr);
+    return;
+  }
+  const char *NamePtr;
+  bool isNamed = false;
+  bool isDecimal = false;
+  char C = *TokenPtr;
+  if (isHTMLNamedCharacterReferenceCharacter(C)) {
+    NamePtr = TokenPtr;
+    TokenPtr = skipNamedCharacterReference(TokenPtr, CommentEnd);
+    isNamed = true;
+  } else if (C == '#') {
+    TokenPtr++;
+    if (TokenPtr == CommentEnd) {
+      formTextToken(T, TokenPtr);
+      return;
+    }
+    C = *TokenPtr;
+    if (isHTMLDecimalCharacterReferenceCharacter(C)) {
+      NamePtr = TokenPtr;
+      TokenPtr = skipDecimalCharacterReference(TokenPtr, CommentEnd);
+      isDecimal = true;
+    } else if (C == 'x' || C == 'X') {
+      TokenPtr++;
+      NamePtr = TokenPtr;
+      TokenPtr = skipHexCharacterReference(TokenPtr, CommentEnd);
+    } else {
+      formTextToken(T, TokenPtr);
+      return;
+    }
+  } else {
+    formTextToken(T, TokenPtr);
+    return;
+  }
+  if (NamePtr == TokenPtr || TokenPtr == CommentEnd ||
+      *TokenPtr != ';') {
+    formTextToken(T, TokenPtr);
+    return;
+  }
+  StringRef Name(NamePtr, TokenPtr - NamePtr);
+  TokenPtr++; // Skip semicolon.
+  StringRef Resolved;
+  if (isNamed)
+    Resolved = resolveHTMLNamedCharacterReference(Name);
+  else if (isDecimal)
+    Resolved = resolveHTMLDecimalCharacterReference(Name);
+  else
+    Resolved = resolveHTMLHexCharacterReference(Name);
+
+  if (Resolved.empty()) {
+    formTextToken(T, TokenPtr);
+    return;
+  }
+  formTokenWithChars(T, TokenPtr, tok::text);
+  T.setText(Resolved);
+  return;
+}
+
 void Lexer::setupAndLexHTMLStartTag(Token &T) {
   assert(BufferPtr[0] == '<' &&
          isHTMLIdentifierStartingCharacter(BufferPtr[1]));
@@ -561,11 +636,9 @@
       if (TokenPtr != CommentEnd && *TokenPtr == '>') {
         TokenPtr++;
         formTokenWithChars(T, TokenPtr, tok::html_slash_greater);
-      } else {
-        StringRef Text(BufferPtr, TokenPtr - BufferPtr);
-        formTokenWithChars(T, TokenPtr, tok::text);
-        T.setText(Text);
-      }
+      } else
+        formTextToken(T, TokenPtr);
+
       State = LS_Normal;
       return;
     }
@@ -609,8 +682,10 @@
   State = LS_Normal;
 }
 
-Lexer::Lexer(SourceLocation FileLoc, const CommentOptions &CommOpts,
+Lexer::Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits,
+             SourceLocation FileLoc, const CommentOptions &CommOpts,
              const char *BufferStart, const char *BufferEnd):
+    Allocator(Allocator), Traits(Traits),
     BufferStart(BufferStart), BufferEnd(BufferEnd),
     FileLoc(FileLoc), CommOpts(CommOpts), BufferPtr(BufferStart),
     CommentState(LCS_BeforeComment), State(LS_Normal) {
@@ -735,19 +810,6 @@
   return StringRef(Begin, Tok.getLength());
 }
 
-void Lexer::addVerbatimBlockCommand(StringRef BeginName, StringRef EndName) {
-  VerbatimBlockCommand VBC;
-  VBC.BeginName = BeginName;
-  VBC.EndName = EndName;
-  VerbatimBlockCommands.push_back(VBC);
-}
-
-void Lexer::addVerbatimLineCommand(StringRef Name) {
-  VerbatimLineCommand VLC;
-  VLC.Name = Name;
-  VerbatimLineCommands.push_back(VLC);
-}
-
 } // end namespace comments
 } // end namespace clang
 
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index 6b7e0ab..43abf6a 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -10,43 +10,285 @@
 #include "clang/AST/CommentParser.h"
 #include "clang/AST/CommentSema.h"
 #include "clang/AST/CommentDiagnostic.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/Support/ErrorHandling.h"
 
 namespace clang {
 namespace comments {
 
+/// Re-lexes a sequence of tok::text tokens.
+class TextTokenRetokenizer {
+  llvm::BumpPtrAllocator &Allocator;
+  Parser &P;
+
+  /// This flag is set when there are no more tokens we can fetch from lexer.
+  bool NoMoreInterestingTokens;
+
+  /// Token buffer: tokens we have processed and lookahead.
+  SmallVector<Token, 16> Toks;
+
+  /// A position in \c Toks.
+  struct Position {
+    unsigned CurToken;
+    const char *BufferStart;
+    const char *BufferEnd;
+    const char *BufferPtr;
+    SourceLocation BufferStartLoc;
+  };
+
+  /// Current position in Toks.
+  Position Pos;
+
+  bool isEnd() const {
+    return Pos.CurToken >= Toks.size();
+  }
+
+  /// Sets up the buffer pointers to point to current token.
+  void setupBuffer() {
+    assert(!isEnd());
+    const Token &Tok = Toks[Pos.CurToken];
+
+    Pos.BufferStart = Tok.getText().begin();
+    Pos.BufferEnd = Tok.getText().end();
+    Pos.BufferPtr = Pos.BufferStart;
+    Pos.BufferStartLoc = Tok.getLocation();
+  }
+
+  SourceLocation getSourceLocation() const {
+    const unsigned CharNo = Pos.BufferPtr - Pos.BufferStart;
+    return Pos.BufferStartLoc.getLocWithOffset(CharNo);
+  }
+
+  char peek() const {
+    assert(!isEnd());
+    assert(Pos.BufferPtr != Pos.BufferEnd);
+    return *Pos.BufferPtr;
+  }
+
+  void consumeChar() {
+    assert(!isEnd());
+    assert(Pos.BufferPtr != Pos.BufferEnd);
+    Pos.BufferPtr++;
+    if (Pos.BufferPtr == Pos.BufferEnd) {
+      Pos.CurToken++;
+      if (isEnd() && !addToken())
+        return;
+
+      assert(!isEnd());
+      setupBuffer();
+    }
+  }
+
+  /// Add a token.
+  /// Returns true on success, false if there are no interesting tokens to
+  /// fetch from lexer.
+  bool addToken() {
+    if (NoMoreInterestingTokens)
+      return false;
+
+    if (P.Tok.is(tok::newline)) {
+      // If we see a single newline token between text tokens, skip it.
+      Token Newline = P.Tok;
+      P.consumeToken();
+      if (P.Tok.isNot(tok::text)) {
+        P.putBack(Newline);
+        NoMoreInterestingTokens = true;
+        return false;
+      }
+    }
+    if (P.Tok.isNot(tok::text)) {
+      NoMoreInterestingTokens = true;
+      return false;
+    }
+
+    Toks.push_back(P.Tok);
+    P.consumeToken();
+    if (Toks.size() == 1)
+      setupBuffer();
+    return true;
+  }
+
+  static bool isWhitespace(char C) {
+    return C == ' ' || C == '\n' || C == '\r' ||
+           C == '\t' || C == '\f' || C == '\v';
+  }
+
+  void consumeWhitespace() {
+    while (!isEnd()) {
+      if (isWhitespace(peek()))
+        consumeChar();
+      else
+        break;
+    }
+  }
+
+  void formTokenWithChars(Token &Result,
+                          SourceLocation Loc,
+                          const char *TokBegin,
+                          unsigned TokLength,
+                          StringRef Text) {
+    Result.setLocation(Loc);
+    Result.setKind(tok::text);
+    Result.setLength(TokLength);
+#ifndef NDEBUG
+    Result.TextPtr1 = "<UNSET>";
+    Result.TextLen1 = 7;
+#endif
+    Result.setText(Text);
+  }
+
+public:
+  TextTokenRetokenizer(llvm::BumpPtrAllocator &Allocator, Parser &P):
+      Allocator(Allocator), P(P), NoMoreInterestingTokens(false) {
+    Pos.CurToken = 0;
+    addToken();
+  }
+
+  /// Extract a word -- sequence of non-whitespace characters.
+  bool lexWord(Token &Tok) {
+    if (isEnd())
+      return false;
+
+    Position SavedPos = Pos;
+
+    consumeWhitespace();
+    SmallString<32> WordText;
+    const char *WordBegin = Pos.BufferPtr;
+    SourceLocation Loc = getSourceLocation();
+    while (!isEnd()) {
+      const char C = peek();
+      if (!isWhitespace(C)) {
+        WordText.push_back(C);
+        consumeChar();
+      } else
+        break;
+    }
+    const unsigned Length = WordText.size();
+    if (Length == 0) {
+      Pos = SavedPos;
+      return false;
+    }
+
+    char *TextPtr = Allocator.Allocate<char>(Length + 1);
+
+    memcpy(TextPtr, WordText.c_str(), Length + 1);
+    StringRef Text = StringRef(TextPtr, Length);
+
+    formTokenWithChars(Tok, Loc, WordBegin,
+                       Pos.BufferPtr - WordBegin, Text);
+    return true;
+  }
+
+  bool lexDelimitedSeq(Token &Tok, char OpenDelim, char CloseDelim) {
+    if (isEnd())
+      return false;
+
+    Position SavedPos = Pos;
+
+    consumeWhitespace();
+    SmallString<32> WordText;
+    const char *WordBegin = Pos.BufferPtr;
+    SourceLocation Loc = getSourceLocation();
+    bool Error = false;
+    if (!isEnd()) {
+      const char C = peek();
+      if (C == OpenDelim) {
+        WordText.push_back(C);
+        consumeChar();
+      } else
+        Error = true;
+    }
+    char C = '\0';
+    while (!Error && !isEnd()) {
+      C = peek();
+      WordText.push_back(C);
+      consumeChar();
+      if (C == CloseDelim)
+        break;
+    }
+    if (!Error && C != CloseDelim)
+      Error = true;
+
+    if (Error) {
+      Pos = SavedPos;
+      return false;
+    }
+
+    const unsigned Length = WordText.size();
+    char *TextPtr = Allocator.Allocate<char>(Length + 1);
+
+    memcpy(TextPtr, WordText.c_str(), Length + 1);
+    StringRef Text = StringRef(TextPtr, Length);
+
+    formTokenWithChars(Tok, Loc, WordBegin,
+                       Pos.BufferPtr - WordBegin, Text);
+    return true;
+  }
+
+  /// Put back tokens that we didn't consume.
+  void putBackLeftoverTokens() {
+    if (isEnd())
+      return;
+
+    bool HavePartialTok = false;
+    Token PartialTok;
+    if (Pos.BufferPtr != Pos.BufferStart) {
+      formTokenWithChars(PartialTok, getSourceLocation(),
+                         Pos.BufferPtr, Pos.BufferEnd - Pos.BufferPtr,
+                         StringRef(Pos.BufferPtr,
+                                   Pos.BufferEnd - Pos.BufferPtr));
+      HavePartialTok = true;
+      Pos.CurToken++;
+    }
+
+    P.putBack(llvm::makeArrayRef(Toks.begin() + Pos.CurToken, Toks.end()));
+    Pos.CurToken = Toks.size();
+
+    if (HavePartialTok)
+      P.putBack(PartialTok);
+  }
+};
+
 Parser::Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator,
-               const SourceManager &SourceMgr, DiagnosticsEngine &Diags):
-    L(L), S(S), Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags) {
+               const SourceManager &SourceMgr, DiagnosticsEngine &Diags,
+               const CommandTraits &Traits):
+    L(L), S(S), Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags),
+    Traits(Traits) {
   consumeToken();
 }
 
-ParamCommandComment *Parser::parseParamCommandArgs(
-    ParamCommandComment *PC,
-    TextTokenRetokenizer &Retokenizer) {
+void Parser::parseParamCommandArgs(ParamCommandComment *PC,
+                                   TextTokenRetokenizer &Retokenizer) {
   Token Arg;
   // Check if argument looks like direction specification: [dir]
   // e.g., [in], [out], [in,out]
   if (Retokenizer.lexDelimitedSeq(Arg, '[', ']'))
-    PC = S.actOnParamCommandDirectionArg(PC,
-                                         Arg.getLocation(),
-                                         Arg.getEndLocation(),
-                                         Arg.getText());
+    S.actOnParamCommandDirectionArg(PC,
+                                    Arg.getLocation(),
+                                    Arg.getEndLocation(),
+                                    Arg.getText());
 
   if (Retokenizer.lexWord(Arg))
-    PC = S.actOnParamCommandParamNameArg(PC,
-                                         Arg.getLocation(),
-                                         Arg.getEndLocation(),
-                                         Arg.getText());
-
-  return PC;
+    S.actOnParamCommandParamNameArg(PC,
+                                    Arg.getLocation(),
+                                    Arg.getEndLocation(),
+                                    Arg.getText());
 }
 
-BlockCommandComment *Parser::parseBlockCommandArgs(
-    BlockCommandComment *BC,
-    TextTokenRetokenizer &Retokenizer,
-    unsigned NumArgs) {
+void Parser::parseTParamCommandArgs(TParamCommandComment *TPC,
+                                    TextTokenRetokenizer &Retokenizer) {
+  Token Arg;
+  if (Retokenizer.lexWord(Arg))
+    S.actOnTParamCommandParamNameArg(TPC,
+                                     Arg.getLocation(),
+                                     Arg.getEndLocation(),
+                                     Arg.getText());
+}
+
+void Parser::parseBlockCommandArgs(BlockCommandComment *BC,
+                                   TextTokenRetokenizer &Retokenizer,
+                                   unsigned NumArgs) {
   typedef BlockCommandComment::Argument Argument;
   Argument *Args =
       new (Allocator.Allocate<Argument>(NumArgs)) Argument[NumArgs];
@@ -59,64 +301,82 @@
     ParsedArgs++;
   }
 
-  return S.actOnBlockCommandArgs(BC, llvm::makeArrayRef(Args, ParsedArgs));
+  S.actOnBlockCommandArgs(BC, llvm::makeArrayRef(Args, ParsedArgs));
 }
 
 BlockCommandComment *Parser::parseBlockCommand() {
   assert(Tok.is(tok::command));
 
   ParamCommandComment *PC;
+  TParamCommandComment *TPC;
   BlockCommandComment *BC;
   bool IsParam = false;
+  bool IsTParam = false;
   unsigned NumArgs = 0;
-  if (S.isParamCommand(Tok.getCommandName())) {
+  if (Traits.isParamCommand(Tok.getCommandName())) {
     IsParam = true;
     PC = S.actOnParamCommandStart(Tok.getLocation(),
                                   Tok.getEndLocation(),
                                   Tok.getCommandName());
+  } if (Traits.isTParamCommand(Tok.getCommandName())) {
+    IsTParam = true;
+    TPC = S.actOnTParamCommandStart(Tok.getLocation(),
+                                    Tok.getEndLocation(),
+                                    Tok.getCommandName());
   } else {
-    NumArgs = S.getBlockCommandNumArgs(Tok.getCommandName());
+    NumArgs = Traits.getBlockCommandNumArgs(Tok.getCommandName());
     BC = S.actOnBlockCommandStart(Tok.getLocation(),
                                   Tok.getEndLocation(),
                                   Tok.getCommandName());
   }
   consumeToken();
 
-  if (Tok.is(tok::command) && S.isBlockCommand(Tok.getCommandName())) {
+  if (Tok.is(tok::command) && Traits.isBlockCommand(Tok.getCommandName())) {
     // Block command ahead.  We can't nest block commands, so pretend that this
     // command has an empty argument.
-    ParagraphComment *PC = S.actOnParagraphComment(
+    ParagraphComment *Paragraph = S.actOnParagraphComment(
                                 ArrayRef<InlineContentComment *>());
-    return S.actOnBlockCommandFinish(BC, PC);
+    if (IsParam) {
+      S.actOnParamCommandFinish(PC, Paragraph);
+      return PC;
+    } else if (IsTParam) {
+      S.actOnTParamCommandFinish(TPC, Paragraph);
+      return TPC;
+    } else {
+      S.actOnBlockCommandFinish(BC, Paragraph);
+      return BC;
+    }
   }
 
-  if (IsParam || NumArgs > 0) {
+  if (IsParam || IsTParam || NumArgs > 0) {
     // In order to parse command arguments we need to retokenize a few
     // following text tokens.
-    TextTokenRetokenizer Retokenizer(Allocator);
-    while (Tok.is(tok::text)) {
-      if (Retokenizer.addToken(Tok))
-        consumeToken();
-    }
+    TextTokenRetokenizer Retokenizer(Allocator, *this);
 
     if (IsParam)
-      PC = parseParamCommandArgs(PC, Retokenizer);
+      parseParamCommandArgs(PC, Retokenizer);
+    else if (IsTParam)
+      parseTParamCommandArgs(TPC, Retokenizer);
     else
-      BC = parseBlockCommandArgs(BC, Retokenizer, NumArgs);
+      parseBlockCommandArgs(BC, Retokenizer, NumArgs);
 
-    // Put back tokens we didn't use.
-    Token Text;
-    while (Retokenizer.lexText(Text))
-      putBack(Text);
+    Retokenizer.putBackLeftoverTokens();
   }
 
   BlockContentComment *Block = parseParagraphOrBlockCommand();
   // Since we have checked for a block command, we should have parsed a
   // paragraph.
-  if (IsParam)
-    return S.actOnParamCommandFinish(PC, cast<ParagraphComment>(Block));
-  else
-    return S.actOnBlockCommandFinish(BC, cast<ParagraphComment>(Block));
+  ParagraphComment *Paragraph = cast<ParagraphComment>(Block);
+  if (IsParam) {
+    S.actOnParamCommandFinish(PC, Paragraph);
+    return PC;
+  } else if (IsTParam) {
+    S.actOnTParamCommandFinish(TPC, Paragraph);
+    return TPC;
+  } else {
+    S.actOnBlockCommandFinish(BC, Paragraph);
+    return BC;
+  }
 }
 
 InlineCommandComment *Parser::parseInlineCommand() {
@@ -125,11 +385,7 @@
   const Token CommandTok = Tok;
   consumeToken();
 
-  TextTokenRetokenizer Retokenizer(Allocator);
-  while (Tok.is(tok::text)) {
-    if (Retokenizer.addToken(Tok))
-      consumeToken();
-  }
+  TextTokenRetokenizer Retokenizer(Allocator, *this);
 
   Token ArgTok;
   bool ArgTokValid = Retokenizer.lexWord(ArgTok);
@@ -148,9 +404,7 @@
                               CommandTok.getCommandName());
   }
 
-  Token Text;
-  while (Retokenizer.lexText(Text))
-    putBack(Text);
+  Retokenizer.putBackLeftoverTokens();
 
   return IC;
 }
@@ -198,18 +452,18 @@
     }
 
     case tok::html_greater:
-      HST = S.actOnHTMLStartTagFinish(HST,
-                                      copyArray(llvm::makeArrayRef(Attrs)),
-                                      Tok.getLocation(),
-                                      /* IsSelfClosing = */ false);
+      S.actOnHTMLStartTagFinish(HST,
+                                S.copyArray(llvm::makeArrayRef(Attrs)),
+                                Tok.getLocation(),
+                                /* IsSelfClosing = */ false);
       consumeToken();
       return HST;
 
     case tok::html_slash_greater:
-      HST = S.actOnHTMLStartTagFinish(HST,
-                                      copyArray(llvm::makeArrayRef(Attrs)),
-                                      Tok.getLocation(),
-                                      /* IsSelfClosing = */ true);
+      S.actOnHTMLStartTagFinish(HST,
+                                S.copyArray(llvm::makeArrayRef(Attrs)),
+                                Tok.getLocation(),
+                                /* IsSelfClosing = */ true);
       consumeToken();
       return HST;
 
@@ -225,17 +479,18 @@
           Tok.is(tok::html_slash_greater))
         continue;
 
-      return S.actOnHTMLStartTagFinish(HST,
-                                       copyArray(llvm::makeArrayRef(Attrs)),
-                                       SourceLocation(),
-                                       /* IsSelfClosing = */ false);
+      S.actOnHTMLStartTagFinish(HST,
+                                S.copyArray(llvm::makeArrayRef(Attrs)),
+                                SourceLocation(),
+                                /* IsSelfClosing = */ false);
+      return HST;
 
     default:
       // Not a token from an HTML start tag.  Thus HTML tag prematurely ended.
-      HST = S.actOnHTMLStartTagFinish(HST,
-                                      copyArray(llvm::makeArrayRef(Attrs)),
-                                      SourceLocation(),
-                                      /* IsSelfClosing = */ false);
+      S.actOnHTMLStartTagFinish(HST,
+                                S.copyArray(llvm::makeArrayRef(Attrs)),
+                                SourceLocation(),
+                                /* IsSelfClosing = */ false);
       bool StartLineInvalid;
       const unsigned StartLine = SourceMgr.getPresumedLineNumber(
                                                   HST->getLocation(),
@@ -286,12 +541,12 @@
       break; // Block content or EOF ahead, finish this parapgaph.
 
     case tok::command:
-      if (S.isBlockCommand(Tok.getCommandName())) {
+      if (Traits.isBlockCommand(Tok.getCommandName())) {
         if (Content.size() == 0)
           return parseBlockCommand();
         break; // Block command ahead, finish this parapgaph.
       }
-      if (S.isInlineCommand(Tok.getCommandName())) {
+      if (Traits.isInlineCommand(Tok.getCommandName())) {
         Content.push_back(parseInlineCommand());
         continue;
       }
@@ -343,7 +598,7 @@
     break;
   }
 
-  return S.actOnParagraphComment(copyArray(llvm::makeArrayRef(Content)));
+  return S.actOnParagraphComment(S.copyArray(llvm::makeArrayRef(Content)));
 }
 
 VerbatimBlockComment *Parser::parseVerbatimBlock() {
@@ -379,14 +634,14 @@
   }
 
   if (Tok.is(tok::verbatim_block_end)) {
-    VB = S.actOnVerbatimBlockFinish(VB, Tok.getLocation(),
-                                    Tok.getVerbatimBlockName(),
-                                    copyArray(llvm::makeArrayRef(Lines)));
+    S.actOnVerbatimBlockFinish(VB, Tok.getLocation(),
+                               Tok.getVerbatimBlockName(),
+                               S.copyArray(llvm::makeArrayRef(Lines)));
     consumeToken();
   } else {
     // Unterminated \\verbatim block
-    VB = S.actOnVerbatimBlockFinish(VB, SourceLocation(), "",
-                                    copyArray(llvm::makeArrayRef(Lines)));
+    S.actOnVerbatimBlockFinish(VB, SourceLocation(), "",
+                               S.copyArray(llvm::makeArrayRef(Lines)));
   }
 
   return VB;
@@ -460,7 +715,7 @@
     while (Tok.is(tok::newline))
       consumeToken();
   }
-  return S.actOnFullComment(copyArray(llvm::makeArrayRef(Blocks)));
+  return S.actOnFullComment(S.copyArray(llvm::makeArrayRef(Blocks)));
 }
 
 } // end namespace comments
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index bfc9b91..c39ee57 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -9,8 +9,9 @@
 
 #include "clang/AST/CommentSema.h"
 #include "clang/AST/CommentDiagnostic.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringSwitch.h"
 
@@ -18,13 +19,18 @@
 namespace comments {
 
 Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
-           DiagnosticsEngine &Diags) :
-    Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), ThisDecl(NULL),
-    IsThisDeclInspected(false) {
+           DiagnosticsEngine &Diags, const CommandTraits &Traits) :
+    Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
+    ThisDeclInfo(NULL), BriefCommand(NULL), ReturnsCommand(NULL) {
 }
 
 void Sema::setDecl(const Decl *D) {
-  ThisDecl = D;
+  if (!D)
+    return;
+
+  ThisDeclInfo = new (Allocator) DeclInfo;
+  ThisDeclInfo->ThisDecl = D;
+  ThisDeclInfo->IsFilled = false;
 }
 
 ParagraphComment *Sema::actOnParagraphComment(
@@ -38,19 +44,17 @@
   return new (Allocator) BlockCommandComment(LocBegin, LocEnd, Name);
 }
 
-BlockCommandComment *Sema::actOnBlockCommandArgs(
-                              BlockCommandComment *Command,
-                              ArrayRef<BlockCommandComment::Argument> Args) {
+void Sema::actOnBlockCommandArgs(BlockCommandComment *Command,
+                                 ArrayRef<BlockCommandComment::Argument> Args) {
   Command->setArgs(Args);
-  return Command;
 }
 
-BlockCommandComment *Sema::actOnBlockCommandFinish(
-                              BlockCommandComment *Command,
-                              ParagraphComment *Paragraph) {
+void Sema::actOnBlockCommandFinish(BlockCommandComment *Command,
+                                   ParagraphComment *Paragraph) {
   Command->setParagraph(Paragraph);
   checkBlockCommandEmptyParagraph(Command);
-  return Command;
+  checkBlockCommandDuplicate(Command);
+  checkReturnsCommand(Command);
 }
 
 ParamCommandComment *Sema::actOnParamCommandStart(SourceLocation LocBegin,
@@ -67,11 +71,10 @@
   return Command;
 }
 
-ParamCommandComment *Sema::actOnParamCommandDirectionArg(
-                                                ParamCommandComment *Command,
-                                                SourceLocation ArgLocBegin,
-                                                SourceLocation ArgLocEnd,
-                                                StringRef Arg) {
+void Sema::actOnParamCommandDirectionArg(ParamCommandComment *Command,
+                                         SourceLocation ArgLocBegin,
+                                         SourceLocation ArgLocEnd,
+                                         StringRef Arg) {
   ParamCommandComment::PassDirection Direction;
   std::string ArgLower = Arg.lower();
   // TODO: optimize: lower Name first (need an API in SmallString for that),
@@ -121,14 +124,12 @@
         << ArgRange;
   }
   Command->setDirection(Direction, /* Explicit = */ true);
-  return Command;
 }
 
-ParamCommandComment *Sema::actOnParamCommandParamNameArg(
-                                                ParamCommandComment *Command,
-                                                SourceLocation ArgLocBegin,
-                                                SourceLocation ArgLocEnd,
-                                                StringRef Arg) {
+void Sema::actOnParamCommandParamNameArg(ParamCommandComment *Command,
+                                         SourceLocation ArgLocBegin,
+                                         SourceLocation ArgLocEnd,
+                                         StringRef Arg) {
   // Parser will not feed us more arguments than needed.
   assert(Command->getNumArgs() == 0);
 
@@ -144,7 +145,7 @@
 
   if (!isFunctionDecl()) {
     // We already warned that this \\param is not attached to a function decl.
-    return Command;
+    return;
   }
 
   ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
@@ -153,13 +154,26 @@
   const unsigned ResolvedParamIndex = resolveParmVarReference(Arg, ParamVars);
   if (ResolvedParamIndex != ParamCommandComment::InvalidParamIndex) {
     Command->setParamIndex(ResolvedParamIndex);
-    return Command;
+    if (ParamVarDocs[ResolvedParamIndex]) {
+      SourceRange ArgRange(ArgLocBegin, ArgLocEnd);
+      Diag(ArgLocBegin, diag::warn_doc_param_duplicate)
+        << Arg << ArgRange;
+      ParamCommandComment *PrevCommand = ParamVarDocs[ResolvedParamIndex];
+      Diag(PrevCommand->getLocation(), diag::note_doc_param_previous)
+        << PrevCommand->getParamNameRange();
+    }
+    ParamVarDocs[ResolvedParamIndex] = Command;
+    return;
   }
 
   SourceRange ArgRange(ArgLocBegin, ArgLocEnd);
   Diag(ArgLocBegin, diag::warn_doc_param_not_found)
     << Arg << ArgRange;
 
+  // No parameters -- can't suggest a correction.
+  if (ParamVars.size() == 0)
+    return;
+
   unsigned CorrectedParamIndex = ParamCommandComment::InvalidParamIndex;
   if (ParamVars.size() == 1) {
     // If function has only one parameter then only that parameter
@@ -177,14 +191,96 @@
         << FixItHint::CreateReplacement(ArgRange, CorrectedII->getName());
   }
 
+  return;
+}
+
+void Sema::actOnParamCommandFinish(ParamCommandComment *Command,
+                                   ParagraphComment *Paragraph) {
+  Command->setParagraph(Paragraph);
+  checkBlockCommandEmptyParagraph(Command);
+}
+
+TParamCommandComment *Sema::actOnTParamCommandStart(SourceLocation LocBegin,
+                                                    SourceLocation LocEnd,
+                                                    StringRef Name) {
+  TParamCommandComment *Command =
+      new (Allocator) TParamCommandComment(LocBegin, LocEnd, Name);
+
+  if (!isTemplateOrSpecialization())
+    Diag(Command->getLocation(),
+         diag::warn_doc_tparam_not_attached_to_a_template_decl)
+      << Command->getCommandNameRange();
+
   return Command;
 }
 
-ParamCommandComment *Sema::actOnParamCommandFinish(ParamCommandComment *Command,
-                                                   ParagraphComment *Paragraph) {
+void Sema::actOnTParamCommandParamNameArg(TParamCommandComment *Command,
+                                          SourceLocation ArgLocBegin,
+                                          SourceLocation ArgLocEnd,
+                                          StringRef Arg) {
+  // Parser will not feed us more arguments than needed.
+  assert(Command->getNumArgs() == 0);
+
+  typedef BlockCommandComment::Argument Argument;
+  Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin,
+                                                     ArgLocEnd),
+                                         Arg);
+  Command->setArgs(llvm::makeArrayRef(A, 1));
+
+  if (!isTemplateOrSpecialization()) {
+    // We already warned that this \\tparam is not attached to a template decl.
+    return;
+  }
+
+  const TemplateParameterList *TemplateParameters =
+      ThisDeclInfo->TemplateParameters;
+  SmallVector<unsigned, 2> Position;
+  if (resolveTParamReference(Arg, TemplateParameters, &Position)) {
+    Command->setPosition(copyArray(llvm::makeArrayRef(Position)));
+    llvm::StringMap<TParamCommandComment *>::iterator PrevCommandIt =
+        TemplateParameterDocs.find(Arg);
+    if (PrevCommandIt != TemplateParameterDocs.end()) {
+      SourceRange ArgRange(ArgLocBegin, ArgLocEnd);
+      Diag(ArgLocBegin, diag::warn_doc_tparam_duplicate)
+        << Arg << ArgRange;
+      TParamCommandComment *PrevCommand = PrevCommandIt->second;
+      Diag(PrevCommand->getLocation(), diag::note_doc_tparam_previous)
+        << PrevCommand->getParamNameRange();
+    }
+    TemplateParameterDocs[Arg] = Command;
+    return;
+  }
+
+  SourceRange ArgRange(ArgLocBegin, ArgLocEnd);
+  Diag(ArgLocBegin, diag::warn_doc_tparam_not_found)
+    << Arg << ArgRange;
+
+  if (!TemplateParameters || TemplateParameters->size() == 0)
+    return;
+
+  StringRef CorrectedName;
+  if (TemplateParameters->size() == 1) {
+    const NamedDecl *Param = TemplateParameters->getParam(0);
+    const IdentifierInfo *II = Param->getIdentifier();
+    if (II)
+      CorrectedName = II->getName();
+  } else {
+    CorrectedName = correctTypoInTParamReference(Arg, TemplateParameters);
+  }
+
+  if (!CorrectedName.empty()) {
+    Diag(ArgLocBegin, diag::note_doc_tparam_name_suggestion)
+      << CorrectedName
+      << FixItHint::CreateReplacement(ArgRange, CorrectedName);
+  }
+
+  return;
+}
+
+void Sema::actOnTParamCommandFinish(TParamCommandComment *Command,
+                                    ParagraphComment *Paragraph) {
   Command->setParagraph(Paragraph);
   checkBlockCommandEmptyParagraph(Command);
-  return Command;
 }
 
 InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
@@ -247,14 +343,13 @@
   return new (Allocator) VerbatimBlockLineComment(Loc, Text);
 }
 
-VerbatimBlockComment *Sema::actOnVerbatimBlockFinish(
+void Sema::actOnVerbatimBlockFinish(
                             VerbatimBlockComment *Block,
                             SourceLocation CloseNameLocBegin,
                             StringRef CloseName,
                             ArrayRef<VerbatimBlockLineComment *> Lines) {
   Block->setCloseName(CloseName, CloseNameLocBegin);
   Block->setLines(Lines);
-  return Block;
 }
 
 VerbatimLineComment *Sema::actOnVerbatimLine(SourceLocation LocBegin,
@@ -274,7 +369,7 @@
   return new (Allocator) HTMLStartTagComment(LocBegin, TagName);
 }
 
-HTMLStartTagComment *Sema::actOnHTMLStartTagFinish(
+void Sema::actOnHTMLStartTagFinish(
                               HTMLStartTagComment *Tag,
                               ArrayRef<HTMLStartTagComment::Attribute> Attrs,
                               SourceLocation GreaterLoc,
@@ -285,7 +380,6 @@
     Tag->setSelfClosing();
   else if (!isHTMLEndTagForbidden(Tag->getTagName()))
     HTMLOpenTags.push_back(Tag);
-  return Tag;
 }
 
 HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
@@ -351,8 +445,7 @@
 
 FullComment *Sema::actOnFullComment(
                               ArrayRef<BlockContentComment *> Blocks) {
-  SmallVector<ParamCommandComment *, 8> Params;
-  return new (Allocator) FullComment(Blocks);
+  return new (Allocator) FullComment(Blocks, ThisDeclInfo);
 }
 
 void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
@@ -369,39 +462,98 @@
   }
 }
 
-bool Sema::isFunctionDecl() {
-  if (IsThisDeclInspected)
-    return IsFunctionDecl;
+void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
+  if (!Traits.isReturnsCommand(Command->getCommandName()))
+    return;
+  if (isFunctionDecl()) {
+    if (ThisDeclInfo->ResultType->isVoidType()) {
+      unsigned DiagKind;
+      switch (ThisDeclInfo->ThisDecl->getKind()) {
+      default:
+        if (ThisDeclInfo->IsObjCMethod)
+          DiagKind = 3;
+        else
+          DiagKind = 0;
+        break;
+      case Decl::CXXConstructor:
+        DiagKind = 1;
+        break;
+      case Decl::CXXDestructor:
+        DiagKind = 2;
+        break;
+      }
+      Diag(Command->getLocation(),
+           diag::warn_doc_returns_attached_to_a_void_function)
+        << Command->getCommandName()
+        << DiagKind
+        << Command->getSourceRange();
+    }
+    return;
+  }
+  Diag(Command->getLocation(),
+       diag::warn_doc_returns_not_attached_to_a_function_decl)
+    << Command->getCommandName()
+    << Command->getSourceRange();
+}
 
-  inspectThisDecl();
-  return IsFunctionDecl;
+void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
+  StringRef Name = Command->getCommandName();
+  const BlockCommandComment *PrevCommand = NULL;
+  if (Traits.isBriefCommand(Name)) {
+    if (!BriefCommand) {
+      BriefCommand = Command;
+      return;
+    }
+    PrevCommand = BriefCommand;
+  } else if (Traits.isReturnsCommand(Name)) {
+    if (!ReturnsCommand) {
+      ReturnsCommand = Command;
+      return;
+    }
+    PrevCommand = ReturnsCommand;
+  } else {
+    // We don't want to check this command for duplicates.
+    return;
+  }
+  Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate)
+      << Name
+      << Command->getSourceRange();
+  if (Name == PrevCommand->getCommandName())
+    Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous)
+        << PrevCommand->getCommandName()
+        << Command->getSourceRange();
+  else
+    Diag(PrevCommand->getLocation(),
+         diag::note_doc_block_command_previous_alias)
+        << PrevCommand->getCommandName()
+        << Name;
+}
+
+bool Sema::isFunctionDecl() {
+  if (!ThisDeclInfo)
+    return false;
+  if (!ThisDeclInfo->IsFilled)
+    inspectThisDecl();
+  return ThisDeclInfo->getKind() == DeclInfo::FunctionKind;
+}
+
+bool Sema::isTemplateOrSpecialization() {
+  if (!ThisDeclInfo)
+    return false;
+  if (!ThisDeclInfo->IsFilled)
+    inspectThisDecl();
+  return ThisDeclInfo->getTemplateKind() != DeclInfo::NotTemplate;
 }
 
 ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
-  if (IsThisDeclInspected)
-    return ParamVars;
-
-  inspectThisDecl();
-  return ParamVars;
+  if (!ThisDeclInfo->IsFilled)
+    inspectThisDecl();
+  return ThisDeclInfo->ParamVars;
 }
 
 void Sema::inspectThisDecl() {
-  if (!ThisDecl) {
-    IsFunctionDecl = false;
-    ParamVars = ArrayRef<const ParmVarDecl *>();
-  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ThisDecl)) {
-    IsFunctionDecl = true;
-    ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
-                                              FD->getNumParams());
-  } else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ThisDecl)) {
-    IsFunctionDecl = true;
-    ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
-                                              MD->param_size());
-  } else {
-    IsFunctionDecl = false;
-    ParamVars = ArrayRef<const ParmVarDecl *>();
-  }
-  IsThisDeclInspected = true;
+  ThisDeclInfo->fill();
+  ParamVarDocs.resize(ThisDeclInfo->ParamVars.size(), NULL);
 }
 
 unsigned Sema::resolveParmVarReference(StringRef Name,
@@ -414,78 +566,141 @@
   return ParamCommandComment::InvalidParamIndex;
 }
 
+namespace {
+class SimpleTypoCorrector {
+  StringRef Typo;
+  const unsigned MaxEditDistance;
+
+  const NamedDecl *BestDecl;
+  unsigned BestEditDistance;
+  unsigned BestIndex;
+  unsigned NextIndex;
+
+public:
+  SimpleTypoCorrector(StringRef Typo) :
+      Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
+      BestDecl(NULL), BestEditDistance(MaxEditDistance + 1),
+      BestIndex(0), NextIndex(0)
+  { }
+
+  void addDecl(const NamedDecl *ND);
+
+  const NamedDecl *getBestDecl() const {
+    if (BestEditDistance > MaxEditDistance)
+      return NULL;
+
+    return BestDecl;
+  }
+
+  unsigned getBestDeclIndex() const {
+    assert(getBestDecl());
+    return BestIndex;
+  }
+};
+
+void SimpleTypoCorrector::addDecl(const NamedDecl *ND) {
+  unsigned CurrIndex = NextIndex++;
+
+  const IdentifierInfo *II = ND->getIdentifier();
+  if (!II)
+    return;
+
+  StringRef Name = II->getName();
+  unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
+  if (MinPossibleEditDistance > 0 &&
+      Typo.size() / MinPossibleEditDistance < 3)
+    return;
+
+  unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
+  if (EditDistance < BestEditDistance) {
+    BestEditDistance = EditDistance;
+    BestDecl = ND;
+    BestIndex = CurrIndex;
+  }
+}
+} // unnamed namespace
+
 unsigned Sema::correctTypoInParmVarReference(
                                     StringRef Typo,
                                     ArrayRef<const ParmVarDecl *> ParamVars) {
-  const unsigned MaxEditDistance = (Typo.size() + 2) / 3;
-  unsigned BestPVDIndex = 0;
-  unsigned BestEditDistance = MaxEditDistance + 1;
-  for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) {
-    const IdentifierInfo *II = ParamVars[i]->getIdentifier();
-    if (II) {
-      StringRef Name = II->getName();
-      unsigned MinPossibleEditDistance =
-        abs((int)Name.size() - (int)Typo.size());
-      if (MinPossibleEditDistance > 0 &&
-          Typo.size() / MinPossibleEditDistance < 3)
-        continue;
-
-      unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
-      if (EditDistance < BestEditDistance) {
-        BestEditDistance = EditDistance;
-        BestPVDIndex = i;
-      }
-    }
-  }
-
-  if (BestEditDistance <= MaxEditDistance)
-    return BestPVDIndex;
+  SimpleTypoCorrector Corrector(Typo);
+  for (unsigned i = 0, e = ParamVars.size(); i != e; ++i)
+    Corrector.addDecl(ParamVars[i]);
+  if (Corrector.getBestDecl())
+    return Corrector.getBestDeclIndex();
   else
     return ParamCommandComment::InvalidParamIndex;;
 }
 
-// TODO: tablegen
-bool Sema::isBlockCommand(StringRef Name) {
-  return llvm::StringSwitch<bool>(Name)
-      .Cases("brief", "short", true)
-      .Case("result", true)
-      .Case("return", true)
-      .Case("returns", true)
-      .Case("author", true)
-      .Case("authors", true)
-      .Case("pre", true)
-      .Case("post", true)
-      .Default(false) || isParamCommand(Name);
+namespace {
+bool ResolveTParamReferenceHelper(
+                            StringRef Name,
+                            const TemplateParameterList *TemplateParameters,
+                            SmallVectorImpl<unsigned> *Position) {
+  for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) {
+    const NamedDecl *Param = TemplateParameters->getParam(i);
+    const IdentifierInfo *II = Param->getIdentifier();
+    if (II && II->getName() == Name) {
+      Position->push_back(i);
+      return true;
+    }
+
+    if (const TemplateTemplateParmDecl *TTP =
+            dyn_cast<TemplateTemplateParmDecl>(Param)) {
+      Position->push_back(i);
+      if (ResolveTParamReferenceHelper(Name, TTP->getTemplateParameters(),
+                                       Position))
+        return true;
+      Position->pop_back();
+    }
+  }
+  return false;
+}
+} // unnamed namespace
+
+bool Sema::resolveTParamReference(
+                            StringRef Name,
+                            const TemplateParameterList *TemplateParameters,
+                            SmallVectorImpl<unsigned> *Position) {
+  Position->clear();
+  if (!TemplateParameters)
+    return false;
+
+  return ResolveTParamReferenceHelper(Name, TemplateParameters, Position);
 }
 
-bool Sema::isParamCommand(StringRef Name) {
-  return llvm::StringSwitch<bool>(Name)
-      .Case("param", true)
-      .Case("arg", true)
-      .Default(false);
-}
+namespace {
+void CorrectTypoInTParamReferenceHelper(
+                            const TemplateParameterList *TemplateParameters,
+                            SimpleTypoCorrector &Corrector) {
+  for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) {
+    const NamedDecl *Param = TemplateParameters->getParam(i);
+    Corrector.addDecl(Param);
 
-unsigned Sema::getBlockCommandNumArgs(StringRef Name) {
-  return llvm::StringSwitch<unsigned>(Name)
-      .Cases("brief", "short", 0)
-      .Case("pre", 0)
-      .Case("post", 0)
-      .Case("author", 0)
-      .Case("authors", 0)
-      .Default(0);
+    if (const TemplateTemplateParmDecl *TTP =
+            dyn_cast<TemplateTemplateParmDecl>(Param))
+      CorrectTypoInTParamReferenceHelper(TTP->getTemplateParameters(),
+                                         Corrector);
+  }
 }
+} // unnamed namespace
 
-bool Sema::isInlineCommand(StringRef Name) const {
-  return llvm::StringSwitch<bool>(Name)
-      .Case("b", true)
-      .Cases("c", "p", true)
-      .Cases("a", "e", "em", true)
-      .Default(false);
+StringRef Sema::correctTypoInTParamReference(
+                            StringRef Typo,
+                            const TemplateParameterList *TemplateParameters) {
+  SimpleTypoCorrector Corrector(Typo);
+  CorrectTypoInTParamReferenceHelper(TemplateParameters, Corrector);
+  if (const NamedDecl *ND = Corrector.getBestDecl()) {
+    const IdentifierInfo *II = ND->getIdentifier();
+    assert(II && "SimpleTypoCorrector should not return this decl");
+    return II->getName();
+  }
+  return StringRef();
 }
 
 InlineCommandComment::RenderKind
 Sema::getInlineCommandRenderKind(StringRef Name) const {
-  assert(isInlineCommand(Name));
+  assert(Traits.isInlineCommand(Name));
 
   return llvm::StringSwitch<InlineCommandComment::RenderKind>(Name)
       .Case("b", InlineCommandComment::RenderBold)
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c98853a..d5b0be3 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -710,6 +710,10 @@
   if (llvm::Optional<Visibility> V = getVisibilityOf(this))
     return V;
 
+  // The visibility of a template is stored in the templated decl.
+  if (const TemplateDecl *TD = dyn_cast<TemplateDecl>(this))
+    return getVisibilityOf(TD->getTemplatedDecl());
+
   // If there wasn't explicit visibility there, and this is a
   // specialization of a class template, check for visibility
   // on the pattern.
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 217b27a..2f21e4c 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -344,8 +344,8 @@
     if (Cands[Best].second.compatiblyIncludes(Cands[I].second))
       Best = I;
   
-  for (unsigned I = 1; I != N; ++I)
-    if (Cands[Best].second.compatiblyIncludes(Cands[I].second))
+  for (unsigned I = 0; I != N; ++I)
+    if (I != Best && Cands[Best].second.compatiblyIncludes(Cands[I].second))
       return 0;
   
   return Cands[Best].first;
@@ -1294,15 +1294,20 @@
 }
 
 CXXMethodDecl *
-CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD) {
+CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
+                                             bool MayBeBase) {
   if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl())
     return this;
 
   // Lookup doesn't work for destructors, so handle them separately.
   if (isa<CXXDestructorDecl>(this)) {
     CXXMethodDecl *MD = RD->getDestructor();
-    if (MD && recursivelyOverrides(MD, this))
-      return MD;
+    if (MD) {
+      if (recursivelyOverrides(MD, this))
+        return MD;
+      if (MayBeBase && recursivelyOverrides(this, MD))
+        return MD;
+    }
     return NULL;
   }
 
@@ -1313,6 +1318,8 @@
       continue;
     if (recursivelyOverrides(MD, this))
       return MD;
+    if (MayBeBase && recursivelyOverrides(this, MD))
+      return MD;
   }
 
   for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 39f0906..4d48ad8 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -363,9 +363,12 @@
   return NULL;
 }
 
+// Will search "local" class/category implementations for a method decl.
+// If failed, then we search in class's root for an instance method.
+// Returns 0 if no method is found.
 ObjCMethodDecl *ObjCInterfaceDecl::lookupPrivateMethod(
                                    const Selector &Sel,
-                                   bool Instance) {
+                                   bool Instance) const {
   // FIXME: Should make sure no callers ever do this.
   if (!hasDefinition())
     return 0;
@@ -377,7 +380,23 @@
   if (ObjCImplementationDecl *ImpDecl = getImplementation())
     Method = Instance ? ImpDecl->getInstanceMethod(Sel) 
                       : ImpDecl->getClassMethod(Sel);
-  
+
+  // Look through local category implementations associated with the class.
+  if (!Method)
+    Method = Instance ? getCategoryInstanceMethod(Sel)
+                      : getCategoryClassMethod(Sel);
+
+  // Before we give up, check if the selector is an instance method.
+  // But only in the root. This matches gcc's behavior and what the
+  // runtime expects.
+  if (!Instance && !Method && !getSuperClass()) {
+    Method = lookupInstanceMethod(Sel);
+    // Look through local category implementations associated
+    // with the root class.
+    if (!Method)
+      Method = lookupPrivateMethod(Sel, true);
+  }
+
   if (!Method && getSuperClass())
     return getSuperClass()->lookupPrivateMethod(Sel, Instance);
   return Method;
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 10f3894..4cba2b0 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -26,7 +26,6 @@
 namespace {
   class DeclPrinter : public DeclVisitor<DeclPrinter> {
     raw_ostream &Out;
-    ASTContext &Context;
     PrintingPolicy Policy;
     unsigned Indentation;
     bool PrintInstantiation;
@@ -38,11 +37,9 @@
     void Print(AccessSpecifier AS);
 
   public:
-    DeclPrinter(raw_ostream &Out, ASTContext &Context,
-                const PrintingPolicy &Policy,
-                unsigned Indentation = 0,
-                bool PrintInstantiation = false)
-      : Out(Out), Context(Context), Policy(Policy), Indentation(Indentation),
+    DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
+                unsigned Indentation = 0, bool PrintInstantiation = false)
+      : Out(Out), Policy(Policy), Indentation(Indentation),
         PrintInstantiation(PrintInstantiation) { }
 
     void VisitDeclContext(DeclContext *DC, bool Indent = true);
@@ -96,7 +93,7 @@
 
 void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
                  unsigned Indentation, bool PrintInstantiation) const {
-  DeclPrinter Printer(Out, getASTContext(), Policy, Indentation, PrintInstantiation);
+  DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation);
   Printer.Visit(const_cast<Decl*>(this));
 }
 
@@ -114,6 +111,8 @@
       BaseType = FTy->getResultType();
     else if (const VectorType *VTy = BaseType->getAs<VectorType>())
       BaseType = VTy->getElementType();
+    else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
+      BaseType = RTy->getPointeeType();
     else
       llvm_unreachable("Unknown declarator!");
   }
@@ -169,12 +168,18 @@
     DC = DC->getParent();
   
   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
-  DeclPrinter Printer(llvm::errs(), Ctx, Ctx.getPrintingPolicy(), 0);
+  DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), 0);
   Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
 }
 
 void Decl::dump() const {
-  print(llvm::errs());
+  dump(llvm::errs());
+}
+
+void Decl::dump(raw_ostream &Out) const {
+  PrintingPolicy Policy = getASTContext().getPrintingPolicy();
+  Policy.DumpSourceManager = &getASTContext().getSourceManager();
+  print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ true);
 }
 
 raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
@@ -187,8 +192,8 @@
   if (D->hasAttrs()) {
     AttrVec &Attrs = D->getAttrs();
     for (AttrVec::const_iterator i=Attrs.begin(), e=Attrs.end(); i!=e; ++i) {
-        Attr *A = *i;
-        A->printPretty(Out, Context);
+      Attr *A = *i;
+      A->printPretty(Out, Policy);
     }
   }
 }
@@ -215,6 +220,9 @@
 //----------------------------------------------------------------------------
 
 void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
+  if (Policy.TerseOutput)
+    return;
+
   if (Indent)
     Indentation += Policy.Indentation;
 
@@ -227,7 +235,7 @@
     if (isa<ObjCIvarDecl>(*D))
       continue;
 
-    if (!Policy.Dump) {
+    if (!Policy.DumpSourceManager) {
       // Skip over implicit declarations in pretty-printing mode.
       if (D->isImplicit()) continue;
       // FIXME: Ugly hack so we don't pretty-print the builtin declaration
@@ -377,7 +385,7 @@
   Out << *D;
   if (Expr *Init = D->getInitExpr()) {
     Out << " = ";
-    Init->printPretty(Out, Context, 0, Policy, Indentation);
+    Init->printPretty(Out, 0, Policy, Indentation);
   }
 }
 
@@ -416,7 +424,7 @@
     Proto += "(";
     if (FT) {
       llvm::raw_string_ostream POut(Proto);
-      DeclPrinter ParamPrinter(POut, Context, SubPolicy, Indentation);
+      DeclPrinter ParamPrinter(POut, SubPolicy, Indentation);
       for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
         if (i) POut << ", ";
         ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
@@ -436,13 +444,12 @@
 
     Proto += ")";
     
-    if (FT && FT->getTypeQuals()) {
-      unsigned TypeQuals = FT->getTypeQuals();
-      if (TypeQuals & Qualifiers::Const)
+    if (FT) {
+      if (FT->isConst())
         Proto += " const";
-      if (TypeQuals & Qualifiers::Volatile) 
+      if (FT->isVolatile())
         Proto += " volatile";
-      if (TypeQuals & Qualifiers::Restrict)
+      if (FT->isRestrict())
         Proto += " restrict";
     }
 
@@ -463,7 +470,7 @@
       if (FT->getExceptionSpecType() == EST_ComputedNoexcept) {
         Proto += "(";
         llvm::raw_string_ostream EOut(Proto);
-        FT->getNoexceptExpr()->printPretty(EOut, Context, 0, SubPolicy,
+        FT->getNoexceptExpr()->printPretty(EOut, 0, SubPolicy,
                                            Indentation);
         EOut.flush();
         Proto += EOut.str();
@@ -519,7 +526,7 @@
             SimpleInit = Init;
           
           if (SimpleInit)
-            SimpleInit->printPretty(Out, Context, 0, Policy, Indentation);
+            SimpleInit->printPretty(Out, 0, Policy, Indentation);
           else {
             for (unsigned I = 0; I != NumArgs; ++I) {
               if (isa<CXXDefaultArgExpr>(Args[I]))
@@ -527,7 +534,7 @@
               
               if (I)
                 Out << ", ";
-              Args[I]->printPretty(Out, Context, 0, Policy, Indentation);
+              Args[I]->printPretty(Out, 0, Policy, Indentation);
             }
           }
         }
@@ -546,12 +553,12 @@
     Out << " = 0";
   else if (D->isDeletedAsWritten())
     Out << " = delete";
-  else if (D->doesThisDeclarationHaveABody()) {
+  else if (D->doesThisDeclarationHaveABody() && !Policy.TerseOutput) {
     if (!D->hasPrototype() && D->getNumParams()) {
       // This is a K&R function definition, so we need to print the
       // parameters.
       Out << '\n';
-      DeclPrinter ParamPrinter(Out, Context, SubPolicy, Indentation);
+      DeclPrinter ParamPrinter(Out, SubPolicy, Indentation);
       Indentation += Policy.Indentation;
       for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
         Indent();
@@ -562,7 +569,7 @@
     } else
       Out << ' ';
 
-    D->getBody()->printPretty(Out, Context, 0, SubPolicy, Indentation);
+    D->getBody()->printPretty(Out, 0, SubPolicy, Indentation);
     Out << '\n';
   }
 }
@@ -577,7 +584,7 @@
 
   if (D->isBitField()) {
     Out << " : ";
-    D->getBitWidth()->printPretty(Out, Context, 0, Policy, Indentation);
+    D->getBitWidth()->printPretty(Out, 0, Policy, Indentation);
   }
 
   Expr *Init = D->getInClassInitializer();
@@ -586,7 +593,7 @@
       Out << " ";
     else
       Out << " = ";
-    Init->printPretty(Out, Context, 0, Policy, Indentation);
+    Init->printPretty(Out, 0, Policy, Indentation);
   }
   prettyPrintAttributes(D);
 }
@@ -622,7 +629,7 @@
       else if (D->getInitStyle() == VarDecl::CInit) {
         Out << " = ";
       }
-      Init->printPretty(Out, Context, 0, Policy, Indentation);
+      Init->printPretty(Out, 0, Policy, Indentation);
       if (D->getInitStyle() == VarDecl::CallInit)
         Out << ")";
     }
@@ -636,7 +643,7 @@
 
 void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
   Out << "__asm (";
-  D->getAsmString()->printPretty(Out, Context, 0, Policy, Indentation);
+  D->getAsmString()->printPretty(Out, 0, Policy, Indentation);
   Out << ")";
 }
 
@@ -647,9 +654,9 @@
 
 void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
   Out << "static_assert(";
-  D->getAssertExpr()->printPretty(Out, Context, 0, Policy, Indentation);
+  D->getAssertExpr()->printPretty(Out, 0, Policy, Indentation);
   Out << ", ";
-  D->getMessage()->printPretty(Out, Context, 0, Policy, Indentation);
+  D->getMessage()->printPretty(Out, 0, Policy, Indentation);
   Out << ")";
 }
 
@@ -783,8 +790,7 @@
         Args->get(i).print(Policy, Out);
       } else if (NTTP->hasDefaultArgument()) {
         Out << " = ";
-        NTTP->getDefaultArgument()->printPretty(Out, Context, 0, Policy,
-                                                Indentation);
+        NTTP->getDefaultArgument()->printPretty(Out, 0, Policy, Indentation);
       }
     } else if (const TemplateTemplateParmDecl *TTPD =
                  dyn_cast<TemplateTemplateParmDecl>(Param)) {
@@ -868,7 +874,7 @@
 
   if (OMD->getBody()) {
     Out << ' ';
-    OMD->getBody()->printPretty(Out, Context, 0, Policy);
+    OMD->getBody()->printPretty(Out, 0, Policy);
     Out << '\n';
   }
 }
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 5aebc2b..a7e8999 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -43,7 +43,8 @@
                               unsigned NumParams, SourceLocation RAngleLoc) {
   unsigned Size = sizeof(TemplateParameterList) 
                 + sizeof(NamedDecl *) * NumParams;
-  unsigned Align = llvm::AlignOf<TemplateParameterList>::Alignment;
+  unsigned Align = std::max(llvm::alignOf<TemplateParameterList>(),
+                            llvm::alignOf<NamedDecl*>());
   void *Mem = C.Allocate(Size, Align);
   return new (Mem) TemplateParameterList(TemplateLoc, LAngleLoc, Params,
                                          NumParams, RAngleLoc);
diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp
index c5b3c68..84f3fc4 100644
--- a/lib/AST/DumpXML.cpp
+++ b/lib/AST/DumpXML.cpp
@@ -971,9 +971,9 @@
   }
 
   void visitFunctionProtoTypeAttrs(FunctionProtoType *T) {
-    setFlag("const", T->getTypeQuals() & Qualifiers::Const);
-    setFlag("volatile", T->getTypeQuals() & Qualifiers::Volatile);
-    setFlag("restrict", T->getTypeQuals() & Qualifiers::Restrict);
+    setFlag("const", T->isConst());
+    setFlag("volatile", T->isVolatile());
+    setFlag("restrict", T->isRestrict());
   }
   void visitFunctionProtoTypeChildren(FunctionProtoType *T) {
     push("parameters");
@@ -1023,7 +1023,7 @@
 }
 
 void Decl::dumpXML() const {
-  dumpXML(llvm::errs());
+  dump(llvm::errs());
 }
 
 void Decl::dumpXML(raw_ostream &out) const {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 47b5625..7e82382 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -211,7 +211,7 @@
     if ((Ctx.getLangOpts().CPlusPlus0x ?
            Var->getType()->isLiteralType() :
            Var->getType()->isIntegralOrEnumerationType()) &&
-        (Var->getType().getCVRQualifiers() == Qualifiers::Const ||
+        (Var->getType().isConstQualified() ||
          Var->getType()->isReferenceType())) {
       if (const Expr *Init = Var->getAnyInitializer())
         if (Init->isValueDependent()) {
@@ -440,10 +440,10 @@
     POut << ")";
 
     if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
-      Qualifiers ThisQuals = Qualifiers::fromCVRMask(MD->getTypeQualifiers());
-      if (ThisQuals.hasConst())
+      const FunctionType *FT = cast<FunctionType>(MD->getType().getTypePtr());
+      if (FT->isConst())
         POut << " const";
-      if (ThisQuals.hasVolatile())
+      if (FT->isVolatile())
         POut << " volatile";
       RefQualifierKind Ref = MD->getRefQualifier();
       if (Ref == RQ_LValue)
@@ -1723,10 +1723,10 @@
 bool InitListExpr::isStringLiteralInit() const {
   if (getNumInits() != 1)
     return false;
-  const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(getType());
-  if (!CAT || !CAT->getElementType()->isIntegerType())
+  const ArrayType *AT = getType()->getAsArrayTypeUnsafe();
+  if (!AT || !AT->getElementType()->isIntegerType())
     return false;
-  const Expr *Init = getInit(0)->IgnoreParenImpCasts();
+  const Expr *Init = getInit(0)->IgnoreParens();
   return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);
 }
 
@@ -2622,6 +2622,207 @@
   return isEvaluatable(Ctx);
 }
 
+bool Expr::HasSideEffects(const ASTContext &Ctx) const {
+  if (isInstantiationDependent())
+    return true;
+
+  switch (getStmtClass()) {
+  case NoStmtClass:
+  #define ABSTRACT_STMT(Type)
+  #define STMT(Type, Base) case Type##Class:
+  #define EXPR(Type, Base)
+  #include "clang/AST/StmtNodes.inc"
+    llvm_unreachable("unexpected Expr kind");
+
+  case DependentScopeDeclRefExprClass:
+  case CXXUnresolvedConstructExprClass:
+  case CXXDependentScopeMemberExprClass:
+  case UnresolvedLookupExprClass:
+  case UnresolvedMemberExprClass:
+  case PackExpansionExprClass:
+  case SubstNonTypeTemplateParmPackExprClass:
+    llvm_unreachable("shouldn't see dependent / unresolved nodes here");
+
+  case DeclRefExprClass:
+  case ObjCIvarRefExprClass:
+  case PredefinedExprClass:
+  case IntegerLiteralClass:
+  case FloatingLiteralClass:
+  case ImaginaryLiteralClass:
+  case StringLiteralClass:
+  case CharacterLiteralClass:
+  case OffsetOfExprClass:
+  case ImplicitValueInitExprClass:
+  case UnaryExprOrTypeTraitExprClass:
+  case AddrLabelExprClass:
+  case GNUNullExprClass:
+  case CXXBoolLiteralExprClass:
+  case CXXNullPtrLiteralExprClass:
+  case CXXThisExprClass:
+  case CXXScalarValueInitExprClass:
+  case TypeTraitExprClass:
+  case UnaryTypeTraitExprClass:
+  case BinaryTypeTraitExprClass:
+  case ArrayTypeTraitExprClass:
+  case ExpressionTraitExprClass:
+  case CXXNoexceptExprClass:
+  case SizeOfPackExprClass:
+  case ObjCStringLiteralClass:
+  case ObjCEncodeExprClass:
+  case ObjCBoolLiteralExprClass:
+  case CXXUuidofExprClass:
+  case OpaqueValueExprClass:
+    // These never have a side-effect.
+    return false;
+
+  case CallExprClass:
+  case CompoundAssignOperatorClass:
+  case VAArgExprClass:
+  case AtomicExprClass:
+  case StmtExprClass:
+  case CXXOperatorCallExprClass:
+  case CXXMemberCallExprClass:
+  case UserDefinedLiteralClass:
+  case CXXThrowExprClass:
+  case CXXNewExprClass:
+  case CXXDeleteExprClass:
+  case ExprWithCleanupsClass:
+  case CXXBindTemporaryExprClass:
+  case BlockExprClass:
+  case CUDAKernelCallExprClass:
+    // These always have a side-effect.
+    return true;
+
+  case ParenExprClass:
+  case ArraySubscriptExprClass:
+  case MemberExprClass:
+  case ConditionalOperatorClass:
+  case BinaryConditionalOperatorClass:
+  case CompoundLiteralExprClass:
+  case ExtVectorElementExprClass:
+  case DesignatedInitExprClass:
+  case ParenListExprClass:
+  case CXXPseudoDestructorExprClass:
+  case SubstNonTypeTemplateParmExprClass:
+  case MaterializeTemporaryExprClass:
+  case ShuffleVectorExprClass:
+  case AsTypeExprClass:
+    // These have a side-effect if any subexpression does.
+    break;
+
+  case UnaryOperatorClass:
+    if (cast<UnaryOperator>(this)->isIncrementDecrementOp())
+      return true;
+    break;
+
+  case BinaryOperatorClass:
+    if (cast<BinaryOperator>(this)->isAssignmentOp())
+      return true;
+    break;
+
+  case InitListExprClass:
+    // FIXME: The children for an InitListExpr doesn't include the array filler.
+    if (const Expr *E = cast<InitListExpr>(this)->getArrayFiller())
+      if (E->HasSideEffects(Ctx))
+        return true;
+    break;
+
+  case GenericSelectionExprClass:
+    return cast<GenericSelectionExpr>(this)->getResultExpr()->
+        HasSideEffects(Ctx);
+
+  case ChooseExprClass:
+    return cast<ChooseExpr>(this)->getChosenSubExpr(Ctx)->HasSideEffects(Ctx);
+
+  case CXXDefaultArgExprClass:
+    return cast<CXXDefaultArgExpr>(this)->getExpr()->HasSideEffects(Ctx);
+
+  case CXXDynamicCastExprClass: {
+    // A dynamic_cast expression has side-effects if it can throw.
+    const CXXDynamicCastExpr *DCE = cast<CXXDynamicCastExpr>(this);
+    if (DCE->getTypeAsWritten()->isReferenceType() &&
+        DCE->getCastKind() == CK_Dynamic)
+      return true;
+  } // Fall through.
+  case ImplicitCastExprClass:
+  case CStyleCastExprClass:
+  case CXXStaticCastExprClass:
+  case CXXReinterpretCastExprClass:
+  case CXXConstCastExprClass:
+  case CXXFunctionalCastExprClass: {
+    const CastExpr *CE = cast<CastExpr>(this);
+    if (CE->getCastKind() == CK_LValueToRValue &&
+        CE->getSubExpr()->getType().isVolatileQualified())
+      return true;
+    break;
+  }
+
+  case CXXTypeidExprClass:
+    // typeid might throw if its subexpression is potentially-evaluated, so has
+    // side-effects in that case whether or not its subexpression does.
+    return cast<CXXTypeidExpr>(this)->isPotentiallyEvaluated();
+
+  case CXXConstructExprClass:
+  case CXXTemporaryObjectExprClass: {
+    const CXXConstructExpr *CE = cast<CXXConstructExpr>(this);
+    if (!CE->getConstructor()->isTrivial())
+      return true;
+    // A trivial constructor does not add any side-effects of its own. Just look
+    // at its arguments.
+    break;
+  }
+
+  case LambdaExprClass: {
+    const LambdaExpr *LE = cast<LambdaExpr>(this);
+    for (LambdaExpr::capture_iterator I = LE->capture_begin(),
+                                      E = LE->capture_end(); I != E; ++I)
+      if (I->getCaptureKind() == LCK_ByCopy)
+        // FIXME: Only has a side-effect if the variable is volatile or if
+        // the copy would invoke a non-trivial copy constructor.
+        return true;
+    return false;
+  }
+
+  case PseudoObjectExprClass: {
+    // Only look for side-effects in the semantic form, and look past
+    // OpaqueValueExpr bindings in that form.
+    const PseudoObjectExpr *PO = cast<PseudoObjectExpr>(this);
+    for (PseudoObjectExpr::const_semantics_iterator I = PO->semantics_begin(),
+                                                    E = PO->semantics_end();
+         I != E; ++I) {
+      const Expr *Subexpr = *I;
+      if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Subexpr))
+        Subexpr = OVE->getSourceExpr();
+      if (Subexpr->HasSideEffects(Ctx))
+        return true;
+    }
+    return false;
+  }
+
+  case ObjCBoxedExprClass:
+  case ObjCArrayLiteralClass:
+  case ObjCDictionaryLiteralClass:
+  case ObjCMessageExprClass:
+  case ObjCSelectorExprClass:
+  case ObjCProtocolExprClass:
+  case ObjCPropertyRefExprClass:
+  case ObjCIsaExprClass:
+  case ObjCIndirectCopyRestoreExprClass:
+  case ObjCSubscriptRefExprClass:
+  case ObjCBridgedCastExprClass:
+    // FIXME: Classify these cases better.
+    return true;
+  }
+
+  // Recurse to children.
+  for (const_child_range SubStmts = children(); SubStmts; ++SubStmts)
+    if (const Stmt *S = *SubStmts)
+      if (cast<Expr>(S)->HasSideEffects(Ctx))
+        return true;
+
+  return false;
+}
+
 namespace {
   /// \brief Look for a call to a non-trivial function within an expression.
   class NonTrivialCallFinder : public EvaluatedExprVisitor<NonTrivialCallFinder>
@@ -2690,7 +2891,7 @@
       llvm_unreachable("Unexpected value dependent expression!");
     case NPC_ValueDependentIsNull:
       if (isTypeDependent() || getType()->isIntegralType(Ctx))
-        return NPCK_ZeroInteger;
+        return NPCK_ZeroExpression;
       else
         return NPCK_NotNull;
         
@@ -2764,7 +2965,12 @@
       return NPCK_NotNull;
   }
 
-  return (EvaluateKnownConstInt(Ctx) == 0) ? NPCK_ZeroInteger : NPCK_NotNull;
+  if (EvaluateKnownConstInt(Ctx) != 0)
+    return NPCK_NotNull;
+
+  if (isa<IntegerLiteral>(this))
+    return NPCK_ZeroLiteral;
+  return NPCK_ZeroExpression;
 }
 
 /// \brief If this expression is an l-value for an Objective C
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 73347b2..40d218b 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -24,6 +24,21 @@
 //  Child Iterators for iterating over subexpressions/substatements
 //===----------------------------------------------------------------------===//
 
+bool CXXTypeidExpr::isPotentiallyEvaluated() const {
+  if (isTypeOperand())
+    return false;
+
+  // C++11 [expr.typeid]p3:
+  //   When typeid is applied to an expression other than a glvalue of
+  //   polymorphic class type, [...] the expression is an unevaluated operand.
+  const Expr *E = getExprOperand();
+  if (const CXXRecordDecl *RD = E->getType()->getAsCXXRecordDecl())
+    if (RD->isPolymorphic() && E->isGLValue())
+      return true;
+
+  return false;
+}
+
 QualType CXXTypeidExpr::getTypeOperand() const {
   assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
   return Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType()
@@ -262,6 +277,7 @@
           isa<UnresolvedUsingValueDecl>(*I)) {
         ExprBits.TypeDependent = true;
         ExprBits.ValueDependent = true;
+        ExprBits.InstantiationDependent = true;
       }
     }
 
@@ -434,9 +450,12 @@
 }
 
 Expr *CXXMemberCallExpr::getImplicitObjectArgument() const {
-  if (const MemberExpr *MemExpr = 
-        dyn_cast<MemberExpr>(getCallee()->IgnoreParens()))
+  const Expr *Callee = getCallee()->IgnoreParens();
+  if (const MemberExpr *MemExpr = dyn_cast<MemberExpr>(Callee))
     return MemExpr->getBase();
+  if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Callee))
+    if (BO->getOpcode() == BO_PtrMemD || BO->getOpcode() == BO_PtrMemI)
+      return BO->getLHS();
 
   // FIXME: Will eventually need to cope with member pointers.
   return 0;
@@ -790,10 +809,11 @@
                        ArrayRef<Expr *> CaptureInits,
                        ArrayRef<VarDecl *> ArrayIndexVars,
                        ArrayRef<unsigned> ArrayIndexStarts,
-                       SourceLocation ClosingBrace)
+                       SourceLocation ClosingBrace,
+                       bool ContainsUnexpandedParameterPack)
   : Expr(LambdaExprClass, T, VK_RValue, OK_Ordinary,
          T->isDependentType(), T->isDependentType(), T->isDependentType(),
-         /*ContainsUnexpandedParameterPack=*/false),
+         ContainsUnexpandedParameterPack),
     IntroducerRange(IntroducerRange),
     NumCaptures(Captures.size()),
     CaptureDefault(CaptureDefault),
@@ -850,20 +870,24 @@
                                ArrayRef<Expr *> CaptureInits,
                                ArrayRef<VarDecl *> ArrayIndexVars,
                                ArrayRef<unsigned> ArrayIndexStarts,
-                               SourceLocation ClosingBrace) {
+                               SourceLocation ClosingBrace,
+                               bool ContainsUnexpandedParameterPack) {
   // Determine the type of the expression (i.e., the type of the
   // function object we're creating).
   QualType T = Context.getTypeDeclType(Class);
 
   unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (Captures.size() + 1);
-  if (!ArrayIndexVars.empty())
-    Size += sizeof(VarDecl *) * ArrayIndexVars.size()
-          + sizeof(unsigned) * (Captures.size() + 1);
+  if (!ArrayIndexVars.empty()) {
+    Size += sizeof(unsigned) * (Captures.size() + 1);
+    // Realign for following VarDecl array.
+    Size = llvm::RoundUpToAlignment(Size, llvm::alignOf<VarDecl*>());
+    Size += sizeof(VarDecl *) * ArrayIndexVars.size();
+  }
   void *Mem = Context.Allocate(Size);
   return new (Mem) LambdaExpr(T, IntroducerRange, CaptureDefault, 
                               Captures, ExplicitParams, ExplicitResultType,
                               CaptureInits, ArrayIndexVars, ArrayIndexStarts,
-                              ClosingBrace);
+                              ClosingBrace, ContainsUnexpandedParameterPack);
 }
 
 LambdaExpr *LambdaExpr::CreateDeserialized(ASTContext &C, unsigned NumCaptures,
@@ -938,7 +962,7 @@
 }
 
 bool LambdaExpr::isMutable() const {
-  return (getCallOperator()->getTypeQualifiers() & Qualifiers::Const) == 0;
+  return !getCallOperator()->isConst();
 }
 
 ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index cbcd5e8..06c41a2 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2277,90 +2277,6 @@
   return Success;
 }
 
-namespace {
-class HasSideEffect
-  : public ConstStmtVisitor<HasSideEffect, bool> {
-  const ASTContext &Ctx;
-public:
-
-  HasSideEffect(const ASTContext &C) : Ctx(C) {}
-
-  // Unhandled nodes conservatively default to having side effects.
-  bool VisitStmt(const Stmt *S) {
-    return true;
-  }
-
-  bool VisitParenExpr(const ParenExpr *E) { return Visit(E->getSubExpr()); }
-  bool VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
-    return Visit(E->getResultExpr());
-  }
-  bool VisitDeclRefExpr(const DeclRefExpr *E) {
-    if (Ctx.getCanonicalType(E->getType()).isVolatileQualified())
-      return true;
-    return false;
-  }
-  bool VisitObjCIvarRefExpr(const ObjCIvarRefExpr *E) {
-    if (Ctx.getCanonicalType(E->getType()).isVolatileQualified())
-      return true;
-    return false;
-  }
-
-  // We don't want to evaluate BlockExprs multiple times, as they generate
-  // a ton of code.
-  bool VisitBlockExpr(const BlockExpr *E) { return true; }
-  bool VisitPredefinedExpr(const PredefinedExpr *E) { return false; }
-  bool VisitCompoundLiteralExpr(const CompoundLiteralExpr *E)
-    { return Visit(E->getInitializer()); }
-  bool VisitMemberExpr(const MemberExpr *E) { return Visit(E->getBase()); }
-  bool VisitIntegerLiteral(const IntegerLiteral *E) { return false; }
-  bool VisitFloatingLiteral(const FloatingLiteral *E) { return false; }
-  bool VisitStringLiteral(const StringLiteral *E) { return false; }
-  bool VisitCharacterLiteral(const CharacterLiteral *E) { return false; }
-  bool VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E)
-    { return false; }
-  bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E)
-    { return Visit(E->getLHS()) || Visit(E->getRHS()); }
-  bool VisitChooseExpr(const ChooseExpr *E)
-    { return Visit(E->getChosenSubExpr(Ctx)); }
-  bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E)
-    { return Visit(E->getCond()) || Visit(E->getTrueExpr())
-      || Visit(E->getFalseExpr()); }
-  bool VisitCastExpr(const CastExpr *E) { return Visit(E->getSubExpr()); }
-  bool VisitBinAssign(const BinaryOperator *E) { return true; }
-  bool VisitCompoundAssignOperator(const BinaryOperator *E) { return true; }
-  bool VisitBinaryOperator(const BinaryOperator *E)
-  { return Visit(E->getLHS()) || Visit(E->getRHS()); }
-  bool VisitUnaryPreInc(const UnaryOperator *E) { return true; }
-  bool VisitUnaryPostInc(const UnaryOperator *E) { return true; }
-  bool VisitUnaryPreDec(const UnaryOperator *E) { return true; }
-  bool VisitUnaryPostDec(const UnaryOperator *E) { return true; }
-  bool VisitUnaryDeref(const UnaryOperator *E) {
-    if (Ctx.getCanonicalType(E->getType()).isVolatileQualified())
-      return true;
-    return Visit(E->getSubExpr());
-  }
-  bool VisitUnaryOperator(const UnaryOperator *E) { return Visit(E->getSubExpr()); }
-  bool VisitGNUNullExpr(const GNUNullExpr *E) { return false; }
-  bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return false; }
-  bool VisitCXXThisExpr(const CXXThisExpr *E) { return false; }
-  bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E) {
-    return false;
-  }
-    
-  // Has side effects if any element does.
-  bool VisitInitListExpr(const InitListExpr *E) {
-    for (unsigned i = 0, e = E->getNumInits(); i != e; ++i)
-      if (Visit(E->getInit(i))) return true;
-    if (const Expr *filler = E->getArrayFiller())
-      return Visit(filler);
-    return false;
-  }
-    
-  bool VisitSizeOfPackExpr(const SizeOfPackExpr *) { return false; }
-};
-
-} // end anonymous namespace
-
 //===----------------------------------------------------------------------===//
 // Generic Evaluation
 //===----------------------------------------------------------------------===//
@@ -2965,6 +2881,9 @@
   if (E->isTypeOperand())
     return Success(E);
   CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl();
+  // FIXME: The standard says "a typeid expression whose operand is of a
+  // polymorphic class type" is not a constant expression, but it probably
+  // means "a typeid expression whose operand is potentially evaluated".
   if (RD && RD->isPolymorphic()) {
     Info.Diag(E, diag::note_constexpr_typeid_polymorphic)
       << E->getExprOperand()->getType()
@@ -4355,9 +4274,9 @@
     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. CodeGen relies on
-    // us to handle all cases where the expression has side-effects.
+    // If evaluating the argument has side-effects, we can't determine the size
+    // of the object, and so we lower it to unknown now. CodeGen relies on us to
+    // handle all cases where the expression has side-effects.
     if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
       if (E->getArg(1)->EvaluateKnownConstInt(Info.Ctx).getZExtValue() <= 1)
         return Success(-1ULL, E);
@@ -6422,10 +6341,6 @@
   return EvaluateAsRValue(Result, Ctx) && !Result.HasSideEffects;
 }
 
-bool Expr::HasSideEffects(const ASTContext &Ctx) const {
-  return HasSideEffect(Ctx).Visit(this);
-}
-
 APSInt Expr::EvaluateKnownConstInt(const ASTContext &Ctx) const {
   EvalResult EvalResult;
   bool Result = EvaluateAsRValue(EvalResult, Ctx);
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 7c7a5e5..0b8a4c8 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -693,9 +693,10 @@
 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());
+    Value.abs().print(Out, /*signed*/ false);
+  } else {
+    Value.print(Out, /*signed*/ false);
+  }
 }
 
 void CXXNameMangler::mangleNumber(int64_t Number) {
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index f9245b8..e2cee7f 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -33,6 +33,8 @@
   MangleContext &Context;
   raw_ostream &Out;
 
+  // FIXME: audit the performance of BackRefMap as it might do way too many
+  // copying of strings.
   typedef std::map<std::string, unsigned> BackRefMap;
   BackRefMap NameBackReferences;
   bool UseNameBackReferences;
@@ -1057,8 +1059,6 @@
                                          SourceRange) {
   // 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,
@@ -1088,8 +1088,15 @@
   else {
     QualType Result = Proto->getResultType();
     const Type* RT = Result.getTypePtr();
-    if(isa<TagType>(RT) && !RT->isAnyPointerType() && !RT->isReferenceType())
-        Out << "?A";
+    if (!RT->isAnyPointerType() && !RT->isReferenceType()) {
+      if (Result.hasQualifiers() || !RT->isBuiltinType())
+        Out << '?';
+      if (!RT->isBuiltinType() && !Result.hasQualifiers()) {
+        // Lack of qualifiers for user types is mangled as 'A'.
+        Out << 'A';
+      }
+    }
+
     // FIXME: Get the source range for the result type. Or, better yet,
     // implement the unimplemented stuff so we don't need accurate source
     // location info anymore :).
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index dbf267b..49b119b 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLoc.h"
+#include "llvm/Support/AlignOf.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 
@@ -33,7 +34,8 @@
   NestedNameSpecifier *NNS
     = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
   if (!NNS) {
-    NNS = new (Context, 4) NestedNameSpecifier(Mockup);
+    NNS = new (Context, llvm::alignOf<NestedNameSpecifier>())
+        NestedNameSpecifier(Mockup);
     Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
   }
 
@@ -107,7 +109,9 @@
 NestedNameSpecifier *
 NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
   if (!Context.GlobalNestedNameSpecifier)
-    Context.GlobalNestedNameSpecifier = new (Context, 4) NestedNameSpecifier();
+    Context.GlobalNestedNameSpecifier =
+        new (Context, llvm::alignOf<NestedNameSpecifier>())
+            NestedNameSpecifier();
   return Context.GlobalNestedNameSpecifier;
 }
 
@@ -630,4 +634,3 @@
   memcpy(Mem, Buffer, BufferSize);
   return NestedNameSpecifierLoc(Representation, Mem);
 }
-
diff --git a/lib/AST/ParentMap.cpp b/lib/AST/ParentMap.cpp
index 64016d9..fa87afd 100644
--- a/lib/AST/ParentMap.cpp
+++ b/lib/AST/ParentMap.cpp
@@ -23,13 +23,20 @@
 static void BuildParentMap(MapTy& M, Stmt* S) {
   for (Stmt::child_range I = S->children(); I; ++I)
     if (*I) {
-      M[*I] = S;
-      BuildParentMap(M, *I);
+      // Prefer the first time we see this statement in the traversal.
+      // This is important for PseudoObjectExprs.
+      Stmt *&Parent = M[*I];
+      if (!Parent) {
+        Parent = S;
+        BuildParentMap(M, *I);
+      }
     }
   
   // Also include the source expr tree of an OpaqueValueExpr in the map.
-  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
+  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S)) {
+    M[OVE->getSourceExpr()] = S;
     BuildParentMap(M, OVE->getSourceExpr());
+  }
 }
 
 ParentMap::ParentMap(Stmt* S) : Impl(0) {
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 7e183e2..a5a3287 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -9,8 +9,12 @@
 
 #include "clang/AST/RawCommentList.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/Comment.h"
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentBriefParser.h"
+#include "clang/AST/CommentSema.h"
+#include "clang/AST/CommentParser.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/STLExtras.h"
 
 using namespace clang;
@@ -134,9 +138,16 @@
   // Make sure that RawText is valid.
   getRawText(Context.getSourceManager());
 
-  comments::Lexer L(Range.getBegin(), comments::CommentOptions(),
+  // Since we will be copying the resulting text, all allocations made during
+  // parsing are garbage after resulting string is formed.  Thus we can use
+  // a separate allocator for all temporary stuff.
+  llvm::BumpPtrAllocator Allocator;
+
+  comments::CommandTraits Traits;
+  comments::Lexer L(Allocator, Traits,
+                    Range.getBegin(), comments::CommentOptions(),
                     RawText.begin(), RawText.end());
-  comments::BriefParser P(L);
+  comments::BriefParser P(L, Traits);
 
   const std::string Result = P.Parse();
   const unsigned BriefTextLength = Result.size();
@@ -148,6 +159,24 @@
   return BriefTextPtr;
 }
 
+comments::FullComment *RawComment::parse(const ASTContext &Context,
+                                         const Decl *D) const {
+  // Make sure that RawText is valid.
+  getRawText(Context.getSourceManager());
+
+  comments::CommandTraits Traits;
+  comments::Lexer L(Context.getAllocator(), Traits,
+                    getSourceRange().getBegin(), comments::CommentOptions(),
+                    RawText.begin(), RawText.end());
+  comments::Sema S(Context.getAllocator(), Context.getSourceManager(),
+                   Context.getDiagnostics(), Traits);
+  S.setDecl(D);
+  comments::Parser P(L, S, Context.getAllocator(), Context.getSourceManager(),
+                     Context.getDiagnostics(), Traits);
+
+  return P.parseFullComment();
+}
+
 namespace {
 bool containsOnlyWhitespace(StringRef Str) {
   return Str.find_first_not_of(" \t\f\v\r\n") == StringRef::npos;
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 86a8814..d5df63f 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -2351,6 +2351,10 @@
     if (MD->hasInlineBody())
       continue;
 
+    // Ignore inline deleted or defaulted functions.
+    if (!MD->isUserProvided())
+      continue;
+
     // We found it.
     return MD;
   }
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index ff6374c..963a20c 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -361,7 +361,7 @@
                                              StringLiteral **Constraints,
                                              Stmt **Exprs,
                                              unsigned NumOutputs,
-                                             unsigned NumInputs,                                      
+                                             unsigned NumInputs,
                                              StringLiteral **Clobbers,
                                              unsigned NumClobbers) {
   this->NumOutputs = NumOutputs;
@@ -369,19 +369,19 @@
   this->NumClobbers = NumClobbers;
 
   unsigned NumExprs = NumOutputs + NumInputs;
-  
+
   C.Deallocate(this->Names);
   this->Names = new (C) IdentifierInfo*[NumExprs];
   std::copy(Names, Names + NumExprs, this->Names);
-  
+
   C.Deallocate(this->Exprs);
   this->Exprs = new (C) Stmt*[NumExprs];
   std::copy(Exprs, Exprs + NumExprs, this->Exprs);
-  
+
   C.Deallocate(this->Constraints);
   this->Constraints = new (C) StringLiteral*[NumExprs];
   std::copy(Constraints, Constraints + NumExprs, this->Constraints);
-  
+
   C.Deallocate(this->Clobbers);
   this->Clobbers = new (C) StringLiteral*[NumClobbers];
   std::copy(Clobbers, Clobbers + NumClobbers, this->Clobbers);
@@ -440,7 +440,7 @@
   std::string CurStringPiece;
 
   bool HasVariants = !C.getTargetInfo().hasNoAsmVariants();
-  
+
   while (1) {
     // Done with the string?
     if (CurPtr == StrEnd) {
@@ -461,7 +461,7 @@
       CurStringPiece += CurChar;
       continue;
     }
-    
+
     // Escaped "%" character in asm string.
     if (CurPtr == StrEnd) {
       // % at end of string is invalid (no escape).
@@ -558,18 +558,17 @@
 // Constructors
 //===----------------------------------------------------------------------===//
 
-AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, 
-                 bool isvolatile, bool msasm, 
-                 unsigned numoutputs, unsigned numinputs,
+AsmStmt::AsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple,
+                 bool isvolatile, unsigned numoutputs, unsigned numinputs,
                  IdentifierInfo **names, StringLiteral **constraints,
                  Expr **exprs, StringLiteral *asmstr, unsigned numclobbers,
                  StringLiteral **clobbers, SourceLocation rparenloc)
   : Stmt(AsmStmtClass), AsmLoc(asmloc), RParenLoc(rparenloc), AsmStr(asmstr)
-  , IsSimple(issimple), IsVolatile(isvolatile), MSAsm(msasm)
-  , NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) {
+  , IsSimple(issimple), IsVolatile(isvolatile), NumOutputs(numoutputs)
+  , NumInputs(numinputs), NumClobbers(numclobbers) {
 
-  unsigned NumExprs = NumOutputs +NumInputs;
-    
+  unsigned NumExprs = NumOutputs + NumInputs;
+
   Names = new (C) IdentifierInfo*[NumExprs];
   std::copy(names, names + NumExprs, Names);
 
@@ -583,10 +582,36 @@
   std::copy(clobbers, clobbers + NumClobbers, Clobbers);
 }
 
-MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc, std::string &asmstr,
-                     SourceLocation endloc)
-  : Stmt(MSAsmStmtClass), AsmLoc(asmloc), EndLoc(endloc), AsmStr(asmstr),
-    IsSimple(true), IsVolatile(true) {
+MSAsmStmt::MSAsmStmt(ASTContext &C, SourceLocation asmloc,
+                     SourceLocation lbraceloc, bool issimple, bool isvolatile,
+                     ArrayRef<Token> asmtoks, ArrayRef<IdentifierInfo*> inputs,
+                     ArrayRef<IdentifierInfo*> outputs, StringRef asmstr,
+                     ArrayRef<StringRef> clobbers, SourceLocation endloc)
+  : Stmt(MSAsmStmtClass), AsmLoc(asmloc), LBraceLoc(lbraceloc), EndLoc(endloc),
+    AsmStr(asmstr.str()), IsSimple(issimple), IsVolatile(isvolatile),
+    NumAsmToks(asmtoks.size()), NumInputs(inputs.size()),
+    NumOutputs(outputs.size()), NumClobbers(clobbers.size()) {
+
+  unsigned NumExprs = NumOutputs + NumInputs;
+
+  Names = new (C) IdentifierInfo*[NumExprs];
+  for (unsigned i = 0, e = NumOutputs; i != e; ++i)
+    Names[i] = outputs[i];
+  for (unsigned i = NumOutputs, e = NumExprs; i != e; ++i)
+    Names[i] = inputs[i];
+
+  AsmToks = new (C) Token[NumAsmToks];
+  for (unsigned i = 0, e = NumAsmToks; i != e; ++i)
+    AsmToks[i] = asmtoks[i];
+
+  Clobbers = new (C) StringRef[NumClobbers];
+  for (unsigned i = 0, e = NumClobbers; i != e; ++i) {
+    // FIXME: Avoid the allocation/copy if at all possible.
+    size_t size = clobbers[i].size();
+    char *dest = new (C) char[size];
+    std::strncpy(dest, clobbers[i].data(), size); 
+    Clobbers[i] = StringRef(dest, size);
+  }
 }
 
 ObjCForCollectionStmt::ObjCForCollectionStmt(Stmt *Elem, Expr *Collect,
@@ -610,31 +635,31 @@
   Stmts[0] = atTryStmt;
   for (unsigned I = 0; I != NumCatchStmts; ++I)
     Stmts[I + 1] = CatchStmts[I];
-  
+
   if (HasFinally)
     Stmts[NumCatchStmts + 1] = atFinallyStmt;
 }
 
-ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context, 
-                                     SourceLocation atTryLoc, 
+ObjCAtTryStmt *ObjCAtTryStmt::Create(ASTContext &Context,
+                                     SourceLocation atTryLoc,
                                      Stmt *atTryStmt,
-                                     Stmt **CatchStmts, 
+                                     Stmt **CatchStmts,
                                      unsigned NumCatchStmts,
                                      Stmt *atFinallyStmt) {
-  unsigned Size = sizeof(ObjCAtTryStmt) + 
+  unsigned Size = sizeof(ObjCAtTryStmt) +
     (1 + NumCatchStmts + (atFinallyStmt != 0)) * sizeof(Stmt *);
   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
   return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts,
                                  atFinallyStmt);
 }
 
-ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context, 
+ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(ASTContext &Context,
                                                  unsigned NumCatchStmts,
                                                  bool HasFinally) {
-  unsigned Size = sizeof(ObjCAtTryStmt) + 
+  unsigned Size = sizeof(ObjCAtTryStmt) +
     (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *);
   void *Mem = Context.Allocate(Size, llvm::alignOf<ObjCAtTryStmt>());
-  return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);  
+  return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally);
 }
 
 SourceRange ObjCAtTryStmt::getSourceRange() const {
@@ -645,12 +670,12 @@
     EndLoc = getCatchStmt(NumCatchStmts - 1)->getLocEnd();
   else
     EndLoc = getTryBody()->getLocEnd();
-  
+
   return SourceRange(AtTryLoc, EndLoc);
 }
 
 CXXTryStmt *CXXTryStmt::Create(ASTContext &C, SourceLocation tryLoc,
-                               Stmt *tryBlock, Stmt **handlers, 
+                               Stmt *tryBlock, Stmt **handlers,
                                unsigned numHandlers) {
   std::size_t Size = sizeof(CXXTryStmt);
   Size += ((numHandlers + 1) * sizeof(Stmt));
@@ -710,20 +735,20 @@
   return const_cast<CXXForRangeStmt*>(this)->getLoopVariable();
 }
 
-IfStmt::IfStmt(ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, 
+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;  
+  SubExprs[ELSE] = elsev;
 }
 
 VarDecl *IfStmt::getConditionVariable() const {
   if (!SubExprs[VAR])
     return 0;
-  
+
   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
   return cast<VarDecl>(DS->getSingleDecl());
 }
@@ -733,16 +758,16 @@
     SubExprs[VAR] = 0;
     return;
   }
-  
+
   SourceRange VarRange = V->getSourceRange();
   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
                                    VarRange.getEnd());
 }
 
-ForStmt::ForStmt(ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar, 
-                 Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP, 
+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) 
+  : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
 {
   SubExprs[INIT] = Init;
   setConditionVariable(C, condVar);
@@ -754,7 +779,7 @@
 VarDecl *ForStmt::getConditionVariable() const {
   if (!SubExprs[CONDVAR])
     return 0;
-  
+
   DeclStmt *DS = cast<DeclStmt>(SubExprs[CONDVAR]);
   return cast<VarDecl>(DS->getSingleDecl());
 }
@@ -764,14 +789,14 @@
     SubExprs[CONDVAR] = 0;
     return;
   }
-  
+
   SourceRange VarRange = V->getSourceRange();
   SubExprs[CONDVAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
                                        VarRange.getEnd());
 }
 
-SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond) 
-  : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0) 
+SwitchStmt::SwitchStmt(ASTContext &C, VarDecl *Var, Expr *cond)
+  : Stmt(SwitchStmtClass), FirstCase(0), AllEnumCasesCovered(0)
 {
   setConditionVariable(C, Var);
   SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
@@ -781,7 +806,7 @@
 VarDecl *SwitchStmt::getConditionVariable() const {
   if (!SubExprs[VAR])
     return 0;
-  
+
   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
   return cast<VarDecl>(DS->getSingleDecl());
 }
@@ -791,7 +816,7 @@
     SubExprs[VAR] = 0;
     return;
   }
-  
+
   SourceRange VarRange = V->getSourceRange();
   SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(),
                                    VarRange.getEnd());
@@ -803,7 +828,7 @@
   return cast<DefaultStmt>(this)->getSubStmt();
 }
 
-WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, 
+WhileStmt::WhileStmt(ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
                      SourceLocation WL)
   : Stmt(WhileStmtClass) {
   setConditionVariable(C, Var);
@@ -815,7 +840,7 @@
 VarDecl *WhileStmt::getConditionVariable() const {
   if (!SubExprs[VAR])
     return 0;
-  
+
   DeclStmt *DS = cast<DeclStmt>(SubExprs[VAR]);
   return cast<VarDecl>(DS->getSingleDecl());
 }
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 2f7cb55..c0960ce 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -30,17 +30,15 @@
 namespace  {
   class StmtPrinter : public StmtVisitor<StmtPrinter> {
     raw_ostream &OS;
-    ASTContext &Context;
     unsigned IndentLevel;
     clang::PrinterHelper* Helper;
     PrintingPolicy Policy;
 
   public:
-    StmtPrinter(raw_ostream &os, ASTContext &C, PrinterHelper* helper,
+    StmtPrinter(raw_ostream &os, PrinterHelper* helper,
                 const PrintingPolicy &Policy,
                 unsigned Indentation = 0)
-      : OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
-        Policy(Policy) {}
+      : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy) {}
 
     void PrintStmt(Stmt *S) {
       PrintStmt(S, Policy.Indentation);
@@ -181,7 +179,7 @@
       first = false;
     }
     // TODO: check this
-    (*it)->printPretty(OS, Context);
+    (*it)->printPretty(OS, Policy);
   }
   OS << "]] ";
   PrintStmt(Node->getSubStmt(), 0);
@@ -432,7 +430,12 @@
 
 void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) {
   // FIXME: Implement MS style inline asm statement printer.
-  Indent() << "asm ()";
+  Indent() << "__asm ";
+  if (Node->hasBraces())
+    OS << "{\n";
+  OS << *(Node->getAsmString()) << "\n";
+  if (Node->hasBraces())
+    Indent() << "}\n";
 }
 
 void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) {
@@ -1390,7 +1393,7 @@
   std::string TypeS;
   if (Expr *Size = E->getArraySize()) {
     llvm::raw_string_ostream s(TypeS);
-    Size->printPretty(s, Context, Helper, Policy);
+    Size->printPretty(s, Helper, Policy);
     s.flush();
     TypeS = "[" + TypeS + "]";
   }
@@ -1799,13 +1802,12 @@
 // Stmt method implementations
 //===----------------------------------------------------------------------===//
 
-void Stmt::dumpPretty(ASTContext& Context) const {
-  printPretty(llvm::errs(), Context, 0,
-              PrintingPolicy(Context.getLangOpts()));
+void Stmt::dumpPretty(ASTContext &Context) const {
+  printPretty(llvm::errs(), 0, PrintingPolicy(Context.getLangOpts()));
 }
 
-void Stmt::printPretty(raw_ostream &OS, ASTContext& Context,
-                       PrinterHelper* Helper,
+void Stmt::printPretty(raw_ostream &OS,
+                       PrinterHelper *Helper,
                        const PrintingPolicy &Policy,
                        unsigned Indentation) const {
   if (this == 0) {
@@ -1813,12 +1815,12 @@
     return;
   }
 
-  if (Policy.Dump && &Context) {
-    dump(OS, Context.getSourceManager());
+  if (Policy.DumpSourceManager) {
+    dump(OS, *Policy.DumpSourceManager);
     return;
   }
 
-  StmtPrinter P(OS, Context, Helper, Policy, Indentation);
+  StmtPrinter P(OS, Helper, Policy, Indentation);
   P.Visit(const_cast<Stmt*>(this));
 }
 
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index f8dd396..95ff4ed 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -556,8 +556,7 @@
 const ASTTemplateArgumentListInfo *
 ASTTemplateArgumentListInfo::Create(ASTContext &C,
                                     const TemplateArgumentListInfo &List) {
-  std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
-                     ASTTemplateArgumentListInfo::sizeFor(List.size());
+  std::size_t size = ASTTemplateArgumentListInfo::sizeFor(List.size());
   void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
   ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
   TAI->initializeFrom(List);
@@ -642,6 +641,7 @@
 std::size_t
 ASTTemplateKWAndArgsInfo::sizeFor(unsigned NumTemplateArgs) {
   // Add space for the template keyword location.
+  // FIXME: There's room for this in the padding before the template args in
+  //        64-bit builds.
   return Base::sizeFor(NumTemplateArgs) + sizeof(SourceLocation);
 }
-
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index eacf505..abefae4 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1584,6 +1584,11 @@
     slot[1] = epi.ExceptionSpecTemplate;
     // This exception specification doesn't make the type dependent, because
     // it's not instantiated as part of instantiating the type.
+  } else if (getExceptionSpecType() == EST_Unevaluated) {
+    // Store the function decl from which we will resolve our
+    // exception specification.
+    FunctionDecl **slot = reinterpret_cast<FunctionDecl**>(argSlot + numArgs);
+    slot[0] = epi.ExceptionSpecDecl;
   }
 
   if (epi.ConsumedArguments) {
@@ -1667,7 +1672,8 @@
       ID.AddPointer(epi.Exceptions[i].getAsOpaquePtr());
   } else if (epi.ExceptionSpecType == EST_ComputedNoexcept && epi.NoexceptExpr){
     epi.NoexceptExpr->Profile(ID, Context, false);
-  } else if (epi.ExceptionSpecType == EST_Uninstantiated) {
+  } else if (epi.ExceptionSpecType == EST_Uninstantiated ||
+             epi.ExceptionSpecType == EST_Unevaluated) {
     ID.AddPointer(epi.ExceptionSpecDecl->getCanonicalDecl());
   }
   if (epi.ConsumedArguments) {
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index a58d4f0..085049d 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -467,8 +467,9 @@
 }
 
 bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLoc) {
+  match(TypeLoc.getType());
   return RecursiveASTVisitor<MatchASTVisitor>::
-      TraverseType(TypeLoc.getType());
+      TraverseTypeLoc(TypeLoc);
 }
 
 class MatchASTConsumer : public ASTConsumer {
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index 32b1fcf..7de7f39 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -181,8 +181,16 @@
 }
 
 ParentMap &AnalysisDeclContext::getParentMap() {
-  if (!PM)
+  if (!PM) {
     PM.reset(new ParentMap(getBody()));
+    if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(getDecl())) {
+      for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
+                                                   E = C->init_end();
+           I != E; ++I) {
+        PM->addStmt((*I)->getInit());
+      }
+    }
+  }
   return *PM;
 }
 
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 1e3fa90..05c5385 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -1340,7 +1340,7 @@
   const FunctionType *FT = Ty->getAs<FunctionType>();
   if (FT) {
     if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FT))
-      if (Proto->getExceptionSpecType() != EST_Uninstantiated &&
+      if (!isUnresolvedExceptionSpec(Proto->getExceptionSpecType()) &&
           Proto->isNothrow(Ctx))
         return false;
   }
@@ -1491,6 +1491,12 @@
   if (badCFG)
     return 0;
 
+  // If the condition is a logical '&&' or '||', build a more accurate CFG.
+  if (BinaryOperator *Cond =
+        dyn_cast<BinaryOperator>(C->getCond()->IgnoreParens()))
+    if (Cond->isLogicalOp())
+      return VisitLogicalOperator(Cond, C, LHSBlock, RHSBlock).first;
+
   // Create the block that will contain the condition.
   Block = createBlock(false);
 
@@ -1708,7 +1714,8 @@
   // control-flow transfer of '&&' or '||' go directly into the then/else
   // blocks directly.
   if (!I->getConditionVariable())
-    if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(I->getCond()))
+    if (BinaryOperator *Cond =
+            dyn_cast<BinaryOperator>(I->getCond()->IgnoreParens()))
       if (Cond->isLogicalOp())
         return VisitLogicalOperator(Cond, I, ThenBlock, ElseBlock).first;
 
@@ -1928,7 +1935,8 @@
 
     // Specially handle logical operators, which have a slightly
     // more optimal CFG representation.
-    if (BinaryOperator *Cond = dyn_cast_or_null<BinaryOperator>(C))
+    if (BinaryOperator *Cond =
+            dyn_cast_or_null<BinaryOperator>(C ? C->IgnoreParens() : 0))
       if (Cond->isLogicalOp()) {
         llvm::tie(EntryConditionBlock, ExitConditionBlock) =
           VisitLogicalOperator(Cond, F, BodyBlock, LoopSuccessor);
@@ -2237,7 +2245,7 @@
 
     // Specially handle logical operators, which have a slightly
     // more optimal CFG representation.
-    if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C))
+    if (BinaryOperator *Cond = dyn_cast<BinaryOperator>(C->IgnoreParens()))
       if (Cond->isLogicalOp()) {
         llvm::tie(EntryConditionBlock, ExitConditionBlock) =
           VisitLogicalOperator(Cond, W, BodyBlock,
@@ -3712,8 +3720,7 @@
     const Type* T = VD->getType().getTypePtr();
     if (const ReferenceType* RT = T->getAs<ReferenceType>())
       T = RT->getPointeeType().getTypePtr();
-    else if (const Type *ET = T->getArrayElementTypeNoTypeQual())
-      T = ET;
+    T = T->getBaseElementTypeUnsafe();
 
     OS << ".~" << T->getAsCXXRecordDecl()->getName().str() << "()";
     OS << " (Implicit destructor)\n";
@@ -3725,11 +3732,7 @@
 
   } else if (const CFGMemberDtor *ME = E.getAs<CFGMemberDtor>()) {
     const FieldDecl *FD = ME->getFieldDecl();
-
-    const Type *T = FD->getType().getTypePtr();
-    if (const Type *ET = T->getArrayElementTypeNoTypeQual())
-      T = ET;
-
+    const Type *T = FD->getType()->getBaseElementTypeUnsafe();
     OS << "this->" << FD->getName();
     OS << ".~" << T->getAsCXXRecordDecl()->getName() << "()";
     OS << " (Member object destructor)\n";
diff --git a/lib/Analysis/CMakeLists.txt b/lib/Analysis/CMakeLists.txt
index 07cc9f0..d57e481 100644
--- a/lib/Analysis/CMakeLists.txt
+++ b/lib/Analysis/CMakeLists.txt
@@ -21,9 +21,10 @@
 add_dependencies(clangAnalysis
   ClangAttrClasses
   ClangAttrList
-  ClangDiagnosticAnalysis
   ClangCommentNodes
+  ClangDiagnosticCommon
   ClangDeclNodes
+  ClangDiagnosticAnalysis
   ClangStmtNodes
   )
 
diff --git a/lib/Analysis/CocoaConventions.cpp b/lib/Analysis/CocoaConventions.cpp
index 7e9e38f..ce973af 100644
--- a/lib/Analysis/CocoaConventions.cpp
+++ b/lib/Analysis/CocoaConventions.cpp
@@ -17,6 +17,8 @@
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/ErrorHandling.h"
+#include <cctype>
+
 using namespace clang;
 using namespace ento;
 
diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
index caceeac..e7ea486 100644
--- a/lib/Analysis/FormatString.cpp
+++ b/lib/Analysis/FormatString.cpp
@@ -15,7 +15,7 @@
 #include "FormatStringParsing.h"
 #include "clang/Basic/LangOptions.h"
 
-using clang::analyze_format_string::ArgTypeResult;
+using clang::analyze_format_string::ArgType;
 using clang::analyze_format_string::FormatStringHandler;
 using clang::analyze_format_string::FormatSpecifier;
 using clang::analyze_format_string::LengthModifier;
@@ -229,13 +229,26 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Methods on ArgTypeResult.
+// Methods on ArgType.
 //===----------------------------------------------------------------------===//
 
-bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
+bool ArgType::matchesType(ASTContext &C, QualType argTy) const {
+  if (Ptr) {
+    // It has to be a pointer.
+    const PointerType *PT = argTy->getAs<PointerType>();
+    if (!PT)
+      return false;
+
+    // We cannot write through a const qualified pointer.
+    if (PT->getPointeeType().isConstQualified())
+      return false;
+
+    argTy = PT->getPointeeType();
+  }
+
   switch (K) {
     case InvalidTy:
-      llvm_unreachable("ArgTypeResult must be valid");
+      llvm_unreachable("ArgType must be valid");
 
     case UnknownTy:
       return true;
@@ -364,39 +377,63 @@
     }
   }
 
-  llvm_unreachable("Invalid ArgTypeResult Kind!");
+  llvm_unreachable("Invalid ArgType Kind!");
 }
 
-QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const {
+QualType ArgType::getRepresentativeType(ASTContext &C) const {
+  QualType Res;
   switch (K) {
     case InvalidTy:
-      llvm_unreachable("No representative type for Invalid ArgTypeResult");
+      llvm_unreachable("No representative type for Invalid ArgType");
     case UnknownTy:
-      return QualType();
+      llvm_unreachable("No representative type for Unknown ArgType");
     case AnyCharTy:
-      return C.CharTy;
+      Res = C.CharTy;
+      break;
     case SpecificTy:
-      return T;
+      Res = T;
+      break;
     case CStrTy:
-      return C.getPointerType(C.CharTy);
+      Res = C.getPointerType(C.CharTy);
+      break;
     case WCStrTy:
-      return C.getPointerType(C.getWCharType());
+      Res = C.getPointerType(C.getWCharType());
+      break;
     case ObjCPointerTy:
-      return C.ObjCBuiltinIdTy;
+      Res = C.ObjCBuiltinIdTy;
+      break;
     case CPointerTy:
-      return C.VoidPtrTy;
+      Res = C.VoidPtrTy;
+      break;
     case WIntTy: {
-      return C.getWIntType();
+      Res = C.getWIntType();
+      break;
     }
   }
 
-  llvm_unreachable("Invalid ArgTypeResult Kind!");
+  if (Ptr)
+    Res = C.getPointerType(Res);
+  return Res;
 }
 
-std::string ArgTypeResult::getRepresentativeTypeName(ASTContext &C) const {
+std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
   std::string S = getRepresentativeType(C).getAsString();
-  if (Name && S != Name)
-    return std::string("'") + Name + "' (aka '" + S + "')";
+
+  std::string Alias;
+  if (Name) {
+    // Use a specific name for this type, e.g. "size_t".
+    Alias = Name;
+    if (Ptr) {
+      // If ArgType is actually a pointer to T, append an asterisk.
+      Alias += (Alias[Alias.size()-1] == '*') ? "*" : " *";
+    }
+    // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
+    if (S == Alias)
+      Alias.clear();
+  }
+
+  if (!Alias.empty())
+    return std::string("'") + Alias + "' (aka '" + S + "')";
   return std::string("'") + S + "'";
 }
 
@@ -405,7 +442,7 @@
 // Methods on OptionalAmount.
 //===----------------------------------------------------------------------===//
 
-ArgTypeResult
+ArgType
 analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
   return Ctx.IntTy;
 }
@@ -681,3 +718,37 @@
   }
   return true;
 }
+
+bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
+                                                LengthModifier &LM) {
+  assert(isa<TypedefType>(QT) && "Expected a TypedefType");
+  const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
+
+  for (;;) {
+    const IdentifierInfo *Identifier = Typedef->getIdentifier();
+    if (Identifier->getName() == "size_t") {
+      LM.setKind(LengthModifier::AsSizeT);
+      return true;
+    } else if (Identifier->getName() == "ssize_t") {
+      // Not C99, but common in Unix.
+      LM.setKind(LengthModifier::AsSizeT);
+      return true;
+    } else if (Identifier->getName() == "intmax_t") {
+      LM.setKind(LengthModifier::AsIntMax);
+      return true;
+    } else if (Identifier->getName() == "uintmax_t") {
+      LM.setKind(LengthModifier::AsIntMax);
+      return true;
+    } else if (Identifier->getName() == "ptrdiff_t") {
+      LM.setKind(LengthModifier::AsPtrDiff);
+      return true;
+    }
+
+    QualType T = Typedef->getUnderlyingType();
+    if (!isa<TypedefType>(T))
+      break;
+
+    Typedef = cast<TypedefType>(T)->getDecl();
+  }
+  return false;
+}
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index 6e10ac1..38f8199 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -284,6 +284,14 @@
       }
       break;
     }
+    case Stmt::ObjCMessageExprClass: {
+      // In calls to super, include the implicit "self" pointer as being live.
+      ObjCMessageExpr *CE = cast<ObjCMessageExpr>(S);
+      if (CE->getReceiverKind() == ObjCMessageExpr::SuperInstance)
+        val.liveDecls = LV.DSetFact.add(val.liveDecls,
+                                        LV.analysisContext.getSelfDecl());
+      break;
+    }
     case Stmt::DeclStmtClass: {
       const DeclStmt *DS = cast<DeclStmt>(S);
       if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl())) {
@@ -455,6 +463,12 @@
   for (CFGBlock::const_reverse_iterator it = block->rbegin(),
        ei = block->rend(); it != ei; ++it) {
     const CFGElement &elem = *it;
+
+    if (const CFGAutomaticObjDtor *Dtor = dyn_cast<CFGAutomaticObjDtor>(&elem)){
+      val.liveDecls = DSetFact.add(val.liveDecls, Dtor->getVarDecl());
+      continue;
+    }
+
     if (!isa<CFGStmt>(elem))
       continue;
     
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index aa6d742..9e4c0fe 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -15,7 +15,7 @@
 #include "clang/Analysis/Analyses/FormatString.h"
 #include "FormatStringParsing.h"
 
-using clang::analyze_format_string::ArgTypeResult;
+using clang::analyze_format_string::ArgType;
 using clang::analyze_format_string::FormatStringHandler;
 using clang::analyze_format_string::LengthModifier;
 using clang::analyze_format_string::OptionalAmount;
@@ -241,20 +241,20 @@
 // Methods on PrintfSpecifier.
 //===----------------------------------------------------------------------===//
 
-ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
-                                          bool IsObjCLiteral) const {
+ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
+                                    bool IsObjCLiteral) const {
   const PrintfConversionSpecifier &CS = getConversionSpecifier();
 
   if (!CS.consumesDataArgument())
-    return ArgTypeResult::Invalid();
+    return ArgType::Invalid();
 
   if (CS.getKind() == ConversionSpecifier::cArg)
     switch (LM.getKind()) {
       case LengthModifier::None: return Ctx.IntTy;
       case LengthModifier::AsLong:
-        return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t");
+        return ArgType(ArgType::WIntTy, "wint_t");
       default:
-        return ArgTypeResult::Invalid();
+        return ArgType::Invalid();
     }
 
   if (CS.isIntArg())
@@ -263,22 +263,22 @@
         // GNU extension.
         return Ctx.LongLongTy;
       case LengthModifier::None: return Ctx.IntTy;
-      case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy;
+      case LengthModifier::AsChar: return ArgType::AnyCharTy;
       case LengthModifier::AsShort: return Ctx.ShortTy;
       case LengthModifier::AsLong: return Ctx.LongTy;
       case LengthModifier::AsLongLong:
       case LengthModifier::AsQuad:
         return Ctx.LongLongTy;
       case LengthModifier::AsIntMax:
-        return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
+        return ArgType(Ctx.getIntMaxType(), "intmax_t");
       case LengthModifier::AsSizeT:
         // FIXME: How to get the corresponding signed version of size_t?
-        return ArgTypeResult();
+        return ArgType();
       case LengthModifier::AsPtrDiff:
-        return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t");
+        return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
       case LengthModifier::AsAllocate:
       case LengthModifier::AsMAllocate:
-        return ArgTypeResult::Invalid();
+        return ArgType::Invalid();
     }
 
   if (CS.isUIntArg())
@@ -294,16 +294,16 @@
       case LengthModifier::AsQuad:
         return Ctx.UnsignedLongLongTy;
       case LengthModifier::AsIntMax:
-        return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
+        return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
       case LengthModifier::AsSizeT:
-        return ArgTypeResult(Ctx.getSizeType(), "size_t");
+        return ArgType(Ctx.getSizeType(), "size_t");
       case LengthModifier::AsPtrDiff:
         // FIXME: How to get the corresponding unsigned
         // version of ptrdiff_t?
-        return ArgTypeResult();
+        return ArgType();
       case LengthModifier::AsAllocate:
       case LengthModifier::AsMAllocate:
-        return ArgTypeResult::Invalid();
+        return ArgType::Invalid();
     }
 
   if (CS.isDoubleArg()) {
@@ -312,36 +312,67 @@
     return Ctx.DoubleTy;
   }
 
+  if (CS.getKind() == ConversionSpecifier::nArg) {
+    switch (LM.getKind()) {
+      case LengthModifier::None:
+        return ArgType::PtrTo(Ctx.IntTy);
+      case LengthModifier::AsChar:
+        return ArgType::PtrTo(Ctx.SignedCharTy);
+      case LengthModifier::AsShort:
+        return ArgType::PtrTo(Ctx.ShortTy);
+      case LengthModifier::AsLong:
+        return ArgType::PtrTo(Ctx.LongTy);
+      case LengthModifier::AsLongLong:
+      case LengthModifier::AsQuad:
+        return ArgType::PtrTo(Ctx.LongLongTy);
+      case LengthModifier::AsIntMax:
+        return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
+      case LengthModifier::AsSizeT:
+        return ArgType(); // FIXME: ssize_t
+      case LengthModifier::AsPtrDiff:
+        return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
+      case LengthModifier::AsLongDouble:
+        return ArgType(); // FIXME: Is this a known extension?
+      case LengthModifier::AsAllocate:
+      case LengthModifier::AsMAllocate:
+        return ArgType::Invalid();
+    }
+  }
+
   switch (CS.getKind()) {
     case ConversionSpecifier::sArg:
       if (LM.getKind() == LengthModifier::AsWideChar) {
         if (IsObjCLiteral)
           return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
-        return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
+        return ArgType(ArgType::WCStrTy, "wchar_t *");
       }
-      return ArgTypeResult::CStrTy;
+      return ArgType::CStrTy;
     case ConversionSpecifier::SArg:
       if (IsObjCLiteral)
         return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
-      return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
+      return ArgType(ArgType::WCStrTy, "wchar_t *");
     case ConversionSpecifier::CArg:
       if (IsObjCLiteral)
         return Ctx.UnsignedShortTy;
-      return ArgTypeResult(Ctx.WCharTy, "wchar_t");
+      return ArgType(Ctx.WCharTy, "wchar_t");
     case ConversionSpecifier::pArg:
-      return ArgTypeResult::CPointerTy;
+      return ArgType::CPointerTy;
     case ConversionSpecifier::ObjCObjArg:
-      return ArgTypeResult::ObjCPointerTy;
+      return ArgType::ObjCPointerTy;
     default:
       break;
   }
 
   // FIXME: Handle other cases.
-  return ArgTypeResult();
+  return ArgType();
 }
 
 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
                               ASTContext &Ctx, bool IsObjCLiteral) {
+  // %n is different from other conversion specifiers; don't try to fix it.
+  if (CS.getKind() == ConversionSpecifier::nArg)
+    return false;
+
   // Handle Objective-C objects first. Note that while the '%@' specifier will
   // not warn for structure pointer or void pointer arguments (because that's
   // how CoreFoundation objects are implemented), we only show a fixit for '%@'
@@ -447,24 +478,11 @@
   }
 
   // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
-  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
-    const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
-    if (Identifier->getName() == "size_t") {
-      LM.setKind(LengthModifier::AsSizeT);
-    } else if (Identifier->getName() == "ssize_t") {
-      // Not C99, but common in Unix.
-      LM.setKind(LengthModifier::AsSizeT);
-    } else if (Identifier->getName() == "intmax_t") {
-      LM.setKind(LengthModifier::AsIntMax);
-    } else if (Identifier->getName() == "uintmax_t") {
-      LM.setKind(LengthModifier::AsIntMax);
-    } else if (Identifier->getName() == "ptrdiff_t") {
-      LM.setKind(LengthModifier::AsPtrDiff);
-    }
-  }
+  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x))
+    namedTypeToLengthModifier(QT, LM);
 
   // If fixing the length modifier was enough, we are done.
-  const analyze_printf::ArgTypeResult &ATR = getArgType(Ctx, IsObjCLiteral);
+  const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
   if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT))
     return true;
 
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp
index 066d5d6..2942400 100644
--- a/lib/Analysis/ScanfFormatString.cpp
+++ b/lib/Analysis/ScanfFormatString.cpp
@@ -15,12 +15,11 @@
 #include "clang/Analysis/Analyses/FormatString.h"
 #include "FormatStringParsing.h"
 
-using clang::analyze_format_string::ArgTypeResult;
+using clang::analyze_format_string::ArgType;
 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::ScanfArgTypeResult;
 using clang::analyze_scanf::ScanfConversionSpecifier;
 using clang::analyze_scanf::ScanfSpecifier;
 using clang::UpdateOnReturn;
@@ -194,37 +193,42 @@
   return ScanfSpecifierResult(Start, FS);
 }
 
-ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
+ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
   const ScanfConversionSpecifier &CS = getConversionSpecifier();
 
   if (!CS.consumesDataArgument())
-    return ScanfArgTypeResult::Invalid();
+    return ArgType::Invalid();
 
   switch(CS.getKind()) {
     // Signed int.
     case ConversionSpecifier::dArg:
     case ConversionSpecifier::iArg:
       switch (LM.getKind()) {
-        case LengthModifier::None: return ArgTypeResult(Ctx.IntTy);
+        case LengthModifier::None:
+          return ArgType::PtrTo(Ctx.IntTy);
         case LengthModifier::AsChar:
-          return ArgTypeResult(ArgTypeResult::AnyCharTy);
-        case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy);
-        case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy);
+          return ArgType::PtrTo(ArgType::AnyCharTy);
+        case LengthModifier::AsShort:
+          return ArgType::PtrTo(Ctx.ShortTy);
+        case LengthModifier::AsLong:
+          return ArgType::PtrTo(Ctx.LongTy);
         case LengthModifier::AsLongLong:
         case LengthModifier::AsQuad:
-          return ArgTypeResult(Ctx.LongLongTy);
+          return ArgType::PtrTo(Ctx.LongLongTy);
         case LengthModifier::AsIntMax:
-          return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *");
+          return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
         case LengthModifier::AsSizeT:
           // FIXME: ssize_t.
-          return ScanfArgTypeResult();
+          return ArgType();
         case LengthModifier::AsPtrDiff:
-          return ScanfArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t *");
+          return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
         case LengthModifier::AsLongDouble:
           // GNU extension.
-          return ArgTypeResult(Ctx.LongLongTy);
-        case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid();
-        case LengthModifier::AsMAllocate: return ScanfArgTypeResult::Invalid();
+          return ArgType::PtrTo(Ctx.LongLongTy);
+        case LengthModifier::AsAllocate:
+          return ArgType::Invalid();
+        case LengthModifier::AsMAllocate:
+          return ArgType::Invalid();
       }
 
     // Unsigned int.
@@ -233,25 +237,31 @@
     case ConversionSpecifier::xArg:
     case ConversionSpecifier::XArg:
       switch (LM.getKind()) {
-        case LengthModifier::None: return ArgTypeResult(Ctx.UnsignedIntTy);
-        case LengthModifier::AsChar: return ArgTypeResult(Ctx.UnsignedCharTy);
-        case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy);
-        case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy);
+        case LengthModifier::None:
+          return ArgType::PtrTo(Ctx.UnsignedIntTy);
+        case LengthModifier::AsChar:
+          return ArgType::PtrTo(Ctx.UnsignedCharTy);
+        case LengthModifier::AsShort:
+          return ArgType::PtrTo(Ctx.UnsignedShortTy);
+        case LengthModifier::AsLong:
+          return ArgType::PtrTo(Ctx.UnsignedLongTy);
         case LengthModifier::AsLongLong:
         case LengthModifier::AsQuad:
-          return ArgTypeResult(Ctx.UnsignedLongLongTy);
+          return ArgType::PtrTo(Ctx.UnsignedLongLongTy);
         case LengthModifier::AsIntMax:
-          return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *");
+          return ArgType::PtrTo(ArgType(Ctx.getUIntMaxType(), "uintmax_t"));
         case LengthModifier::AsSizeT:
-          return ScanfArgTypeResult(Ctx.getSizeType(), "size_t *");
+          return ArgType::PtrTo(ArgType(Ctx.getSizeType(), "size_t"));
         case LengthModifier::AsPtrDiff:
           // FIXME: Unsigned version of ptrdiff_t?
-          return ScanfArgTypeResult();
+          return ArgType();
         case LengthModifier::AsLongDouble:
           // GNU extension.
-          return ArgTypeResult(Ctx.UnsignedLongLongTy);
-        case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid();
-        case LengthModifier::AsMAllocate: return ScanfArgTypeResult::Invalid();
+          return ArgType::PtrTo(Ctx.UnsignedLongLongTy);
+        case LengthModifier::AsAllocate:
+          return ArgType::Invalid();
+        case LengthModifier::AsMAllocate:
+          return ArgType::Invalid();
       }
 
     // Float.
@@ -264,12 +274,14 @@
     case ConversionSpecifier::gArg:
     case ConversionSpecifier::GArg:
       switch (LM.getKind()) {
-        case LengthModifier::None: return ArgTypeResult(Ctx.FloatTy);
-        case LengthModifier::AsLong: return ArgTypeResult(Ctx.DoubleTy);
+        case LengthModifier::None:
+          return ArgType::PtrTo(Ctx.FloatTy);
+        case LengthModifier::AsLong:
+          return ArgType::PtrTo(Ctx.DoubleTy);
         case LengthModifier::AsLongDouble:
-          return ArgTypeResult(Ctx.LongDoubleTy);
+          return ArgType::PtrTo(Ctx.LongDoubleTy);
         default:
-          return ScanfArgTypeResult::Invalid();
+          return ArgType::Invalid();
       }
 
     // Char, string and scanlist.
@@ -277,37 +289,65 @@
     case ConversionSpecifier::sArg:
     case ConversionSpecifier::ScanListArg:
       switch (LM.getKind()) {
-        case LengthModifier::None: return ScanfArgTypeResult::CStrTy;
+        case LengthModifier::None:
+          return ArgType::PtrTo(ArgType::AnyCharTy);
         case LengthModifier::AsLong:
-          return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *");
+          return ArgType::PtrTo(ArgType(Ctx.getWCharType(), "wchar_t"));
         case LengthModifier::AsAllocate:
         case LengthModifier::AsMAllocate:
-          return ScanfArgTypeResult(ArgTypeResult::CStrTy);
+          return ArgType::PtrTo(ArgType::CStrTy);
         default:
-          return ScanfArgTypeResult::Invalid();
+          return ArgType::Invalid();
       }
     case ConversionSpecifier::CArg:
     case ConversionSpecifier::SArg:
       // FIXME: Mac OS X specific?
       switch (LM.getKind()) {
         case LengthModifier::None:
-          return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *");
+          return ArgType::PtrTo(ArgType(Ctx.getWCharType(), "wchar_t"));
         case LengthModifier::AsAllocate:
         case LengthModifier::AsMAllocate:
-          return ScanfArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t **");
+          return ArgType::PtrTo(ArgType(ArgType::WCStrTy, "wchar_t *"));
         default:
-          return ScanfArgTypeResult::Invalid();
+          return ArgType::Invalid();
       }
 
     // Pointer.
     case ConversionSpecifier::pArg:
-      return ScanfArgTypeResult(ArgTypeResult(ArgTypeResult::CPointerTy));
+      return ArgType::PtrTo(ArgType::CPointerTy);
+
+    // Write-back.
+    case ConversionSpecifier::nArg:
+      switch (LM.getKind()) {
+        case LengthModifier::None:
+          return ArgType::PtrTo(Ctx.IntTy);
+        case LengthModifier::AsChar:
+          return ArgType::PtrTo(Ctx.SignedCharTy);
+        case LengthModifier::AsShort:
+          return ArgType::PtrTo(Ctx.ShortTy);
+        case LengthModifier::AsLong:
+          return ArgType::PtrTo(Ctx.LongTy);
+        case LengthModifier::AsLongLong:
+        case LengthModifier::AsQuad:
+          return ArgType::PtrTo(Ctx.LongLongTy);
+        case LengthModifier::AsIntMax:
+          return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
+        case LengthModifier::AsSizeT:
+          return ArgType(); // FIXME: ssize_t
+        case LengthModifier::AsPtrDiff:
+          return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
+        case LengthModifier::AsLongDouble:
+          return ArgType(); // FIXME: Is this a known extension?
+        case LengthModifier::AsAllocate:
+        case LengthModifier::AsMAllocate:
+          return ArgType::Invalid();
+        }
 
     default:
       break;
   }
 
-  return ScanfArgTypeResult();
+  return ArgType();
 }
 
 bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
@@ -315,6 +355,10 @@
   if (!QT->isPointerType())
     return false;
 
+  // %n is different from other conversion specifiers; don't try to fix it.
+  if (CS.getKind() == ConversionSpecifier::nArg)
+    return false;
+
   QualType PT = QT->getPointeeType();
 
   // If it's an enum, get its underlying type.
@@ -382,25 +426,12 @@
   }
 
   // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
-  if (isa<TypedefType>(PT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
-    const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
-    if (Identifier->getName() == "size_t") {
-      LM.setKind(LengthModifier::AsSizeT);
-    } else if (Identifier->getName() == "ssize_t") {
-      // Not C99, but common in Unix.
-      LM.setKind(LengthModifier::AsSizeT);
-    } else if (Identifier->getName() == "intmax_t") {
-      LM.setKind(LengthModifier::AsIntMax);
-    } else if (Identifier->getName() == "uintmax_t") {
-      LM.setKind(LengthModifier::AsIntMax);
-    } else if (Identifier->getName() == "ptrdiff_t") {
-      LM.setKind(LengthModifier::AsPtrDiff);
-    }
-  }
+  if (isa<TypedefType>(PT) && (LangOpt.C99 || LangOpt.CPlusPlus0x))
+    namedTypeToLengthModifier(PT, LM);
 
   // If fixing the length modifier was enough, we are done.
-  const analyze_scanf::ScanfArgTypeResult &ATR = getArgType(Ctx);
-  if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT))
+  const analyze_scanf::ArgType &AT = getArgType(Ctx);
+  if (hasValidLengthModifier() && AT.isValid() && AT.matchesType(Ctx, QT))
     return true;
 
   // Figure out the conversion specifier.
@@ -457,48 +488,3 @@
   assert(I == E && "Format string not exhausted");
   return false;
 }
-
-bool ScanfArgTypeResult::matchesType(ASTContext& C, QualType argTy) const {
-  switch (K) {
-    case InvalidTy:
-      llvm_unreachable("ArgTypeResult must be valid");
-    case UnknownTy:
-      return true;
-    case CStrTy:
-      return ArgTypeResult(ArgTypeResult::CStrTy).matchesType(C, argTy);
-    case WCStrTy:
-      return ArgTypeResult(ArgTypeResult::WCStrTy).matchesType(C, argTy);
-    case PtrToArgTypeResultTy: {
-      const PointerType *PT = argTy->getAs<PointerType>();
-      if (!PT)
-        return false;
-      return A.matchesType(C, PT->getPointeeType());
-    }
-  }
-
-  llvm_unreachable("Invalid ScanfArgTypeResult Kind!");
-}
-
-QualType ScanfArgTypeResult::getRepresentativeType(ASTContext &C) const {
-  switch (K) {
-    case InvalidTy:
-      llvm_unreachable("No representative type for Invalid ArgTypeResult");
-    case UnknownTy:
-      return QualType();
-    case CStrTy:
-      return C.getPointerType(C.CharTy);
-    case WCStrTy:
-      return C.getPointerType(C.getWCharType());
-    case PtrToArgTypeResultTy:
-      return C.getPointerType(A.getRepresentativeType(C));
-  }
-
-  llvm_unreachable("Invalid ScanfArgTypeResult Kind!");
-}
-
-std::string ScanfArgTypeResult::getRepresentativeTypeName(ASTContext& C) const {
-  std::string S = getRepresentativeType(C).getAsString();
-  if (!Name)
-    return std::string("'") + S + "'";
-  return std::string("'") + Name + "' (aka '" + S + "')";
-}
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp
index cc4eafb..5954682 100644
--- a/lib/Analysis/ThreadSafety.cpp
+++ b/lib/Analysis/ThreadSafety.cpp
@@ -46,8 +46,15 @@
 
 namespace {
 
-/// \brief A MutexID object uniquely identifies a particular mutex, and
-/// is built from an Expr* (i.e. calling a lock function).
+/// SExpr implements a simple expression language that is used to store,
+/// compare, and pretty-print C++ expressions.  Unlike a clang Expr, a SExpr
+/// does not capture surface syntax, and it does not distinguish between
+/// C++ concepts, like pointers and references, that have no real semantic
+/// differences.  This simplicity allows SExprs to be meaningfully compared,
+/// e.g.
+///        (x)          =  x
+///        (*this).foo  =  this->foo
+///        *&a          =  a
 ///
 /// Thread-safety analysis works by comparing lock expressions.  Within the
 /// body of a function, an expression such as "x->foo->bar.mu" will resolve to
@@ -60,30 +67,90 @@
 ///
 /// The current implementation assumes, but does not verify, that multiple uses
 /// of the same lock expression satisfies these criteria.
-///
-/// Clang introduces an additional wrinkle, which is that it is difficult to
-/// derive canonical expressions, or compare expressions directly for equality.
-/// Thus, we identify a mutex not by an Expr, but by the list of named
-/// declarations that are referenced by the Expr.  In other words,
-/// x->foo->bar.mu will be a four element vector with the Decls for
-/// mu, bar, and foo, and x.  The vector will uniquely identify the expression
-/// for all practical purposes.  Null is used to denote 'this'.
-///
-/// Note we will need to perform substitution on "this" and function parameter
-/// names when constructing a lock expression.
-///
-/// For example:
-/// class C { Mutex Mu;  void lock() EXCLUSIVE_LOCK_FUNCTION(this->Mu); };
-/// void myFunc(C *X) { ... X->lock() ... }
-/// The original expression for the mutex acquired by myFunc is "this->Mu", but
-/// "X" is substituted for "this" so we get X->Mu();
-///
-/// For another example:
-/// foo(MyList *L) EXCLUSIVE_LOCKS_REQUIRED(L->Mu) { ... }
-/// MyList *MyL;
-/// foo(MyL);  // requires lock MyL->Mu to be held
-class MutexID {
-  SmallVector<NamedDecl*, 2> DeclSeq;
+class SExpr {
+private:
+  enum ExprOp {
+    EOP_Nop,      //< No-op
+    EOP_Wildcard, //< Matches anything.
+    EOP_This,     //< This keyword.
+    EOP_NVar,     //< Named variable.
+    EOP_LVar,     //< Local variable.
+    EOP_Dot,      //< Field access
+    EOP_Call,     //< Function call
+    EOP_MCall,    //< Method call
+    EOP_Index,    //< Array index
+    EOP_Unary,    //< Unary operation
+    EOP_Binary,   //< Binary operation
+    EOP_Unknown   //< Catchall for everything else
+  };
+
+
+  class SExprNode {
+   private:
+    unsigned char  Op;     //< Opcode of the root node
+    unsigned char  Flags;  //< Additional opcode-specific data
+    unsigned short Sz;     //< Number of child nodes
+    const void*    Data;   //< Additional opcode-specific data
+
+   public:
+    SExprNode(ExprOp O, unsigned F, const void* D)
+      : Op(static_cast<unsigned char>(O)),
+        Flags(static_cast<unsigned char>(F)), Sz(1), Data(D)
+    { }
+
+    unsigned size() const        { return Sz; }
+    void     setSize(unsigned S) { Sz = S;    }
+
+    ExprOp   kind() const { return static_cast<ExprOp>(Op); }
+
+    const NamedDecl* getNamedDecl() const {
+      assert(Op == EOP_NVar || Op == EOP_LVar || Op == EOP_Dot);
+      return reinterpret_cast<const NamedDecl*>(Data);
+    }
+
+    const NamedDecl* getFunctionDecl() const {
+      assert(Op == EOP_Call || Op == EOP_MCall);
+      return reinterpret_cast<const NamedDecl*>(Data);
+    }
+
+    bool isArrow() const { return Op == EOP_Dot && Flags == 1; }
+    void setArrow(bool A) { Flags = A ? 1 : 0; }
+
+    unsigned arity() const {
+      switch (Op) {
+        case EOP_Nop:      return 0;
+        case EOP_Wildcard: return 0;
+        case EOP_NVar:     return 0;
+        case EOP_LVar:     return 0;
+        case EOP_This:     return 0;
+        case EOP_Dot:      return 1;
+        case EOP_Call:     return Flags+1;  // First arg is function.
+        case EOP_MCall:    return Flags+1;  // First arg is implicit obj.
+        case EOP_Index:    return 2;
+        case EOP_Unary:    return 1;
+        case EOP_Binary:   return 2;
+        case EOP_Unknown:  return Flags;
+      }
+      return 0;
+    }
+
+    bool operator==(const SExprNode& Other) const {
+      // Ignore flags and size -- they don't matter.
+      return (Op == Other.Op &&
+              Data == Other.Data);
+    }
+
+    bool operator!=(const SExprNode& Other) const {
+      return !(*this == Other);
+    }
+
+    bool matches(const SExprNode& Other) const {
+      return (*this == Other) ||
+             (Op == EOP_Wildcard) ||
+             (Other.Op == EOP_Wildcard);
+    }
+  };
+
 
   /// \brief Encapsulates the lexical context of a function call.  The lexical
   /// context includes the arguments to the call, including the implicit object
@@ -95,27 +162,99 @@
   /// should be evaluated; multiple calling contexts can be chained together
   /// by the lock_returned attribute.
   struct CallingContext {
-    const NamedDecl* AttrDecl;  // The decl to which the attribute is attached.
-    Expr*            SelfArg;   // Implicit object argument -- e.g. 'this'
-    unsigned         NumArgs;   // Number of funArgs
-    Expr**           FunArgs;   // Function arguments
-    CallingContext*  PrevCtx;   // The previous context; or 0 if none.
+    const NamedDecl* AttrDecl;   // The decl to which the attribute is attached.
+    Expr*            SelfArg;    // Implicit object argument -- e.g. 'this'
+    bool             SelfArrow;  // is Self referred to with -> or .?
+    unsigned         NumArgs;    // Number of funArgs
+    Expr**           FunArgs;    // Function arguments
+    CallingContext*  PrevCtx;    // The previous context; or 0 if none.
 
-    CallingContext(const NamedDecl* D = 0, Expr* S = 0,
-                   unsigned N = 0, Expr** A = 0, CallingContext* P = 0)
-      : AttrDecl(D), SelfArg(S), NumArgs(N), FunArgs(A), PrevCtx(P)
+    CallingContext(const NamedDecl *D = 0, Expr *S = 0,
+                   unsigned N = 0, Expr **A = 0, CallingContext *P = 0)
+      : AttrDecl(D), SelfArg(S), SelfArrow(false),
+        NumArgs(N), FunArgs(A), PrevCtx(P)
     { }
   };
 
-  /// Build a Decl sequence representing the lock from the given expression.
+  typedef SmallVector<SExprNode, 4> NodeVector;
+
+private:
+  // A SExpr is a list of SExprNodes in prefix order.  The Size field allows
+  // the list to be traversed as a tree.
+  NodeVector NodeVec;
+
+private:
+  unsigned makeNop() {
+    NodeVec.push_back(SExprNode(EOP_Nop, 0, 0));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeWildcard() {
+    NodeVec.push_back(SExprNode(EOP_Wildcard, 0, 0));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeNamedVar(const NamedDecl *D) {
+    NodeVec.push_back(SExprNode(EOP_NVar, 0, D));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeLocalVar(const NamedDecl *D) {
+    NodeVec.push_back(SExprNode(EOP_LVar, 0, D));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeThis() {
+    NodeVec.push_back(SExprNode(EOP_This, 0, 0));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeDot(const NamedDecl *D, bool Arrow) {
+    NodeVec.push_back(SExprNode(EOP_Dot, Arrow ? 1 : 0, D));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeCall(unsigned NumArgs, const NamedDecl *D) {
+    NodeVec.push_back(SExprNode(EOP_Call, NumArgs, D));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeMCall(unsigned NumArgs, const NamedDecl *D) {
+    NodeVec.push_back(SExprNode(EOP_MCall, NumArgs, D));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeIndex() {
+    NodeVec.push_back(SExprNode(EOP_Index, 0, 0));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeUnary() {
+    NodeVec.push_back(SExprNode(EOP_Unary, 0, 0));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeBinary() {
+    NodeVec.push_back(SExprNode(EOP_Binary, 0, 0));
+    return NodeVec.size()-1;
+  }
+
+  unsigned makeUnknown(unsigned Arity) {
+    NodeVec.push_back(SExprNode(EOP_Unknown, Arity, 0));
+    return NodeVec.size()-1;
+  }
+
+  /// Build an SExpr from the given C++ expression.
   /// Recursive function that terminates on DeclRefExpr.
-  /// Note: this function merely creates a MutexID; it does not check to
+  /// Note: this function merely creates a SExpr; it does not check to
   /// ensure that the original expression is a valid mutex expression.
-  void buildMutexID(Expr *Exp, CallingContext* CallCtx) {
-    if (!Exp) {
-      DeclSeq.clear();
-      return;
-    }
+  ///
+  /// NDeref returns the number of Derefence and AddressOf operations
+  /// preceeding the Expr; this is used to decide whether to pretty-print
+  /// SExprs with . or ->.
+  unsigned buildSExpr(Expr *Exp, CallingContext* CallCtx, int* NDeref = 0) {
+    if (!Exp)
+      return 0;
 
     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp)) {
       NamedDecl *ND = cast<NamedDecl>(DRE->getDecl()->getCanonicalDecl());
@@ -129,27 +268,35 @@
             FD == CallCtx->AttrDecl->getCanonicalDecl()) {
           // Substitute call arguments for references to function parameters
           assert(i < CallCtx->NumArgs);
-          buildMutexID(CallCtx->FunArgs[i], CallCtx->PrevCtx);
-          return;
+          return buildSExpr(CallCtx->FunArgs[i], CallCtx->PrevCtx, NDeref);
         }
         // Map the param back to the param of the original function declaration.
-        DeclSeq.push_back(FD->getParamDecl(i));
-        return;
+        makeNamedVar(FD->getParamDecl(i));
+        return 1;
       }
       // Not a function parameter -- just store the reference.
-      DeclSeq.push_back(ND);
+      makeNamedVar(ND);
+      return 1;
     } else if (isa<CXXThisExpr>(Exp)) {
       // Substitute parent for 'this'
-      if (CallCtx && CallCtx->SelfArg)
-        buildMutexID(CallCtx->SelfArg, CallCtx->PrevCtx);
+      if (CallCtx && CallCtx->SelfArg) {
+        if (!CallCtx->SelfArrow && NDeref)
+          // 'this' is a pointer, but self is not, so need to take address.
+          --(*NDeref);
+        return buildSExpr(CallCtx->SelfArg, CallCtx->PrevCtx, NDeref);
+      }
       else {
-        DeclSeq.push_back(0);  // Use 0 to represent 'this'.
-        return;  // mutexID is still valid in this case
+        makeThis();
+        return 1;
       }
     } else if (MemberExpr *ME = dyn_cast<MemberExpr>(Exp)) {
       NamedDecl *ND = ME->getMemberDecl();
-      DeclSeq.push_back(ND);
-      buildMutexID(ME->getBase(), CallCtx);
+      int ImplicitDeref = ME->isArrow() ? 1 : 0;
+      unsigned Root = makeDot(ND, false);
+      unsigned Sz = buildSExpr(ME->getBase(), CallCtx, &ImplicitDeref);
+      NodeVec[Root].setArrow(ImplicitDeref > 0);
+      NodeVec[Root].setSize(Sz + 1);
+      return Sz + 1;
     } else if (CXXMemberCallExpr *CMCE = dyn_cast<CXXMemberCallExpr>(Exp)) {
       // When calling a function with a lock_returned attribute, replace
       // the function call with the expression in lock_returned.
@@ -157,26 +304,31 @@
             CMCE->getMethodDecl()->getAttr<LockReturnedAttr>()) {
         CallingContext LRCallCtx(CMCE->getMethodDecl());
         LRCallCtx.SelfArg = CMCE->getImplicitObjectArgument();
+        LRCallCtx.SelfArrow =
+          dyn_cast<MemberExpr>(CMCE->getCallee())->isArrow();
         LRCallCtx.NumArgs = CMCE->getNumArgs();
         LRCallCtx.FunArgs = CMCE->getArgs();
         LRCallCtx.PrevCtx = CallCtx;
-        buildMutexID(At->getArg(), &LRCallCtx);
-        return;
+        return buildSExpr(At->getArg(), &LRCallCtx);
       }
       // Hack to treat smart pointers and iterators as pointers;
       // ignore any method named get().
       if (CMCE->getMethodDecl()->getNameAsString() == "get" &&
           CMCE->getNumArgs() == 0) {
-        buildMutexID(CMCE->getImplicitObjectArgument(), CallCtx);
-        return;
+        if (NDeref && dyn_cast<MemberExpr>(CMCE->getCallee())->isArrow())
+          ++(*NDeref);
+        return buildSExpr(CMCE->getImplicitObjectArgument(), CallCtx, NDeref);
       }
-      DeclSeq.push_back(CMCE->getMethodDecl()->getCanonicalDecl());
-      buildMutexID(CMCE->getImplicitObjectArgument(), CallCtx);
       unsigned NumCallArgs = CMCE->getNumArgs();
+      unsigned Root =
+        makeMCall(NumCallArgs, CMCE->getMethodDecl()->getCanonicalDecl());
+      unsigned Sz = buildSExpr(CMCE->getImplicitObjectArgument(), CallCtx);
       Expr** CallArgs = CMCE->getArgs();
       for (unsigned i = 0; i < NumCallArgs; ++i) {
-        buildMutexID(CallArgs[i], CallCtx);
+        Sz += buildSExpr(CallArgs[i], CallCtx);
       }
+      NodeVec[Root].setSize(Sz + 1);
+      return Sz + 1;
     } else if (CallExpr *CE = dyn_cast<CallExpr>(Exp)) {
       if (LockReturnedAttr* At =
             CE->getDirectCallee()->getAttr<LockReturnedAttr>()) {
@@ -184,49 +336,90 @@
         LRCallCtx.NumArgs = CE->getNumArgs();
         LRCallCtx.FunArgs = CE->getArgs();
         LRCallCtx.PrevCtx = CallCtx;
-        buildMutexID(At->getArg(), &LRCallCtx);
-        return;
+        return buildSExpr(At->getArg(), &LRCallCtx);
       }
       // Treat smart pointers and iterators as pointers;
       // ignore the * and -> operators.
       if (CXXOperatorCallExpr *OE = dyn_cast<CXXOperatorCallExpr>(CE)) {
         OverloadedOperatorKind k = OE->getOperator();
-        if (k == OO_Arrow || k == OO_Star) {
-          buildMutexID(OE->getArg(0), CallCtx);
-          return;
+        if (k == OO_Star) {
+          if (NDeref) ++(*NDeref);
+          return buildSExpr(OE->getArg(0), CallCtx, NDeref);
+        }
+        else if (k == OO_Arrow) {
+          return buildSExpr(OE->getArg(0), CallCtx, NDeref);
         }
       }
-      buildMutexID(CE->getCallee(), CallCtx);
       unsigned NumCallArgs = CE->getNumArgs();
+      unsigned Root = makeCall(NumCallArgs, 0);
+      unsigned Sz = buildSExpr(CE->getCallee(), CallCtx);
       Expr** CallArgs = CE->getArgs();
       for (unsigned i = 0; i < NumCallArgs; ++i) {
-        buildMutexID(CallArgs[i], CallCtx);
+        Sz += buildSExpr(CallArgs[i], CallCtx);
       }
+      NodeVec[Root].setSize(Sz+1);
+      return Sz+1;
     } else if (BinaryOperator *BOE = dyn_cast<BinaryOperator>(Exp)) {
-      buildMutexID(BOE->getLHS(), CallCtx);
-      buildMutexID(BOE->getRHS(), CallCtx);
+      unsigned Root = makeBinary();
+      unsigned Sz = buildSExpr(BOE->getLHS(), CallCtx);
+      Sz += buildSExpr(BOE->getRHS(), CallCtx);
+      NodeVec[Root].setSize(Sz);
+      return Sz;
     } else if (UnaryOperator *UOE = dyn_cast<UnaryOperator>(Exp)) {
-      buildMutexID(UOE->getSubExpr(), CallCtx);
+      // Ignore & and * operators -- they're no-ops.
+      // However, we try to figure out whether the expression is a pointer,
+      // so we can use . and -> appropriately in error messages.
+      if (UOE->getOpcode() == UO_Deref) {
+        if (NDeref) ++(*NDeref);
+        return buildSExpr(UOE->getSubExpr(), CallCtx, NDeref);
+      }
+      if (UOE->getOpcode() == UO_AddrOf) {
+        if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(UOE->getSubExpr())) {
+          if (DRE->getDecl()->isCXXInstanceMember()) {
+            // This is a pointer-to-member expression, e.g. &MyClass::mu_.
+            // We interpret this syntax specially, as a wildcard.
+            unsigned Root = makeDot(DRE->getDecl(), false);
+            makeWildcard();
+            NodeVec[Root].setSize(2);
+            return 2;
+          }
+        }
+        if (NDeref) --(*NDeref);
+        return buildSExpr(UOE->getSubExpr(), CallCtx, NDeref);
+      }
+      unsigned Root = makeUnary();
+      unsigned Sz = buildSExpr(UOE->getSubExpr(), CallCtx);
+      NodeVec[Root].setSize(Sz);
+      return Sz;
     } else if (ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(Exp)) {
-      buildMutexID(ASE->getBase(), CallCtx);
-      buildMutexID(ASE->getIdx(), CallCtx);
+      unsigned Root = makeIndex();
+      unsigned Sz = buildSExpr(ASE->getBase(), CallCtx);
+      Sz += buildSExpr(ASE->getIdx(), CallCtx);
+      NodeVec[Root].setSize(Sz);
+      return Sz;
     } else if (AbstractConditionalOperator *CE =
-                 dyn_cast<AbstractConditionalOperator>(Exp)) {
-      buildMutexID(CE->getCond(), CallCtx);
-      buildMutexID(CE->getTrueExpr(), CallCtx);
-      buildMutexID(CE->getFalseExpr(), CallCtx);
+               dyn_cast<AbstractConditionalOperator>(Exp)) {
+      unsigned Root = makeUnknown(3);
+      unsigned Sz = buildSExpr(CE->getCond(), CallCtx);
+      Sz += buildSExpr(CE->getTrueExpr(), CallCtx);
+      Sz += buildSExpr(CE->getFalseExpr(), CallCtx);
+      NodeVec[Root].setSize(Sz);
+      return Sz;
     } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(Exp)) {
-      buildMutexID(CE->getCond(), CallCtx);
-      buildMutexID(CE->getLHS(), CallCtx);
-      buildMutexID(CE->getRHS(), CallCtx);
+      unsigned Root = makeUnknown(3);
+      unsigned Sz = buildSExpr(CE->getCond(), CallCtx);
+      Sz += buildSExpr(CE->getLHS(), CallCtx);
+      Sz += buildSExpr(CE->getRHS(), CallCtx);
+      NodeVec[Root].setSize(Sz);
+      return Sz;
     } else if (CastExpr *CE = dyn_cast<CastExpr>(Exp)) {
-      buildMutexID(CE->getSubExpr(), CallCtx);
+      return buildSExpr(CE->getSubExpr(), CallCtx, NDeref);
     } else if (ParenExpr *PE = dyn_cast<ParenExpr>(Exp)) {
-      buildMutexID(PE->getSubExpr(), CallCtx);
+      return buildSExpr(PE->getSubExpr(), CallCtx, NDeref);
     } else if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Exp)) {
-      buildMutexID(EWC->getSubExpr(), CallCtx);
+      return buildSExpr(EWC->getSubExpr(), CallCtx, NDeref);
     } else if (CXXBindTemporaryExpr *E = dyn_cast<CXXBindTemporaryExpr>(Exp)) {
-      buildMutexID(E->getSubExpr(), CallCtx);
+      return buildSExpr(E->getSubExpr(), CallCtx, NDeref);
     } else if (isa<CharacterLiteral>(Exp) ||
                isa<CXXNullPtrLiteralExpr>(Exp) ||
                isa<GNUNullExpr>(Exp) ||
@@ -236,34 +429,38 @@
                isa<IntegerLiteral>(Exp) ||
                isa<StringLiteral>(Exp) ||
                isa<ObjCStringLiteral>(Exp)) {
-      return;  // FIXME: Ignore literals for now
+      makeNop();
+      return 1;  // FIXME: Ignore literals for now
     } else {
-      // Ignore.  FIXME: mark as invalid expression?
+      makeNop();
+      return 1;  // Ignore.  FIXME: mark as invalid expression?
     }
   }
 
-  /// \brief Construct a MutexID from an expression.
+  /// \brief Construct a SExpr from an expression.
   /// \param MutexExp The original mutex expression within an attribute
   /// \param DeclExp An expression involving the Decl on which the attribute
   ///        occurs.
   /// \param D  The declaration to which the lock/unlock attribute is attached.
-  void buildMutexIDFromExp(Expr *MutexExp, Expr *DeclExp, const NamedDecl *D) {
+  void buildSExprFromExpr(Expr *MutexExp, Expr *DeclExp, const NamedDecl *D) {
     CallingContext CallCtx(D);
 
     // If we are processing a raw attribute expression, with no substitutions.
     if (DeclExp == 0) {
-      buildMutexID(MutexExp, 0);
+      buildSExpr(MutexExp, 0);
       return;
     }
 
     // Examine DeclExp to find SelfArg and FunArgs, which are used to substitute
     // for formal parameters when we call buildMutexID later.
     if (MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
-      CallCtx.SelfArg = ME->getBase();
+      CallCtx.SelfArg   = ME->getBase();
+      CallCtx.SelfArrow = ME->isArrow();
     } else if (CXXMemberCallExpr *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
-      CallCtx.SelfArg = CE->getImplicitObjectArgument();
-      CallCtx.NumArgs = CE->getNumArgs();
-      CallCtx.FunArgs = CE->getArgs();
+      CallCtx.SelfArg   = CE->getImplicitObjectArgument();
+      CallCtx.SelfArrow = dyn_cast<MemberExpr>(CE->getCallee())->isArrow();
+      CallCtx.NumArgs   = CE->getNumArgs();
+      CallCtx.FunArgs   = CE->getArgs();
     } else if (CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
       CallCtx.NumArgs = CE->getNumArgs();
       CallCtx.FunArgs = CE->getArgs();
@@ -278,32 +475,35 @@
 
     // If the attribute has no arguments, then assume the argument is "this".
     if (MutexExp == 0) {
-      buildMutexID(CallCtx.SelfArg, 0);
+      buildSExpr(CallCtx.SelfArg, 0);
       return;
     }
 
     // For most attributes.
-    buildMutexID(MutexExp, &CallCtx);
+    buildSExpr(MutexExp, &CallCtx);
+  }
+
+  /// \brief Get index of next sibling of node i.
+  unsigned getNextSibling(unsigned i) const {
+    return i + NodeVec[i].size();
   }
 
 public:
-  explicit MutexID(clang::Decl::EmptyShell e) {
-    DeclSeq.clear();
-  }
+  explicit SExpr(clang::Decl::EmptyShell e) { NodeVec.clear(); }
 
   /// \param MutexExp The original mutex expression within an attribute
   /// \param DeclExp An expression involving the Decl on which the attribute
   ///        occurs.
   /// \param D  The declaration to which the lock/unlock attribute is attached.
   /// Caller must check isValid() after construction.
-  MutexID(Expr* MutexExp, Expr *DeclExp, const NamedDecl* D) {
-    buildMutexIDFromExp(MutexExp, DeclExp, D);
+  SExpr(Expr* MutexExp, Expr *DeclExp, const NamedDecl* D) {
+    buildSExprFromExpr(MutexExp, DeclExp, D);
   }
 
   /// Return true if this is a valid decl sequence.
   /// Caller must call this by hand after construction to handle errors.
   bool isValid() const {
-    return !DeclSeq.empty();
+    return !NodeVec.empty();
   }
 
   /// Issue a warning about an invalid lock expression
@@ -318,57 +518,138 @@
       Handler.handleInvalidLockExp(Loc);
   }
 
-  bool operator==(const MutexID &other) const {
-    return DeclSeq == other.DeclSeq;
+  bool operator==(const SExpr &other) const {
+    return NodeVec == other.NodeVec;
   }
 
-  bool operator!=(const MutexID &other) const {
+  bool operator!=(const SExpr &other) const {
     return !(*this == other);
   }
 
-  // SmallVector overloads Operator< to do lexicographic ordering. Note that
-  // we use pointer equality (and <) to compare NamedDecls. This means the order
-  // of MutexIDs in a lockset is nondeterministic. In order to output
-  // diagnostics in a deterministic ordering, we must order all diagnostics to
-  // output by SourceLocation when iterating through this lockset.
-  bool operator<(const MutexID &other) const {
-    return DeclSeq < other.DeclSeq;
-  }
-
-  /// \brief Returns the name of the first Decl in the list for a given MutexID;
-  /// e.g. the lock expression foo.bar() has name "bar".
-  /// The caret will point unambiguously to the lock expression, so using this
-  /// name in diagnostics is a way to get simple, and consistent, mutex names.
-  /// We do not want to output the entire expression text for security reasons.
-  std::string getName() const {
-    assert(isValid());
-    if (!DeclSeq.front())
-      return "this";  // Use 0 to represent 'this'.
-    return DeclSeq.front()->getNameAsString();
-  }
-
-  void Profile(llvm::FoldingSetNodeID &ID) const {
-    for (SmallVectorImpl<NamedDecl*>::const_iterator I = DeclSeq.begin(),
-         E = DeclSeq.end(); I != E; ++I) {
-      ID.AddPointer(*I);
+  bool matches(const SExpr &Other, unsigned i = 0, unsigned j = 0) const {
+    if (NodeVec[i].matches(Other.NodeVec[j])) {
+      unsigned n = NodeVec[i].arity();
+      bool Result = true;
+      unsigned ci = i+1;  // first child of i
+      unsigned cj = j+1;  // first child of j
+      for (unsigned k = 0; k < n;
+           ++k, ci=getNextSibling(ci), cj = Other.getNextSibling(cj)) {
+        Result = Result && matches(Other, ci, cj);
+      }
+      return Result;
     }
+    return false;
+  }
+
+  /// \brief Pretty print a lock expression for use in error messages.
+  std::string toString(unsigned i = 0) const {
+    assert(isValid());
+    if (i >= NodeVec.size())
+      return "";
+
+    const SExprNode* N = &NodeVec[i];
+    switch (N->kind()) {
+      case EOP_Nop:
+        return "_";
+      case EOP_Wildcard:
+        return "(?)";
+      case EOP_This:
+        return "this";
+      case EOP_NVar:
+      case EOP_LVar: {
+        return N->getNamedDecl()->getNameAsString();
+      }
+      case EOP_Dot: {
+        if (NodeVec[i+1].kind() == EOP_Wildcard) {
+          std::string S = "&";
+          S += N->getNamedDecl()->getQualifiedNameAsString();
+          return S;
+        }
+        std::string FieldName = N->getNamedDecl()->getNameAsString();
+        if (NodeVec[i+1].kind() == EOP_This)
+          return FieldName;
+
+        std::string S = toString(i+1);
+        if (N->isArrow())
+          return S + "->" + FieldName;
+        else
+          return S + "." + FieldName;
+      }
+      case EOP_Call: {
+        std::string S = toString(i+1) + "(";
+        unsigned NumArgs = N->arity()-1;
+        unsigned ci = getNextSibling(i+1);
+        for (unsigned k=0; k<NumArgs; ++k, ci = getNextSibling(ci)) {
+          S += toString(ci);
+          if (k+1 < NumArgs) S += ",";
+        }
+        S += ")";
+        return S;
+      }
+      case EOP_MCall: {
+        std::string S = "";
+        if (NodeVec[i+1].kind() != EOP_This)
+          S = toString(i+1) + ".";
+        if (const NamedDecl *D = N->getFunctionDecl())
+          S += D->getNameAsString() + "(";
+        else
+          S += "#(";
+        unsigned NumArgs = N->arity()-1;
+        unsigned ci = getNextSibling(i+1);
+        for (unsigned k=0; k<NumArgs; ++k, ci = getNextSibling(ci)) {
+          S += toString(ci);
+          if (k+1 < NumArgs) S += ",";
+        }
+        S += ")";
+        return S;
+      }
+      case EOP_Index: {
+        std::string S1 = toString(i+1);
+        std::string S2 = toString(i+1 + NodeVec[i+1].size());
+        return S1 + "[" + S2 + "]";
+      }
+      case EOP_Unary: {
+        std::string S = toString(i+1);
+        return "#" + S;
+      }
+      case EOP_Binary: {
+        std::string S1 = toString(i+1);
+        std::string S2 = toString(i+1 + NodeVec[i+1].size());
+        return "(" + S1 + "#" + S2 + ")";
+      }
+      case EOP_Unknown: {
+        unsigned NumChildren = N->arity();
+        if (NumChildren == 0)
+          return "(...)";
+        std::string S = "(";
+        unsigned ci = i+1;
+        for (unsigned j = 0; j < NumChildren; ++j, ci = getNextSibling(ci)) {
+          S += toString(ci);
+          if (j+1 < NumChildren) S += "#";
+        }
+        S += ")";
+        return S;
+      }
+    }
+    return "";
   }
 };
 
 
-/// \brief A short list of MutexIDs
-class MutexIDList : public SmallVector<MutexID, 3> {
+
+/// \brief A short list of SExprs
+class MutexIDList : public SmallVector<SExpr, 3> {
 public:
-  /// \brief Return true if the list contains the specified MutexID
+  /// \brief Return true if the list contains the specified SExpr
   /// Performs a linear search, because these lists are almost always very small.
-  bool contains(const MutexID& M) {
+  bool contains(const SExpr& M) {
     for (iterator I=begin(),E=end(); I != E; ++I)
       if ((*I) == M) return true;
     return false;
   }
 
   /// \brief Push M onto list, bud discard duplicates
-  void push_back_nodup(const MutexID& M) {
+  void push_back_nodup(const SExpr& M) {
     if (!contains(M)) push_back(M);
   }
 };
@@ -390,14 +671,14 @@
   /// FIXME: add support for re-entrant locking and lock up/downgrading
   LockKind LKind;
   bool     Managed;            // for ScopedLockable objects
-  MutexID  UnderlyingMutex;    // for ScopedLockable objects
+  SExpr    UnderlyingMutex;    // for ScopedLockable objects
 
   LockData(SourceLocation AcquireLoc, LockKind LKind, bool M = false)
     : AcquireLoc(AcquireLoc), LKind(LKind), Managed(M),
       UnderlyingMutex(Decl::EmptyShell())
   {}
 
-  LockData(SourceLocation AcquireLoc, LockKind LKind, const MutexID &Mu)
+  LockData(SourceLocation AcquireLoc, LockKind LKind, const SExpr &Mu)
     : AcquireLoc(AcquireLoc), LKind(LKind), Managed(false),
       UnderlyingMutex(Mu)
   {}
@@ -417,9 +698,101 @@
 };
 
 
-/// A Lockset maps each MutexID (defined above) to information about how it has
+/// \brief A FactEntry stores a single fact that is known at a particular point
+/// in the program execution.  Currently, this is information regarding a lock
+/// that is held at that point.  
+struct FactEntry {
+  SExpr    MutID;
+  LockData LDat;
+
+  FactEntry(const SExpr& M, const LockData& L)
+    : MutID(M), LDat(L)
+  { }
+};
+
+
+typedef unsigned short FactID;
+
+/// \brief FactManager manages the memory for all facts that are created during 
+/// the analysis of a single routine.
+class FactManager {
+private:
+  std::vector<FactEntry> Facts;
+
+public:
+  FactID newLock(const SExpr& M, const LockData& L) {
+    Facts.push_back(FactEntry(M,L));
+    return static_cast<unsigned short>(Facts.size() - 1);
+  }
+
+  const FactEntry& operator[](FactID F) const { return Facts[F]; }
+  FactEntry&       operator[](FactID F)       { return Facts[F]; }
+};
+
+
+/// \brief A FactSet is the set of facts that are known to be true at a
+/// particular program point.  FactSets must be small, because they are 
+/// frequently copied, and are thus implemented as a set of indices into a
+/// table maintained by a FactManager.  A typical FactSet only holds 1 or 2 
+/// locks, so we can get away with doing a linear search for lookup.  Note
+/// that a hashtable or map is inappropriate in this case, because lookups
+/// may involve partial pattern matches, rather than exact matches.
+class FactSet {
+private:
+  typedef SmallVector<FactID, 4> FactVec;
+
+  FactVec FactIDs;
+
+public:
+  typedef FactVec::iterator       iterator;
+  typedef FactVec::const_iterator const_iterator;
+
+  iterator       begin()       { return FactIDs.begin(); }
+  const_iterator begin() const { return FactIDs.begin(); }
+
+  iterator       end()       { return FactIDs.end(); }
+  const_iterator end() const { return FactIDs.end(); }
+
+  bool isEmpty() const { return FactIDs.size() == 0; }
+
+  FactID addLock(FactManager& FM, const SExpr& M, const LockData& L) {
+    FactID F = FM.newLock(M, L);
+    FactIDs.push_back(F);
+    return F;
+  }
+
+  bool removeLock(FactManager& FM, const SExpr& M) {
+    unsigned n = FactIDs.size();
+    if (n == 0)
+      return false;
+
+    for (unsigned i = 0; i < n-1; ++i) {
+      if (FM[FactIDs[i]].MutID.matches(M)) {
+        FactIDs[i] = FactIDs[n-1];
+        FactIDs.pop_back();
+        return true;
+      }
+    }
+    if (FM[FactIDs[n-1]].MutID.matches(M)) {
+      FactIDs.pop_back();
+      return true;
+    }
+    return false;
+  }
+
+  LockData* findLock(FactManager& FM, const SExpr& M) const {
+    for (const_iterator I=begin(), E=end(); I != E; ++I) {
+      if (FM[*I].MutID.matches(M)) return &FM[*I].LDat;
+    }
+    return 0;
+  }
+};
+
+
+
+/// A Lockset maps each SExpr (defined above) to information about how it has
 /// been locked.
-typedef llvm::ImmutableMap<MutexID, LockData> Lockset;
+typedef llvm::ImmutableMap<SExpr, LockData> Lockset;
 typedef llvm::ImmutableMap<const NamedDecl*, unsigned> LocalVarContext;
 
 class LocalVariableMap;
@@ -431,15 +804,15 @@
 /// maintained for each block in the CFG.  See LocalVariableMap for more
 /// information about the contexts.
 struct CFGBlockInfo {
-  Lockset EntrySet;             // Lockset held at entry to block
-  Lockset ExitSet;              // Lockset held at exit from block
+  FactSet EntrySet;             // Lockset held at entry to block
+  FactSet ExitSet;              // Lockset held at exit from block
   LocalVarContext EntryContext; // Context held at entry to block
   LocalVarContext ExitContext;  // Context held at exit from block
   SourceLocation EntryLoc;      // Location of first statement in block
   SourceLocation ExitLoc;       // Location of last statement in block.
   unsigned EntryIndex;          // Used to replay contexts later
 
-  const Lockset &getSet(CFGBlockSide Side) const {
+  const FactSet &getSet(CFGBlockSide Side) const {
     return Side == CBS_Entry ? EntrySet : ExitSet;
   }
   SourceLocation getLocation(CFGBlockSide Side) const {
@@ -447,14 +820,12 @@
   }
 
 private:
-  CFGBlockInfo(Lockset EmptySet, LocalVarContext EmptyCtx)
-    : EntrySet(EmptySet), ExitSet(EmptySet),
-      EntryContext(EmptyCtx), ExitContext(EmptyCtx)
+  CFGBlockInfo(LocalVarContext EmptyCtx)
+    : EntryContext(EmptyCtx), ExitContext(EmptyCtx)
   { }
 
 public:
-  static CFGBlockInfo getEmptyBlockInfo(Lockset::Factory &F,
-                                        LocalVariableMap &M);
+  static CFGBlockInfo getEmptyBlockInfo(LocalVariableMap &M);
 };
 
 
@@ -672,9 +1043,8 @@
 
 
 // This has to be defined after LocalVariableMap.
-CFGBlockInfo CFGBlockInfo::getEmptyBlockInfo(Lockset::Factory &F,
-                                             LocalVariableMap &M) {
-  return CFGBlockInfo(F.getEmptyMap(), M.getEmptyContext());
+CFGBlockInfo CFGBlockInfo::getEmptyBlockInfo(LocalVariableMap &M) {
+  return CFGBlockInfo(M.getEmptyContext());
 }
 
 
@@ -956,17 +1326,16 @@
   friend class BuildLockset;
 
   ThreadSafetyHandler       &Handler;
-  Lockset::Factory          LocksetFactory;
   LocalVariableMap          LocalVarMap;
+  FactManager               FactMan;
   std::vector<CFGBlockInfo> BlockInfo;
 
 public:
   ThreadSafetyAnalyzer(ThreadSafetyHandler &H) : Handler(H) {}
 
-  Lockset addLock(const Lockset &LSet, const MutexID &Mutex,
-                  const LockData &LDat);
-  Lockset removeLock(const Lockset &LSet, const MutexID &Mutex,
-                     SourceLocation UnlockLoc, bool FullyRemove=false);
+  void addLock(FactSet &FSet, const SExpr &Mutex, const LockData &LDat);
+  void removeLock(FactSet &FSet, const SExpr &Mutex,
+                  SourceLocation UnlockLoc, bool FullyRemove=false);
 
   template <typename AttrType>
   void getMutexIDs(MutexIDList &Mtxs, AttrType *Attr, Expr *Exp,
@@ -981,17 +1350,19 @@
   const CallExpr* getTrylockCallExpr(const Stmt *Cond, LocalVarContext C,
                                      bool &Negate);
 
-  Lockset getEdgeLockset(const Lockset &ExitSet,
-                         const CFGBlock* PredBlock,
-                         const CFGBlock *CurrBlock);
+  void getEdgeLockset(FactSet &Result, const FactSet &ExitSet,
+                      const CFGBlock* PredBlock,
+                      const CFGBlock *CurrBlock);
 
-  Lockset intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2,
-                           SourceLocation JoinLoc,
-                           LockErrorKind LEK1, LockErrorKind LEK2);
+  void intersectAndWarn(FactSet &FSet1, const FactSet &FSet2,
+                        SourceLocation JoinLoc,
+                        LockErrorKind LEK1, LockErrorKind LEK2,
+                        bool Modify=true);
 
-  Lockset intersectAndWarn(const Lockset &LSet1, const Lockset &LSet2,
-                           SourceLocation JoinLoc, LockErrorKind LEK1) {
-    return intersectAndWarn(LSet1, LSet2, JoinLoc, LEK1, LEK1);
+  void intersectAndWarn(FactSet &FSet1, const FactSet &FSet2,
+                        SourceLocation JoinLoc, LockErrorKind LEK1,
+                        bool Modify=true) {
+    intersectAndWarn(FSet1, FSet2, JoinLoc, LEK1, LEK1, Modify);
   }
 
   void runAnalysis(AnalysisDeclContext &AC);
@@ -1001,16 +1372,14 @@
 /// \brief Add a new lock to the lockset, warning if the lock is already there.
 /// \param Mutex -- the Mutex expression for the lock
 /// \param LDat  -- the LockData for the lock
-Lockset ThreadSafetyAnalyzer::addLock(const Lockset &LSet,
-                                      const MutexID &Mutex,
-                                      const LockData &LDat) {
+void ThreadSafetyAnalyzer::addLock(FactSet &FSet, const SExpr &Mutex,
+                                   const LockData &LDat) {
   // FIXME: deal with acquired before/after annotations.
   // FIXME: Don't always warn when we have support for reentrant locks.
-  if (LSet.lookup(Mutex)) {
-    Handler.handleDoubleLock(Mutex.getName(), LDat.AcquireLoc);
-    return LSet;
+  if (FSet.findLock(FactMan, Mutex)) {
+    Handler.handleDoubleLock(Mutex.toString(), LDat.AcquireLoc);
   } else {
-    return LocksetFactory.add(LSet, Mutex, LDat);
+    FSet.addLock(FactMan, Mutex, LDat);
   }
 }
 
@@ -1018,36 +1387,35 @@
 /// \brief Remove a lock from the lockset, warning if the lock is not there.
 /// \param LockExp The lock expression corresponding to the lock to be removed
 /// \param UnlockLoc The source location of the unlock (only used in error msg)
-Lockset ThreadSafetyAnalyzer::removeLock(const Lockset &LSet,
-                                         const MutexID &Mutex,
-                                         SourceLocation UnlockLoc,
-                                         bool FullyRemove) {
-  const LockData *LDat = LSet.lookup(Mutex);
+void ThreadSafetyAnalyzer::removeLock(FactSet &FSet,
+                                      const SExpr &Mutex,
+                                      SourceLocation UnlockLoc,
+                                      bool FullyRemove) {
+  const LockData *LDat = FSet.findLock(FactMan, Mutex);
   if (!LDat) {
-    Handler.handleUnmatchedUnlock(Mutex.getName(), UnlockLoc);
-    return LSet;
+    Handler.handleUnmatchedUnlock(Mutex.toString(), UnlockLoc);
+    return;
   }
+
   if (LDat->UnderlyingMutex.isValid()) {
     // This is scoped lockable object, which manages the real mutex.
     if (FullyRemove) {
       // We're destroying the managing object.
       // Remove the underlying mutex if it exists; but don't warn.
-      Lockset Result = LSet;
-      if (LSet.contains(LDat->UnderlyingMutex))
-        Result = LocksetFactory.remove(Result, LDat->UnderlyingMutex);
-      return LocksetFactory.remove(Result, Mutex);
+      if (FSet.findLock(FactMan, LDat->UnderlyingMutex))
+        FSet.removeLock(FactMan, LDat->UnderlyingMutex);
     } else {
       // We're releasing the underlying mutex, but not destroying the
       // managing object.  Warn on dual release.
-      if (!LSet.contains(LDat->UnderlyingMutex)) {
-        Handler.handleUnmatchedUnlock(LDat->UnderlyingMutex.getName(),
+      if (!FSet.findLock(FactMan, LDat->UnderlyingMutex)) {
+        Handler.handleUnmatchedUnlock(LDat->UnderlyingMutex.toString(),
                                       UnlockLoc);
-        return LSet;
       }
-      return LocksetFactory.remove(LSet, LDat->UnderlyingMutex);
+      FSet.removeLock(FactMan, LDat->UnderlyingMutex);
+      return;
     }
   }
-  return LocksetFactory.remove(LSet, Mutex);
+  FSet.removeLock(FactMan, Mutex);
 }
 
 
@@ -1060,18 +1428,18 @@
 
   if (Attr->args_size() == 0) {
     // The mutex held is the "this" object.
-    MutexID Mu(0, Exp, D);
+    SExpr Mu(0, Exp, D);
     if (!Mu.isValid())
-      MutexID::warnInvalidLock(Handler, 0, Exp, D);
+      SExpr::warnInvalidLock(Handler, 0, Exp, D);
     else
       Mtxs.push_back_nodup(Mu);
     return;
   }
 
   for (iterator_type I=Attr->args_begin(), E=Attr->args_end(); I != E; ++I) {
-    MutexID Mu(*I, Exp, D);
+    SExpr Mu(*I, Exp, D);
     if (!Mu.isValid())
-      MutexID::warnInvalidLock(Handler, *I, Exp, D);
+      SExpr::warnInvalidLock(Handler, *I, Exp, D);
     else
       Mtxs.push_back_nodup(Mu);
   }
@@ -1181,11 +1549,14 @@
 /// \brief Find the lockset that holds on the edge between PredBlock
 /// and CurrBlock.  The edge set is the exit set of PredBlock (passed
 /// as the ExitSet parameter) plus any trylocks, which are conditionally held.
-Lockset ThreadSafetyAnalyzer::getEdgeLockset(const Lockset &ExitSet,
-                                             const CFGBlock *PredBlock,
-                                             const CFGBlock *CurrBlock) {
+void ThreadSafetyAnalyzer::getEdgeLockset(FactSet& Result,
+                                          const FactSet &ExitSet,
+                                          const CFGBlock *PredBlock,
+                                          const CFGBlock *CurrBlock) {
+  Result = ExitSet;
+
   if (!PredBlock->getTerminatorCondition())
-    return ExitSet;
+    return;
 
   bool Negate = false;
   const Stmt *Cond = PredBlock->getTerminatorCondition();
@@ -1195,11 +1566,11 @@
   CallExpr *Exp =
     const_cast<CallExpr*>(getTrylockCallExpr(Cond, LVarCtx, Negate));
   if (!Exp)
-    return ExitSet;
+    return;
 
   NamedDecl *FunDecl = dyn_cast_or_null<NamedDecl>(Exp->getCalleeDecl());
   if(!FunDecl || !FunDecl->hasAttrs())
-    return ExitSet;
+    return;
 
 
   MutexIDList ExclusiveLocksToAdd;
@@ -1230,18 +1601,15 @@
   }
 
   // Add and remove locks.
-  Lockset Result = ExitSet;
   SourceLocation Loc = Exp->getExprLoc();
   for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-    Result = addLock(Result, ExclusiveLocksToAdd[i],
-                     LockData(Loc, LK_Exclusive));
+    addLock(Result, ExclusiveLocksToAdd[i],
+            LockData(Loc, LK_Exclusive));
   }
   for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-    Result = addLock(Result, SharedLocksToAdd[i],
-                     LockData(Loc, LK_Shared));
+    addLock(Result, SharedLocksToAdd[i],
+            LockData(Loc, LK_Shared));
   }
-
-  return Result;
 }
 
 
@@ -1254,7 +1622,7 @@
   friend class ThreadSafetyAnalyzer;
 
   ThreadSafetyAnalyzer *Analyzer;
-  Lockset LSet;
+  FactSet FSet;
   LocalVariableMap::Context LVarCtx;
   unsigned CtxIndex;
 
@@ -1270,14 +1638,14 @@
 
   /// \brief Returns true if the lockset contains a lock, regardless of whether
   /// the lock is held exclusively or shared.
-  bool locksetContains(const MutexID &Lock) const {
-    return LSet.lookup(Lock);
+  bool locksetContains(const SExpr &Mu) const {
+    return FSet.findLock(Analyzer->FactMan, Mu);
   }
 
   /// \brief Returns true if the lockset contains a lock with the passed in
   /// locktype.
-  bool locksetContains(const MutexID &Lock, LockKind KindRequested) const {
-    const LockData *LockHeld = LSet.lookup(Lock);
+  bool locksetContains(const SExpr &Mu, LockKind KindRequested) const {
+    const LockData *LockHeld = FSet.findLock(Analyzer->FactMan, Mu);
     return (LockHeld && KindRequested == LockHeld->LKind);
   }
 
@@ -1285,7 +1653,7 @@
   /// passed in locktype. So for example, if we pass in LK_Shared, this function
   /// returns true if the lock is held LK_Shared or LK_Exclusive. If we pass in
   /// LK_Exclusive, this function returns true if the lock is held LK_Exclusive.
-  bool locksetContainsAtLeast(const MutexID &Lock,
+  bool locksetContainsAtLeast(const SExpr &Lock,
                               LockKind KindRequested) const {
     switch (KindRequested) {
       case LK_Shared:
@@ -1300,7 +1668,7 @@
   BuildLockset(ThreadSafetyAnalyzer *Anlzr, CFGBlockInfo &Info)
     : StmtVisitor<BuildLockset>(),
       Analyzer(Anlzr),
-      LSet(Info.EntrySet),
+      FSet(Info.EntrySet),
       LVarCtx(Info.EntryContext),
       CtxIndex(Info.EntryIndex)
   {}
@@ -1332,11 +1700,11 @@
                                       ProtectedOperationKind POK) {
   LockKind LK = getLockKindFromAccessKind(AK);
 
-  MutexID Mutex(MutexExp, Exp, D);
+  SExpr Mutex(MutexExp, Exp, D);
   if (!Mutex.isValid())
-    MutexID::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D);
+    SExpr::warnInvalidLock(Analyzer->Handler, MutexExp, Exp, D);
   else if (!locksetContainsAtLeast(Mutex, LK))
-    Analyzer->Handler.handleMutexNotHeld(D, POK, Mutex.getName(), LK,
+    Analyzer->Handler.handleMutexNotHeld(D, POK, Mutex.toString(), LK,
                                          Exp->getExprLoc());
 }
 
@@ -1356,7 +1724,7 @@
   if(!D || !D->hasAttrs())
     return;
 
-  if (D->getAttr<PtGuardedVarAttr>() && LSet.isEmpty())
+  if (D->getAttr<PtGuardedVarAttr>() && FSet.isEmpty())
     Analyzer->Handler.handleNoMutexHeld(D, POK_VarDereference, AK,
                                         Exp->getExprLoc());
 
@@ -1375,7 +1743,7 @@
   if(!D || !D->hasAttrs())
     return;
 
-  if (D->getAttr<GuardedVarAttr>() && LSet.isEmpty())
+  if (D->getAttr<GuardedVarAttr>() && FSet.isEmpty())
     Analyzer->Handler.handleNoMutexHeld(D, POK_VarAccess, AK,
                                         Exp->getExprLoc());
 
@@ -1450,12 +1818,12 @@
         LocksExcludedAttr *A = cast<LocksExcludedAttr>(At);
         for (LocksExcludedAttr::args_iterator I = A->args_begin(),
             E = A->args_end(); I != E; ++I) {
-          MutexID Mutex(*I, Exp, D);
+          SExpr Mutex(*I, Exp, D);
           if (!Mutex.isValid())
-            MutexID::warnInvalidLock(Analyzer->Handler, *I, Exp, D);
+            SExpr::warnInvalidLock(Analyzer->Handler, *I, Exp, D);
           else if (locksetContains(Mutex))
             Analyzer->Handler.handleFunExcludesLock(D->getName(),
-                                                    Mutex.getName(),
+                                                    Mutex.toString(),
                                                     Exp->getExprLoc());
         }
         break;
@@ -1480,12 +1848,12 @@
   // Add locks.
   SourceLocation Loc = Exp->getExprLoc();
   for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-    LSet = Analyzer->addLock(LSet, ExclusiveLocksToAdd[i],
-                             LockData(Loc, LK_Exclusive, isScopedVar));
+    Analyzer->addLock(FSet, ExclusiveLocksToAdd[i],
+                            LockData(Loc, LK_Exclusive, isScopedVar));
   }
   for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-    LSet = Analyzer->addLock(LSet, SharedLocksToAdd[i],
-                             LockData(Loc, LK_Shared, isScopedVar));
+    Analyzer->addLock(FSet, SharedLocksToAdd[i],
+                            LockData(Loc, LK_Shared, isScopedVar));
   }
 
   // Add the managing object as a dummy mutex, mapped to the underlying mutex.
@@ -1493,15 +1861,15 @@
   if (isScopedVar) {
     SourceLocation MLoc = VD->getLocation();
     DeclRefExpr DRE(VD, false, VD->getType(), VK_LValue, VD->getLocation());
-    MutexID SMutex(&DRE, 0, 0);
+    SExpr SMutex(&DRE, 0, 0);
 
     for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-      LSet = Analyzer->addLock(LSet, SMutex, LockData(MLoc, LK_Exclusive,
-                                                      ExclusiveLocksToAdd[i]));
+      Analyzer->addLock(FSet, SMutex, LockData(MLoc, LK_Exclusive,
+                                               ExclusiveLocksToAdd[i]));
     }
     for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-      LSet = Analyzer->addLock(LSet, SMutex, LockData(MLoc, LK_Shared,
-                                                      SharedLocksToAdd[i]));
+      Analyzer->addLock(FSet, SMutex, LockData(MLoc, LK_Shared,
+                                               SharedLocksToAdd[i]));
     }
   }
 
@@ -1509,7 +1877,7 @@
   // FIXME -- should only fully remove if the attribute refers to 'this'.
   bool Dtor = isa<CXXDestructorDecl>(D);
   for (unsigned i=0,n=LocksToRemove.size(); i<n; ++i) {
-    LSet = Analyzer->removeLock(LSet, LocksToRemove[i], Loc, Dtor);
+    Analyzer->removeLock(FSet, LocksToRemove[i], Loc, Dtor);
   }
 }
 
@@ -1610,65 +1978,71 @@
 /// \param JoinLoc The location of the join point for error reporting
 /// \param LEK1 The error message to report if a mutex is missing from LSet1
 /// \param LEK2 The error message to report if a mutex is missing from Lset2
-Lockset ThreadSafetyAnalyzer::intersectAndWarn(const Lockset &LSet1,
-                                               const Lockset &LSet2,
-                                               SourceLocation JoinLoc,
-                                               LockErrorKind LEK1,
-                                               LockErrorKind LEK2) {
-  Lockset Intersection = LSet1;
+void ThreadSafetyAnalyzer::intersectAndWarn(FactSet &FSet1,
+                                            const FactSet &FSet2,
+                                            SourceLocation JoinLoc,
+                                            LockErrorKind LEK1,
+                                            LockErrorKind LEK2,
+                                            bool Modify) {
+  FactSet FSet1Orig = FSet1;
 
-  for (Lockset::iterator I = LSet2.begin(), E = LSet2.end(); I != E; ++I) {
-    const MutexID &LSet2Mutex = I.getKey();
-    const LockData &LDat2 = I.getData();
-    if (const LockData *LDat1 = LSet1.lookup(LSet2Mutex)) {
+  for (FactSet::const_iterator I = FSet2.begin(), E = FSet2.end();
+       I != E; ++I) {
+    const SExpr &FSet2Mutex = FactMan[*I].MutID;
+    const LockData &LDat2 = FactMan[*I].LDat;
+
+    if (const LockData *LDat1 = FSet1.findLock(FactMan, FSet2Mutex)) {
       if (LDat1->LKind != LDat2.LKind) {
-        Handler.handleExclusiveAndShared(LSet2Mutex.getName(),
+        Handler.handleExclusiveAndShared(FSet2Mutex.toString(),
                                          LDat2.AcquireLoc,
                                          LDat1->AcquireLoc);
-        if (LDat1->LKind != LK_Exclusive)
-          Intersection = LocksetFactory.add(Intersection, LSet2Mutex, LDat2);
+        if (Modify && LDat1->LKind != LK_Exclusive) {
+          FSet1.removeLock(FactMan, FSet2Mutex);
+          FSet1.addLock(FactMan, FSet2Mutex, LDat2);
+        }
       }
     } else {
       if (LDat2.UnderlyingMutex.isValid()) {
-        if (LSet2.lookup(LDat2.UnderlyingMutex)) {
+        if (FSet2.findLock(FactMan, LDat2.UnderlyingMutex)) {
           // If this is a scoped lock that manages another mutex, and if the
           // underlying mutex is still held, then warn about the underlying
           // mutex.
-          Handler.handleMutexHeldEndOfScope(LDat2.UnderlyingMutex.getName(),
+          Handler.handleMutexHeldEndOfScope(LDat2.UnderlyingMutex.toString(),
                                             LDat2.AcquireLoc,
                                             JoinLoc, LEK1);
         }
       }
       else if (!LDat2.Managed)
-        Handler.handleMutexHeldEndOfScope(LSet2Mutex.getName(),
+        Handler.handleMutexHeldEndOfScope(FSet2Mutex.toString(),
                                           LDat2.AcquireLoc,
                                           JoinLoc, LEK1);
     }
   }
 
-  for (Lockset::iterator I = LSet1.begin(), E = LSet1.end(); I != E; ++I) {
-    if (!LSet2.contains(I.getKey())) {
-      const MutexID &Mutex = I.getKey();
-      const LockData &LDat1 = I.getData();
+  for (FactSet::const_iterator I = FSet1.begin(), E = FSet1.end();
+       I != E; ++I) {
+    const SExpr &FSet1Mutex = FactMan[*I].MutID;
+    const LockData &LDat1 = FactMan[*I].LDat;
 
+    if (!FSet2.findLock(FactMan, FSet1Mutex)) {
       if (LDat1.UnderlyingMutex.isValid()) {
-        if (LSet1.lookup(LDat1.UnderlyingMutex)) {
+        if (FSet1Orig.findLock(FactMan, LDat1.UnderlyingMutex)) {
           // If this is a scoped lock that manages another mutex, and if the
           // underlying mutex is still held, then warn about the underlying
           // mutex.
-          Handler.handleMutexHeldEndOfScope(LDat1.UnderlyingMutex.getName(),
+          Handler.handleMutexHeldEndOfScope(LDat1.UnderlyingMutex.toString(),
                                             LDat1.AcquireLoc,
                                             JoinLoc, LEK1);
         }
       }
       else if (!LDat1.Managed)
-        Handler.handleMutexHeldEndOfScope(Mutex.getName(),
+        Handler.handleMutexHeldEndOfScope(FSet1Mutex.toString(),
                                           LDat1.AcquireLoc,
                                           JoinLoc, LEK2);
-      Intersection = LocksetFactory.remove(Intersection, Mutex);
+      if (Modify)
+        FSet1.removeLock(FactMan, FSet1Mutex);
     }
   }
-  return Intersection;
 }
 
 
@@ -1699,7 +2073,7 @@
     return;  // Don't check inside destructors.
 
   BlockInfo.resize(CFGraph->getNumBlockIDs(),
-    CFGBlockInfo::getEmptyBlockInfo(LocksetFactory, LocalVarMap));
+    CFGBlockInfo::getEmptyBlockInfo(LocalVarMap));
 
   // We need to explore the CFG via a "topological" ordering.
   // That way, we will be guaranteed to have information about required
@@ -1718,7 +2092,7 @@
   // FIXME: is there a more intelligent way to check lock/unlock functions?
   if (!SortedGraph->empty() && D->hasAttrs()) {
     const CFGBlock *FirstBlock = *SortedGraph->begin();
-    Lockset &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
+    FactSet &InitialLockset = BlockInfo[FirstBlock->getBlockID()].EntrySet;
     const AttrVec &ArgAttrs = D->getAttrs();
 
     MutexIDList ExclusiveLocksToAdd;
@@ -1754,12 +2128,12 @@
 
     // FIXME -- Loc can be wrong here.
     for (unsigned i=0,n=ExclusiveLocksToAdd.size(); i<n; ++i) {
-      InitialLockset = addLock(InitialLockset, ExclusiveLocksToAdd[i],
-                               LockData(Loc, LK_Exclusive));
+      addLock(InitialLockset, ExclusiveLocksToAdd[i],
+              LockData(Loc, LK_Exclusive));
     }
     for (unsigned i=0,n=SharedLocksToAdd.size(); i<n; ++i) {
-      InitialLockset = addLock(InitialLockset, SharedLocksToAdd[i],
-                               LockData(Loc, LK_Shared));
+      addLock(InitialLockset, SharedLocksToAdd[i],
+              LockData(Loc, LK_Shared));
     }
   }
 
@@ -1811,17 +2185,16 @@
 
       int PrevBlockID = (*PI)->getBlockID();
       CFGBlockInfo *PrevBlockInfo = &BlockInfo[PrevBlockID];
-      Lockset PrevLockset =
-        getEdgeLockset(PrevBlockInfo->ExitSet, *PI, CurrBlock);
+      FactSet PrevLockset;
+      getEdgeLockset(PrevLockset, PrevBlockInfo->ExitSet, *PI, CurrBlock);
 
       if (!LocksetInitialized) {
         CurrBlockInfo->EntrySet = PrevLockset;
         LocksetInitialized = true;
       } else {
-        CurrBlockInfo->EntrySet =
-          intersectAndWarn(CurrBlockInfo->EntrySet, PrevLockset,
-                           CurrBlockInfo->EntryLoc,
-                           LEK_LockedSomePredecessors);
+        intersectAndWarn(CurrBlockInfo->EntrySet, PrevLockset,
+                         CurrBlockInfo->EntryLoc,
+                         LEK_LockedSomePredecessors);
       }
     }
 
@@ -1845,14 +2218,16 @@
         const Stmt *Terminator = PrevBlock->getTerminator();
         bool IsLoop = Terminator && isa<ContinueStmt>(Terminator);
 
-        Lockset PrevLockset =
-          getEdgeLockset(PrevBlockInfo->ExitSet, PrevBlock, CurrBlock);
+        FactSet PrevLockset;
+        getEdgeLockset(PrevLockset, PrevBlockInfo->ExitSet,
+                       PrevBlock, CurrBlock);
 
         // Do not update EntrySet.
         intersectAndWarn(CurrBlockInfo->EntrySet, PrevLockset,
                          PrevBlockInfo->ExitLoc,
                          IsLoop ? LEK_LockedSomeLoopIterations
-                                : LEK_LockedSomePredecessors);
+                                : LEK_LockedSomePredecessors,
+                         false);
       }
     }
 
@@ -1886,7 +2261,7 @@
           break;
       }
     }
-    CurrBlockInfo->ExitSet = LocksetBuilder.LSet;
+    CurrBlockInfo->ExitSet = LocksetBuilder.FSet;
 
     // For every back edge from CurrBlock (the end of the loop) to another block
     // (FirstLoopBlock) we need to check that the Lockset of Block is equal to
@@ -1904,7 +2279,8 @@
       CFGBlockInfo *LoopEnd = &BlockInfo[CurrBlockID];
       intersectAndWarn(LoopEnd->ExitSet, PreLoop->EntrySet,
                        PreLoop->EntryLoc,
-                       LEK_LockedSomeLoopIterations);
+                       LEK_LockedSomeLoopIterations,
+                       false);
     }
   }
 
@@ -1915,7 +2291,8 @@
   intersectAndWarn(Initial->EntrySet, Final->ExitSet,
                    Final->ExitLoc,
                    LEK_LockedAtEndOfFunction,
-                   LEK_NotLockedAtEndOfFunction);
+                   LEK_NotLockedAtEndOfFunction,
+                   false);
 }
 
 } // end anonymous namespace
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 938944d..73e693b 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -43,9 +43,9 @@
   ClangDiagnosticDriver
   ClangDiagnosticFrontend
   ClangDiagnosticGroups
+  ClangDiagnosticIndexName
   ClangDiagnosticLex
   ClangDiagnosticParse
   ClangDiagnosticSema
   ClangDiagnosticSerialization
-  ClangDiagnosticIndexName
   )
diff --git a/lib/Basic/ConvertUTF.c b/lib/Basic/ConvertUTF.c
index e197003..4793b25 100644
--- a/lib/Basic/ConvertUTF.c
+++ b/lib/Basic/ConvertUTF.c
@@ -285,6 +285,7 @@
     *targetStart = target;
     return result;
 }
+#endif
 
 /* --------------------------------------------------------------------- */
 
@@ -339,8 +340,6 @@
     return result;
 }
 
-#endif
-
 /* --------------------------------------------------------------------- */
 
 /*
diff --git a/lib/Basic/ConvertUTFWrapper.cpp b/lib/Basic/ConvertUTFWrapper.cpp
index 42b4f58..a1b3f7f 100644
--- a/lib/Basic/ConvertUTFWrapper.cpp
+++ b/lib/Basic/ConvertUTFWrapper.cpp
@@ -51,4 +51,20 @@
   return result == conversionOK;
 }
 
+bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) {
+  const UTF32 *SourceStart = &Source;
+  const UTF32 *SourceEnd = SourceStart + 1;
+  UTF8 *TargetStart = reinterpret_cast<UTF8 *>(ResultPtr);
+  UTF8 *TargetEnd = TargetStart + 4;
+  ConversionResult CR = ConvertUTF32toUTF8(&SourceStart, SourceEnd,
+                                           &TargetStart, TargetEnd,
+                                           strictConversion);
+  if (CR != conversionOK)
+    return false;
+
+  ResultPtr = reinterpret_cast<char*>(TargetStart);
+  return true;
 }
+
+} // end namespace clang
+
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index cfc07b8..8065b2d 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -17,6 +17,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/CrashRecoveryContext.h"
+#include <cctype>
 
 using namespace clang;
 
@@ -118,7 +119,7 @@
   // Create a DiagState and DiagStatePoint representing diagnostic changes
   // through command-line.
   DiagStates.push_back(DiagState());
-  PushDiagStatePoint(&DiagStates.back(), SourceLocation());
+  DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc()));
 }
 
 void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
@@ -144,6 +145,9 @@
   assert(DiagStatePoints.front().Loc.isInvalid() &&
          "Should have created a DiagStatePoint for command-line");
 
+  if (!SourceMgr)
+    return DiagStatePoints.end() - 1;
+
   FullSourceLoc Loc(L, *SourceMgr);
   if (Loc.isInvalid())
     return DiagStatePoints.end() - 1;
@@ -166,8 +170,9 @@
           (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
          "Cannot map errors into warnings!");
   assert(!DiagStatePoints.empty());
+  assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
 
-  FullSourceLoc Loc(L, *SourceMgr);
+  FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
   FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
   // Don't allow a mapping to a warning override an error/fatal mapping.
   if (Map == diag::MAP_WARNING) {
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index b921f3e..c6b894c 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -223,6 +223,10 @@
   PrevCache->setNextStatCache(statCache->getNextStatCache());
 }
 
+void FileManager::clearStatCaches() {
+  StatCache.reset(0);
+}
+
 /// \brief Retrieve the directory that the given file name resides in.
 /// Filename can point to either a real file or a virtual file.
 static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 92cc179..4869ae1 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/ErrorHandling.h"
+#include <cctype>
 #include <cstdio>
 
 using namespace clang;
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 881072b..b19fe86 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -373,6 +373,7 @@
   OpenBSDTargetInfo(const std::string &triple)
     : OSTargetInfo<Target>(triple) {
       this->UserLabelPrefix = "";
+      this->TLSSupported = false;
 
       llvm::Triple Triple(triple);
       switch (Triple.getArch()) {
@@ -393,6 +394,29 @@
   }
 };
 
+// Bitrig Target
+template<typename Target>
+class BitrigTargetInfo : public OSTargetInfo<Target> {
+protected:
+  virtual void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                            MacroBuilder &Builder) const {
+    // Bitrig defines; list based off of gcc output
+
+    Builder.defineMacro("__Bitrig__");
+    DefineStd(Builder, "unix", Opts);
+    Builder.defineMacro("__ELF__");
+    if (Opts.POSIXThreads)
+      Builder.defineMacro("_REENTRANT");
+  }
+public:
+  BitrigTargetInfo(const std::string &triple)
+    : OSTargetInfo<Target>(triple) {
+      this->UserLabelPrefix = "";
+      this->TLSSupported = false;
+      this->MCountName = "__mcount";
+  }
+};
+
 // PSP Target
 template<typename Target>
 class PSPTargetInfo : public OSTargetInfo<Target> {
@@ -768,8 +792,6 @@
   Builder.defineMacro("__POWERPC__");
   if (PointerWidth == 64) {
     Builder.defineMacro("_ARCH_PPC64");
-    Builder.defineMacro("_LP64");
-    Builder.defineMacro("__LP64__");
     Builder.defineMacro("__powerpc64__");
     Builder.defineMacro("__ppc64__");
   } else {
@@ -777,7 +799,8 @@
   }
 
   // Target properties.
-  if (getTriple().getOS() != llvm::Triple::NetBSD)
+  if (getTriple().getOS() != llvm::Triple::NetBSD &&
+      getTriple().getOS() != llvm::Triple::OpenBSD)
     Builder.defineMacro("_BIG_ENDIAN");
   Builder.defineMacro("__BIG_ENDIAN__");
 
@@ -2049,10 +2072,6 @@
                                      MacroBuilder &Builder) const {
   // Target identification.
   if (PointerWidth == 64) {
-    if (getLongWidth() == 64) {
-      Builder.defineMacro("_LP64");
-      Builder.defineMacro("__LP64__");
-    }
     Builder.defineMacro("__amd64__");
     Builder.defineMacro("__amd64");
     Builder.defineMacro("__x86_64");
@@ -2441,6 +2460,18 @@
 } // end anonymous namespace
 
 namespace {
+class BitrigI386TargetInfo : public BitrigTargetInfo<X86_32TargetInfo> {
+public:
+  BitrigI386TargetInfo(const std::string& triple) :
+    BitrigTargetInfo<X86_32TargetInfo>(triple) {
+    SizeType = UnsignedLong;
+    IntPtrType = SignedLong;
+    PtrDiffType = SignedLong;
+  }
+};
+} // end anonymous namespace
+
+namespace {
 class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
 public:
   DarwinI386TargetInfo(const std::string& triple) :
@@ -2774,6 +2805,18 @@
 } // end anonymous namespace
 
 namespace {
+class BitrigX86_64TargetInfo : public BitrigTargetInfo<X86_64TargetInfo> {
+public:
+  BitrigX86_64TargetInfo(const std::string& triple)
+      : BitrigTargetInfo<X86_64TargetInfo>(triple) {
+     IntMaxType = SignedLongLong;
+     UIntMaxType = UnsignedLongLong;
+     Int64Type = SignedLongLong;
+  }
+};
+} // end anonymous namespace
+
+namespace {
 class ARMTargetInfo : public TargetInfo {
   // Possible FPU choices.
   enum FPUMode {
@@ -3042,9 +3085,8 @@
                                 unsigned &NumAliases) const;
   virtual bool validateAsmConstraint(const char *&Name,
                                      TargetInfo::ConstraintInfo &Info) const {
-    // FIXME: Check if this is complete
     switch (*Name) {
-    default:
+    default: break;
     case 'l': // r0-r7
     case 'h': // r8-r15
     case 'w': // VFP Floating point register single precision
@@ -4153,6 +4195,10 @@
       return new FreeBSDTargetInfo<ARMTargetInfo>(T);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<ARMTargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<ARMTargetInfo>(T);
+    case llvm::Triple::Bitrig:
+      return new BitrigTargetInfo<ARMTargetInfo>(T);
     case llvm::Triple::RTEMS:
       return new RTEMSTargetInfo<ARMTargetInfo>(T);
     default:
@@ -4200,6 +4246,8 @@
       return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<Mips64EBTargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<Mips64EBTargetInfo>(T);
     default:
       return new Mips64EBTargetInfo(T);
     }
@@ -4214,6 +4262,8 @@
       return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<Mips64ELTargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<Mips64ELTargetInfo>(T);
     default:
       return new Mips64ELTargetInfo(T);
     }
@@ -4236,6 +4286,8 @@
       return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<PPC32TargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<PPC32TargetInfo>(T);
     case llvm::Triple::RTEMS:
       return new RTEMSTargetInfo<PPC32TargetInfo>(T);
     default:
@@ -4276,6 +4328,8 @@
       return new SolarisSparcV8TargetInfo(T);
     case llvm::Triple::NetBSD:
       return new NetBSDTargetInfo<SparcV8TargetInfo>(T);
+    case llvm::Triple::OpenBSD:
+      return new OpenBSDTargetInfo<SparcV8TargetInfo>(T);
     case llvm::Triple::RTEMS:
       return new RTEMSTargetInfo<SparcV8TargetInfo>(T);
     default:
@@ -4304,6 +4358,8 @@
       return new NetBSDI386TargetInfo(T);
     case llvm::Triple::OpenBSD:
       return new OpenBSDI386TargetInfo(T);
+    case llvm::Triple::Bitrig:
+      return new BitrigI386TargetInfo(T);
     case llvm::Triple::FreeBSD:
       return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
     case llvm::Triple::Minix:
@@ -4339,6 +4395,8 @@
       return new NetBSDTargetInfo<X86_64TargetInfo>(T);
     case llvm::Triple::OpenBSD:
       return new OpenBSDX86_64TargetInfo(T);
+    case llvm::Triple::Bitrig:
+      return new BitrigX86_64TargetInfo(T);
     case llvm::Triple::FreeBSD:
       return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
     case llvm::Triple::Solaris:
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 2853bc8..86f5380 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -74,31 +74,42 @@
     unsigned UIntData;
     bool BoolData0;
     bool BoolData1;
+    bool InReg;
 
-    ABIArgInfo(Kind K, llvm::Type *TD=0, unsigned UI=0,
-               bool B0 = false, bool B1 = false, llvm::Type* P = 0)
+    ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR,
+               llvm::Type* P)
       : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0),
-        BoolData1(B1) {}
+        BoolData1(B1), InReg(IR) {}
 
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
 
     static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0,
                                 llvm::Type *Padding = 0) {
-      return ABIArgInfo(Direct, T, Offset, false, false, Padding);
+      return ABIArgInfo(Direct, T, Offset, false, false, false, Padding);
+    }
+    static ABIArgInfo getDirectInReg(llvm::Type *T) {
+      return ABIArgInfo(Direct, T, 0, false, false, true, 0);
     }
     static ABIArgInfo getExtend(llvm::Type *T = 0) {
-      return ABIArgInfo(Extend, T, 0);
+      return ABIArgInfo(Extend, T, 0, false, false, false, 0);
+    }
+    static ABIArgInfo getExtendInReg(llvm::Type *T = 0) {
+      return ABIArgInfo(Extend, T, 0, false, false, true, 0);
     }
     static ABIArgInfo getIgnore() {
-      return ABIArgInfo(Ignore);
+      return ABIArgInfo(Ignore, 0, 0, false, false, false, 0);
     }
     static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
                                   , bool Realign = false) {
-      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign);
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, 0);
+    }
+    static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true
+                                  , bool Realign = false) {
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, 0);
     }
     static ABIArgInfo getExpand() {
-      return ABIArgInfo(Expand);
+      return ABIArgInfo(Expand, 0, 0, false, false, false, 0);
     }
 
     Kind getKind() const { return TheKind; }
@@ -132,6 +143,11 @@
       TypeData = T;
     }
 
+    bool getInReg() const {
+      assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
+      return InReg;
+    }
+
     // Indirect accessors
     unsigned getIndirectAlign() const {
       assert(TheKind == Indirect && "Invalid kind!");
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 0a1915b..36b244b 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -375,6 +375,7 @@
   Options.DisableTailCalls = CodeGenOpts.DisableTailCalls;
   Options.TrapFuncName = CodeGenOpts.TrapFuncName;
   Options.PositionIndependentExecutable = LangOpts.PIELevel != 0;
+  Options.SSPBufferSize = CodeGenOpts.SSPBufferSize;
 
   TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU,
                                                      FeaturesStr, Options,
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index e47a9a3..59ed313 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -229,6 +229,35 @@
 
     return RValue::get(Result);
   }
+  
+  case Builtin::BI__builtin_conj:
+  case Builtin::BI__builtin_conjf:
+  case Builtin::BI__builtin_conjl: {
+    ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
+    Value *Real = ComplexVal.first;
+    Value *Imag = ComplexVal.second;
+    Value *Zero = 
+      Imag->getType()->isFPOrFPVectorTy() 
+        ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType())
+        : llvm::Constant::getNullValue(Imag->getType());
+    
+    Imag = Builder.CreateFSub(Zero, Imag, "sub");
+    return RValue::getComplex(std::make_pair(Real, Imag));
+  }
+  case Builtin::BI__builtin_creal:
+  case Builtin::BI__builtin_crealf:
+  case Builtin::BI__builtin_creall: {
+    ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
+    return RValue::get(ComplexVal.first);
+  }
+      
+  case Builtin::BI__builtin_cimag:
+  case Builtin::BI__builtin_cimagf:
+  case Builtin::BI__builtin_cimagl: {
+    ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
+    return RValue::get(ComplexVal.second);
+  }
+      
   case Builtin::BI__builtin_ctzs:
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
@@ -365,6 +394,10 @@
     Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
     return RValue::get(Builder.CreateCall4(F, Address, RW, Locality, Data));
   }
+  case Builtin::BI__builtin_readcyclecounter: {
+    Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
+    return RValue::get(Builder.CreateCall(F));
+  }
   case Builtin::BI__builtin_trap: {
     Value *F = CGM.getIntrinsic(Intrinsic::trap);
     return RValue::get(Builder.CreateCall(F));
@@ -1716,8 +1749,29 @@
     Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty),
                         Ops, "vld1");
-  case ARM::BI__builtin_neon_vld1_lane_v:
-  case ARM::BI__builtin_neon_vld1q_lane_v: {
+  case ARM::BI__builtin_neon_vld1q_lane_v:
+    // Handle 64-bit integer elements as a special case.  Use shuffles of
+    // one-element vectors to avoid poor code for i64 in the backend.
+    if (VTy->getElementType()->isIntegerTy(64)) {
+      // Extract the other lane.
+      Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+      int Lane = cast<ConstantInt>(Ops[2])->getZExtValue();
+      Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane));
+      Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
+      // Load the value as a one-element vector.
+      Ty = llvm::VectorType::get(VTy->getElementType(), 1);
+      Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty);
+      Value *Ld = Builder.CreateCall2(F, Ops[0],
+                                      GetPointeeAlignmentValue(E->getArg(0)));
+      // Combine them.
+      SmallVector<Constant*, 2> Indices;
+      Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane));
+      Indices.push_back(ConstantInt::get(Int32Ty, Lane));
+      SV = llvm::ConstantVector::get(Indices);
+      return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane");
+    }
+    // fall through
+  case ARM::BI__builtin_neon_vld1_lane_v: {
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ty = llvm::PointerType::getUnqual(VTy->getElementType());
     Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
@@ -2082,8 +2136,19 @@
     Ops.push_back(GetPointeeAlignmentValue(E->getArg(0)));
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty),
                         Ops, "");
-  case ARM::BI__builtin_neon_vst1_lane_v:
-  case ARM::BI__builtin_neon_vst1q_lane_v: {
+  case ARM::BI__builtin_neon_vst1q_lane_v:
+    // Handle 64-bit integer elements as a special case.  Use a shuffle to get
+    // a one-element vector and avoid poor code for i64 in the backend.
+    if (VTy->getElementType()->isIntegerTy(64)) {
+      Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
+      Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2]));
+      Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
+      Ops[2] = GetPointeeAlignmentValue(E->getArg(0));
+      return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
+                                                 Ops[1]->getType()), Ops);
+    }
+    // fall through
+  case ARM::BI__builtin_neon_vst1_lane_v: {
     Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
     Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
     Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 37a9a5e..7d2b9d3 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -983,14 +983,18 @@
   case ABIArgInfo::Ignore:
     break;
 
-  case ABIArgInfo::Indirect:
-    PAL.push_back(llvm::AttributeWithIndex::get(Index,
-                                                llvm::Attribute::StructRet));
+  case ABIArgInfo::Indirect: {
+    llvm::Attributes SRETAttrs = llvm::Attribute::StructRet;
+    if (RetAI.getInReg())
+      SRETAttrs |= llvm::Attribute::InReg;
+    PAL.push_back(llvm::AttributeWithIndex::get(Index, SRETAttrs));
+
     ++Index;
     // sret disables readnone and readonly
     FuncAttrs &= ~(llvm::Attribute::ReadOnly |
                    llvm::Attribute::ReadNone);
     break;
+  }
 
   case ABIArgInfo::Expand:
     llvm_unreachable("Invalid ABI kind for return argument");
@@ -999,14 +1003,6 @@
   if (RetAttrs)
     PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs));
 
-  // FIXME: RegParm should be reduced in case of global register variable.
-  signed RegParm;
-  if (FI.getHasRegParm())
-    RegParm = FI.getRegParm();
-  else
-    RegParm = CodeGenOpts.NumRegisterParameters;
-
-  unsigned PointerWidth = getContext().getTargetInfo().getPointerWidth(0);
   for (CGFunctionInfo::const_arg_iterator it = FI.arg_begin(),
          ie = FI.arg_end(); it != ie; ++it) {
     QualType ParamType = it->type;
@@ -1024,22 +1020,22 @@
         Attrs |= llvm::Attribute::ZExt;
       // FALL THROUGH
     case ABIArgInfo::Direct:
-      if (RegParm > 0 &&
-          (ParamType->isIntegerType() || ParamType->isPointerType() ||
-           ParamType->isReferenceType())) {
-        RegParm -=
-        (Context.getTypeSize(ParamType) + PointerWidth - 1) / PointerWidth;
-        if (RegParm >= 0)
+      if (AI.getInReg())
           Attrs |= llvm::Attribute::InReg;
-      }
+
       // FIXME: handle sseregparm someday...
 
       // Increment Index if there is padding.
       Index += (AI.getPaddingType() != 0);
 
       if (llvm::StructType *STy =
-            dyn_cast<llvm::StructType>(AI.getCoerceToType()))
-        Index += STy->getNumElements()-1;  // 1 will be added below.
+          dyn_cast<llvm::StructType>(AI.getCoerceToType())) {
+        unsigned Extra = STy->getNumElements()-1;  // 1 will be added below.
+        if (Attrs != llvm::Attribute::None)
+          for (unsigned I = 0; I < Extra; ++I)
+            PAL.push_back(llvm::AttributeWithIndex::get(Index + I, Attrs));
+        Index += Extra;
+      }
       break;
 
     case ABIArgInfo::Indirect:
@@ -1405,7 +1401,8 @@
 static llvm::Value *tryRemoveRetainOfSelf(CodeGenFunction &CGF,
                                           llvm::Value *result) {
   // This is only applicable to a method with an immutable 'self'.
-  const ObjCMethodDecl *method = dyn_cast<ObjCMethodDecl>(CGF.CurCodeDecl);
+  const ObjCMethodDecl *method =
+    dyn_cast_or_null<ObjCMethodDecl>(CGF.CurCodeDecl);
   if (!method) return 0;
   const VarDecl *self = method->getSelfDecl();
   if (!self->getType().isConstQualified()) return 0;
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index b53f139..e37fa3a 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -105,30 +105,28 @@
 }
 
 static llvm::Value *
-ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ThisPtr,
-                                CharUnits NonVirtual, llvm::Value *Virtual) {
-  llvm::Type *PtrDiffTy = 
-    CGF.ConvertType(CGF.getContext().getPointerDiffType());
-  
-  llvm::Value *NonVirtualOffset = 0;
-  if (!NonVirtual.isZero())
-    NonVirtualOffset = llvm::ConstantInt::get(PtrDiffTy, 
-                                              NonVirtual.getQuantity());
-  
-  llvm::Value *BaseOffset;
-  if (Virtual) {
-    if (NonVirtualOffset)
-      BaseOffset = CGF.Builder.CreateAdd(Virtual, NonVirtualOffset);
-    else
-      BaseOffset = Virtual;
-  } else
-    BaseOffset = NonVirtualOffset;
+ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, llvm::Value *ptr,
+                                CharUnits nonVirtualOffset,
+                                llvm::Value *virtualOffset) {
+  // Assert that we have something to do.
+  assert(!nonVirtualOffset.isZero() || virtualOffset != 0);
+
+  // Compute the offset from the static and dynamic components.
+  llvm::Value *baseOffset;
+  if (!nonVirtualOffset.isZero()) {
+    baseOffset = llvm::ConstantInt::get(CGF.PtrDiffTy,
+                                        nonVirtualOffset.getQuantity());
+    if (virtualOffset) {
+      baseOffset = CGF.Builder.CreateAdd(virtualOffset, baseOffset);
+    }
+  } else {
+    baseOffset = virtualOffset;
+  }
   
   // Apply the base offset.
-  ThisPtr = CGF.Builder.CreateBitCast(ThisPtr, CGF.Int8PtrTy);
-  ThisPtr = CGF.Builder.CreateGEP(ThisPtr, BaseOffset, "add.ptr");
-
-  return ThisPtr;
+  ptr = CGF.Builder.CreateBitCast(ptr, CGF.Int8PtrTy);
+  ptr = CGF.Builder.CreateInBoundsGEP(ptr, baseOffset, "add.ptr");
+  return ptr;
 }
 
 llvm::Value *
@@ -142,72 +140,81 @@
   CastExpr::path_const_iterator Start = PathBegin;
   const CXXRecordDecl *VBase = 0;
   
-  // Get the virtual base.
+  // Sema has done some convenient canonicalization here: if the
+  // access path involved any virtual steps, the conversion path will
+  // *start* with a step down to the correct virtual base subobject,
+  // and hence will not require any further steps.
   if ((*Start)->isVirtual()) {
     VBase = 
       cast<CXXRecordDecl>((*Start)->getType()->getAs<RecordType>()->getDecl());
     ++Start;
   }
-  
+
+  // Compute the static offset of the ultimate destination within its
+  // allocating subobject (the virtual base, if there is one, or else
+  // the "complete" object that we see).
   CharUnits NonVirtualOffset = 
     ComputeNonVirtualBaseClassOffset(getContext(), VBase ? VBase : Derived,
                                      Start, PathEnd);
 
+  // If there's a virtual step, we can sometimes "devirtualize" it.
+  // For now, that's limited to when the derived type is final.
+  // TODO: "devirtualize" this for accesses to known-complete objects.
+  if (VBase && Derived->hasAttr<FinalAttr>()) {
+    const ASTRecordLayout &layout = getContext().getASTRecordLayout(Derived);
+    CharUnits vBaseOffset = layout.getVBaseClassOffset(VBase);
+    NonVirtualOffset += vBaseOffset;
+    VBase = 0; // we no longer have a virtual step
+  }
+
   // Get the base pointer type.
   llvm::Type *BasePtrTy = 
     ConvertType((PathEnd[-1])->getType())->getPointerTo();
-  
+
+  // If the static offset is zero and we don't have a virtual step,
+  // just do a bitcast; null checks are unnecessary.
   if (NonVirtualOffset.isZero() && !VBase) {
-    // Just cast back.
     return Builder.CreateBitCast(Value, BasePtrTy);
   }    
+
+  llvm::BasicBlock *origBB = 0;
+  llvm::BasicBlock *endBB = 0;
   
-  llvm::BasicBlock *CastNull = 0;
-  llvm::BasicBlock *CastNotNull = 0;
-  llvm::BasicBlock *CastEnd = 0;
-  
+  // Skip over the offset (and the vtable load) if we're supposed to
+  // null-check the pointer.
   if (NullCheckValue) {
-    CastNull = createBasicBlock("cast.null");
-    CastNotNull = createBasicBlock("cast.notnull");
-    CastEnd = createBasicBlock("cast.end");
+    origBB = Builder.GetInsertBlock();
+    llvm::BasicBlock *notNullBB = createBasicBlock("cast.notnull");
+    endBB = createBasicBlock("cast.end");
     
-    llvm::Value *IsNull = Builder.CreateIsNull(Value);
-    Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
-    EmitBlock(CastNotNull);
+    llvm::Value *isNull = Builder.CreateIsNull(Value);
+    Builder.CreateCondBr(isNull, endBB, notNullBB);
+    EmitBlock(notNullBB);
   }
 
+  // Compute the virtual offset.
   llvm::Value *VirtualOffset = 0;
-
   if (VBase) {
-    if (Derived->hasAttr<FinalAttr>()) {
-      VirtualOffset = 0;
-
-      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Derived);
-
-      CharUnits VBaseOffset = Layout.getVBaseClassOffset(VBase);
-      NonVirtualOffset += VBaseOffset;
-    } else
-      VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase);
+    VirtualOffset = GetVirtualBaseClassOffset(Value, Derived, VBase);
   }
 
-  // Apply the offsets.
+  // Apply both offsets.
   Value = ApplyNonVirtualAndVirtualOffset(*this, Value, 
                                           NonVirtualOffset,
                                           VirtualOffset);
   
-  // Cast back.
+  // Cast to the destination type.
   Value = Builder.CreateBitCast(Value, BasePtrTy);
- 
+
+  // Build a phi if we needed a null check.
   if (NullCheckValue) {
-    Builder.CreateBr(CastEnd);
-    EmitBlock(CastNull);
-    Builder.CreateBr(CastEnd);
-    EmitBlock(CastEnd);
+    llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
+    Builder.CreateBr(endBB);
+    EmitBlock(endBB);
     
-    llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
-    PHI->addIncoming(Value, CastNotNull);
-    PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), 
-                     CastNull);
+    llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2, "cast.result");
+    PHI->addIncoming(Value, notNullBB);
+    PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB);
     Value = PHI;
   }
   
@@ -556,16 +563,19 @@
 
   llvm::Value *ThisPtr = CGF.LoadCXXThis();
   QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
-  LValue LHS;
+  LValue LHS = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
 
-  // If we are initializing an anonymous union field, drill down to the field.
   if (MemberInit->isIndirectMemberInitializer()) {
-    LHS = CGF.EmitLValueForAnonRecordField(ThisPtr,
-                                           MemberInit->getIndirectMember(), 0);
+    // If we are initializing an anonymous union field, drill down to
+    // the field.
+    IndirectFieldDecl *IndirectField = MemberInit->getIndirectMember();
+    IndirectFieldDecl::chain_iterator I = IndirectField->chain_begin(),
+      IEnd = IndirectField->chain_end();
+    for ( ; I != IEnd; ++I)
+      LHS = CGF.EmitLValueForFieldInitialization(LHS, cast<FieldDecl>(*I));
     FieldType = MemberInit->getIndirectMember()->getAnonField()->getType();
   } else {
-    LValue ThisLHSLV = CGF.MakeNaturalAlignAddrLValue(ThisPtr, RecordTy);
-    LHS = CGF.EmitLValueForFieldInitialization(ThisLHSLV, Field);
+    LHS = CGF.EmitLValueForFieldInitialization(LHS, Field);
   }
 
   // Special case: if we are in a copy or move constructor, and we are copying
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index b00e2a2..f9ea7e0 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -831,8 +831,12 @@
 
     EmitBlock(EHEntry);
 
-    cleanupFlags.setIsForEHCleanup();
-    EmitCleanup(*this, Fn, cleanupFlags, EHActiveFlag);
+    // We only actually emit the cleanup code if the cleanup is either
+    // active or was used before it was deactivated.
+    if (EHActiveFlag || IsActive) {
+      cleanupFlags.setIsForEHCleanup();
+      EmitCleanup(*this, Fn, cleanupFlags, EHActiveFlag);
+    }
 
     Builder.CreateBr(getEHDispatchBlock(EHParent));
 
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index c604e56..d5cf4d0 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -94,8 +94,10 @@
 
   llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
     I = RegionMap.find(Context);
-  if (I != RegionMap.end())
-    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(&*I->second));
+  if (I != RegionMap.end()) {
+    llvm::Value *V = I->second;
+    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));
+  }
 
   // Check namespace.
   if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
@@ -227,8 +229,8 @@
 
   if (it != DIFileCache.end()) {
     // Verify that the information still exists.
-    if (&*it->second)
-      return llvm::DIFile(cast<llvm::MDNode>(it->second));
+    if (llvm::Value *V = it->second)
+      return llvm::DIFile(cast<llvm::MDNode>(V));
   }
 
   llvm::DIFile F = DBuilder.createFile(PLoc.getFilename(), getCurrentDirname());
@@ -349,40 +351,56 @@
   case BuiltinType::Void:
     return llvm::DIType();
   case BuiltinType::ObjCClass:
-    return DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                      "objc_class", TheCU,
-                                      getOrCreateMainFile(), 0);
+    if (ClassTy.Verify())
+      return ClassTy;
+    ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
+                                         "objc_class", TheCU,
+                                         getOrCreateMainFile(), 0);
+    return ClassTy;
   case BuiltinType::ObjCId: {
     // typedef struct objc_class *Class;
     // typedef struct objc_object {
     //  Class isa;
     // } *id;
 
-    // TODO: Cache these two types to avoid duplicates.
-    llvm::DIType OCTy =
-      DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
-                                 "objc_class", TheCU, getOrCreateMainFile(), 0);
+    if (ObjTy.Verify())
+      return ObjTy;
+
+    if (!ClassTy.Verify())
+      ClassTy = DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
+                                           "objc_class", TheCU,
+                                           getOrCreateMainFile(), 0);
+
     unsigned Size = CGM.getContext().getTypeSize(CGM.getContext().VoidPtrTy);
     
-    llvm::DIType ISATy = DBuilder.createPointerType(OCTy, Size);
+    llvm::DIType ISATy = DBuilder.createPointerType(ClassTy, Size);
 
-    SmallVector<llvm::Value *, 16> EltTys;
+    llvm::DIType FwdTy =  DBuilder.createStructType(TheCU, "objc_object", 
+                                                    getOrCreateMainFile(),
+                                                    0, 0, 0, 0,
+                                                    llvm::DIArray());
+
+    llvm::TrackingVH<llvm::MDNode> ObjNode(FwdTy);
+    SmallVector<llvm::Value *, 1> EltTys;
     llvm::DIType FieldTy = 
-      DBuilder.createMemberType(getOrCreateMainFile(), "isa",
+      DBuilder.createMemberType(llvm::DIDescriptor(ObjNode), "isa",
                                 getOrCreateMainFile(), 0, Size,
                                 0, 0, 0, ISATy);
     EltTys.push_back(FieldTy);
     llvm::DIArray Elements = DBuilder.getOrCreateArray(EltTys);
-    
-    return DBuilder.createStructType(TheCU, "objc_object", 
-                                     getOrCreateMainFile(),
-                                     0, 0, 0, 0, Elements);
+
+    ObjNode->replaceOperandWith(10, Elements);
+    ObjTy = llvm::DIType(ObjNode);
+    return ObjTy;
   }
   case BuiltinType::ObjCSel: {
-    return
+    if (SelTy.Verify())
+      return SelTy;
+    SelTy =
       DBuilder.createForwardDecl(llvm::dwarf::DW_TAG_structure_type,
                                  "objc_selector", TheCU, getOrCreateMainFile(),
                                  0);
+    return SelTy;
   }
   case BuiltinType::UChar:
   case BuiltinType::Char_U: Encoding = llvm::dwarf::DW_ATE_unsigned_char; break;
@@ -525,8 +543,10 @@
   // See if we already have the parent.
   llvm::DenseMap<const Decl *, llvm::WeakVH>::iterator
     I = RegionMap.find(Context);
-  if (I != RegionMap.end())
-    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(&*I->second));
+  if (I != RegionMap.end()) {
+    llvm::Value *V = I->second;
+    return llvm::DIDescriptor(dyn_cast_or_null<llvm::MDNode>(V));
+  }
   
   // Check namespace.
   if (const NamespaceDecl *NSDecl = dyn_cast<NamespaceDecl>(Context))
@@ -684,9 +704,9 @@
   // FIXME: IF NOT, HOW IS THIS REPRESENTED?  llvm-gcc doesn't represent '...'!
   if (isa<FunctionNoProtoType>(Ty))
     EltTys.push_back(DBuilder.createUnspecifiedParameter());
-  else if (const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(Ty)) {
-    for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i)
-      EltTys.push_back(getOrCreateType(FTP->getArgType(i), Unit));
+  else if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
+    for (unsigned i = 0, e = FPT->getNumArgs(); i != e; ++i)
+      EltTys.push_back(getOrCreateType(FPT->getArgType(i), Unit));
   }
 
   llvm::DIArray EltTypeArray = DBuilder.getOrCreateArray(EltTys);
@@ -911,7 +931,7 @@
   
   StringRef MethodName = getFunctionName(Method);
   llvm::DIType MethodTy = getOrCreateMethodType(Method, Unit);
-  
+
   // Since a single ctor/dtor corresponds to multiple functions, it doesn't
   // make sense to give a single ctor/dtor a linkage name.
   StringRef MethodLinkageName;
@@ -999,11 +1019,9 @@
     }
     else if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D))
       for (FunctionTemplateDecl::spec_iterator SI = FTD->spec_begin(),
-            SE = FTD->spec_end(); SI != SE; ++SI) {
-        FunctionDecl *FD = *SI;
-        if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(FD))
-          EltTys.push_back(CreateCXXMemberFunction(M, Unit, RecordTy));
-      }
+             SE = FTD->spec_end(); SI != SE; ++SI)
+        EltTys.push_back(CreateCXXMemberFunction(cast<CXXMethodDecl>(*SI), Unit,
+                                                 RecordTy));
   }
 }                                 
 
@@ -1468,7 +1486,10 @@
       CGM.getContext().getTypeAlign(CGM.getContext().getBaseElementType(VAT));
   } else if (Ty->isIncompleteArrayType()) {
     Size = 0;
-    Align = CGM.getContext().getTypeAlign(Ty->getElementType());
+    if (Ty->getElementType()->isIncompleteType())
+      Align = 0;
+    else
+      Align = CGM.getContext().getTypeAlign(Ty->getElementType());
   } else if (Ty->isDependentSizedArrayType() || Ty->isIncompleteType()) {
     Size = 0;
     Align = 0;
@@ -1537,7 +1558,7 @@
   uint64_t FieldOffset = 0;
   llvm::Value *ElementTypes[2];
   
-  // FIXME: This should probably be a function type instead.
+  // FIXME: This should be a DW_TAG_pointer_to_member type.
   ElementTypes[0] =
     DBuilder.createMemberType(U, "ptr", U, 0,
                               Info.first, Info.second, FieldOffset, 0,
@@ -1629,8 +1650,13 @@
     case Type::Paren:
       T = cast<ParenType>(T)->getInnerType();
       break;
-    case Type::SubstTemplateTypeParm:
+    case Type::SubstTemplateTypeParm: {
+      // We need to keep the qualifiers handy since getReplacementType()
+      // will strip them away.
+      unsigned Quals = T.getLocalFastQualifiers();
       T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
+      T.addFastQualifiers(Quals);
+    }
       break;
     case Type::Auto:
       T = cast<AutoType>(T)->getDeducedType();
@@ -1654,8 +1680,8 @@
     TypeCache.find(Ty.getAsOpaquePtr());
   if (it != TypeCache.end()) {
     // Verify that the debug info still exists.
-    if (&*it->second)
-      return llvm::DIType(cast<llvm::MDNode>(it->second));
+    if (llvm::Value *V = it->second)
+      return llvm::DIType(cast<llvm::MDNode>(V));
   }
 
   return llvm::DIType();
@@ -1673,8 +1699,8 @@
     CompletedTypeCache.find(Ty.getAsOpaquePtr());
   if (it != CompletedTypeCache.end()) {
     // Verify that the debug info still exists.
-    if (&*it->second)
-      return llvm::DIType(cast<llvm::MDNode>(it->second));
+    if (llvm::Value *V = it->second)
+      return llvm::DIType(cast<llvm::MDNode>(V));
   }
 
   return llvm::DIType();
@@ -1689,10 +1715,11 @@
 
   // Unwrap the type as needed for debug information.
   Ty = UnwrapTypeForDebugInfo(Ty);
-  
+
   llvm::DIType T = getCompletedTypeOrNull(Ty);
 
-  if (T.Verify()) return T;
+  if (T.Verify())
+    return T;
 
   // Otherwise create the type.
   llvm::DIType Res = CreateTypeNode(Ty, Unit);
@@ -1707,6 +1734,7 @@
 
   if (!Res.isForwardDecl())
     CompletedTypeCache[Ty.getAsOpaquePtr()] = Res;
+
   return Res;
 }
 
@@ -1934,7 +1962,8 @@
   llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
     MI = SPCache.find(FD->getCanonicalDecl());
   if (MI != SPCache.end()) {
-    llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(&*MI->second));
+    llvm::Value *V = MI->second;
+    llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V));
     if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition())
       return SP;
   }
@@ -1945,7 +1974,8 @@
     llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
       MI = SPCache.find(NextFD->getCanonicalDecl());
     if (MI != SPCache.end()) {
-      llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(&*MI->second));
+      llvm::Value *V = MI->second;
+      llvm::DISubprogram SP(dyn_cast_or_null<llvm::MDNode>(V));
       if (SP.isSubprogram() && !llvm::DISubprogram(SP).isDefinition())
         return SP;
     }
@@ -1958,6 +1988,7 @@
 llvm::DIType CGDebugInfo::getOrCreateFunctionType(const Decl * D,
                                                   QualType FnType,
                                                   llvm::DIFile F) {
+
   if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
     return getOrCreateMethodType(Method, F);
   if (const ObjCMethodDecl *OMethod = dyn_cast<ObjCMethodDecl>(D)) {
@@ -2004,7 +2035,8 @@
     llvm::DenseMap<const FunctionDecl *, llvm::WeakVH>::iterator
       FI = SPCache.find(FD->getCanonicalDecl());
     if (FI != SPCache.end()) {
-      llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(&*FI->second));
+      llvm::Value *V = FI->second;
+      llvm::DIDescriptor SP(dyn_cast_or_null<llvm::MDNode>(V));
       if (SP.isSubprogram() && llvm::DISubprogram(SP).isDefinition()) {
         llvm::MDNode *SPN = SP;
         LexicalBlockStack.push_back(SPN);
@@ -2601,9 +2633,7 @@
   if (T->isIncompleteArrayType()) {
 
     // CodeGen turns int[] into int[1] so we'll do the same here.
-    llvm::APSInt ConstVal(32);
-
-    ConstVal = 1;
+    llvm::APInt ConstVal(32, 1);
     QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
 
     T = CGM.getContext().getConstantArrayType(ET, ConstVal,
@@ -2637,9 +2667,7 @@
   if (T->isIncompleteArrayType()) {
 
     // CodeGen turns int[] into int[1] so we'll do the same here.
-    llvm::APSInt ConstVal(32);
-
-    ConstVal = 1;
+    llvm::APInt ConstVal(32, 1);
     QualType ET = CGM.getContext().getAsArrayType(T)->getElementType();
 
     T = CGM.getContext().getConstantArrayType(ET, ConstVal,
@@ -2696,15 +2724,15 @@
          = ReplaceMap.begin(), VE = ReplaceMap.end(); VI != VE; ++VI) {
     llvm::DIType Ty, RepTy;
     // Verify that the debug info still exists.
-    if (&*VI->second)
-      Ty = llvm::DIType(cast<llvm::MDNode>(VI->second));
+    if (llvm::Value *V = VI->second)
+      Ty = llvm::DIType(cast<llvm::MDNode>(V));
     
     llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
       TypeCache.find(VI->first);
     if (it != TypeCache.end()) {
       // Verify that the debug info still exists.
-      if (&*it->second)
-        RepTy = llvm::DIType(cast<llvm::MDNode>(it->second));
+      if (llvm::Value *V = it->second)
+        RepTy = llvm::DIType(cast<llvm::MDNode>(V));
     }
     
     if (Ty.Verify() && Ty.isForwardDecl() && RepTy.Verify()) {
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 44cc49a..2e88a73 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -50,6 +50,9 @@
   llvm::DICompileUnit TheCU;
   SourceLocation CurLoc, PrevLoc;
   llvm::DIType VTablePtrType;
+  llvm::DIType ClassTy;
+  llvm::DIType ObjTy;
+  llvm::DIType SelTy;
   
   /// TypeCache - Cache of previously constructed Types.
   llvm::DenseMap<void *, llvm::WeakVH> TypeCache;
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 7e5fdd0..1fe4c18 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -938,6 +938,50 @@
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
                                               unsigned Alignment, QualType Ty,
                                               llvm::MDNode *TBAAInfo) {
+  
+  // For better performance, handle vector loads differently.
+  if (Ty->isVectorType()) {
+    llvm::Value *V;
+    const llvm::Type *EltTy =
+    cast<llvm::PointerType>(Addr->getType())->getElementType();
+    
+    const llvm::VectorType *VTy = cast<llvm::VectorType>(EltTy);
+      
+    // Handle vectors of size 3, like size 4 for better performance.
+    if (VTy->getNumElements() == 3) {
+        
+      // Bitcast to vec4 type.
+      llvm::VectorType *vec4Ty = llvm::VectorType::get(VTy->getElementType(),
+                                                         4);
+      llvm::PointerType *ptVec4Ty =
+      llvm::PointerType::get(vec4Ty,
+                             (cast<llvm::PointerType>(
+                                      Addr->getType()))->getAddressSpace());
+      llvm::Value *Cast = Builder.CreateBitCast(Addr, ptVec4Ty,
+                                                "castToVec4");
+      // Now load value.
+      llvm::Value *LoadVal = Builder.CreateLoad(Cast, Volatile, "loadVec4");
+        
+      // Shuffle vector to get vec3.
+      llvm::SmallVector<llvm::Constant*, 3> Mask;
+      Mask.push_back(llvm::ConstantInt::get(
+                                    llvm::Type::getInt32Ty(getLLVMContext()),
+                                            0));
+      Mask.push_back(llvm::ConstantInt::get(
+                                    llvm::Type::getInt32Ty(getLLVMContext()),
+                                            1));
+      Mask.push_back(llvm::ConstantInt::get(
+                                     llvm::Type::getInt32Ty(getLLVMContext()),
+                                            2));
+        
+      llvm::Value *MaskV = llvm::ConstantVector::get(Mask);
+      V = Builder.CreateShuffleVector(LoadVal,
+                                      llvm::UndefValue::get(vec4Ty),
+                                      MaskV, "extractVec");
+      return EmitFromMemory(V, Ty);
+    }
+  }
+  
   llvm::LoadInst *Load = Builder.CreateLoad(Addr);
   if (Volatile)
     Load->setVolatile(true);
@@ -984,6 +1028,42 @@
                                         QualType Ty,
                                         llvm::MDNode *TBAAInfo,
                                         bool isInit) {
+  
+  // Handle vectors differently to get better performance.
+  if (Ty->isVectorType()) {
+    llvm::Type *SrcTy = Value->getType();
+    llvm::VectorType *VecTy = cast<llvm::VectorType>(SrcTy);
+    // Handle vec3 special.
+    if (VecTy->getNumElements() == 3) {
+      llvm::LLVMContext &VMContext = getLLVMContext();
+      
+      // Our source is a vec3, do a shuffle vector to make it a vec4.
+      llvm::SmallVector<llvm::Constant*, 4> Mask;
+      Mask.push_back(llvm::ConstantInt::get(
+                                            llvm::Type::getInt32Ty(VMContext),
+                                            0));
+      Mask.push_back(llvm::ConstantInt::get(
+                                            llvm::Type::getInt32Ty(VMContext),
+                                            1));
+      Mask.push_back(llvm::ConstantInt::get(
+                                            llvm::Type::getInt32Ty(VMContext),
+                                            2));
+      Mask.push_back(llvm::UndefValue::get(llvm::Type::getInt32Ty(VMContext)));
+      
+      llvm::Value *MaskV = llvm::ConstantVector::get(Mask);
+      Value = Builder.CreateShuffleVector(Value,
+                                          llvm::UndefValue::get(VecTy),
+                                          MaskV, "extractVec");
+      SrcTy = llvm::VectorType::get(VecTy->getElementType(), 4);
+    }
+    llvm::PointerType *DstPtr = cast<llvm::PointerType>(Addr->getType());
+    if (DstPtr->getElementType() != SrcTy) {
+      llvm::Type *MemTy =
+      llvm::PointerType::get(SrcTy, DstPtr->getAddressSpace());
+      Addr = Builder.CreateBitCast(Addr, MemTy, "storetmp");
+    }
+  }
+  
   Value = EmitToMemory(Value, Ty);
   
   llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
@@ -2056,28 +2136,6 @@
   llvm_unreachable("Unhandled member declaration!");
 }
 
-/// 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 IndirectFieldDecl *Field,
-                                                     unsigned CVRQualifiers) {
-  IndirectFieldDecl::chain_iterator I = Field->chain_begin(),
-    IEnd = Field->chain_end();
-  while (true) {
-    QualType RecordTy =
-        getContext().getTypeDeclType(cast<FieldDecl>(*I)->getParent());
-    LValue LV = EmitLValueForField(MakeAddrLValue(BaseValue, RecordTy),
-                                   cast<FieldDecl>(*I));
-    if (++I == IEnd) return LV;
-
-    assert(LV.isSimple());
-    BaseValue = LV.getAddress();
-    CVRQualifiers |= LV.getVRQualifiers();
-  }
-}
-
 LValue CodeGenFunction::EmitLValueForField(LValue base,
                                            const FieldDecl *field) {
   if (field->isBitField()) {
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 61f7362..287b6dd 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -1300,9 +1300,9 @@
   // implementation handles this case safely.  If there is a libc that does not
   // safely handle this, we can add a target hook.
 
-  // Get size and alignment info for this aggregate.
+  // Get data size and alignment info for this aggregate.
   std::pair<CharUnits, CharUnits> TypeInfo = 
-    getContext().getTypeInfoInChars(Ty);
+    getContext().getTypeInfoDataSizeInChars(Ty);
 
   if (alignment.isZero())
     alignment = TypeInfo.second;
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 79ebe51..31ea1b5 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -123,7 +123,14 @@
     
     return false;
   }
-  
+
+  // We can devirtualize calls on an object accessed by a class member access
+  // expression, since by C++11 [basic.life]p6 we know that it can't refer to
+  // a derived class object constructed in the same location.
+  if (const MemberExpr *ME = dyn_cast<MemberExpr>(Base))
+    if (const ValueDecl *VD = dyn_cast<ValueDecl>(ME->getMemberDecl()))
+      return VD->getType()->isRecordType();
+
   // We can always devirtualize calls on temporary object expressions.
   if (isa<CXXConstructExpr>(Base))
     return true;
@@ -1643,15 +1650,9 @@
   //   polymorphic class type, the result refers to a std::type_info object
   //   representing the type of the most derived object (that is, the dynamic
   //   type) to which the glvalue refers.
-  if (E->getExprOperand()->isGLValue()) {
-    if (const RecordType *RT =
-          E->getExprOperand()->getType()->getAs<RecordType>()) {
-      const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-      if (RD->isPolymorphic())
-        return EmitTypeidFromVTable(*this, E->getExprOperand(), 
-                                    StdTypeInfoPtrTy);
-    }
-  }
+  if (E->isPotentiallyEvaluated())
+    return EmitTypeidFromVTable(*this, E->getExprOperand(), 
+                                StdTypeInfoPtrTy);
 
   QualType OperandTy = E->getExprOperand()->getType();
   return Builder.CreateBitCast(CGM.GetAddrOfRTTIDescriptor(OperandTy),
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index d5f3ecc..4a8a079 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -613,7 +613,16 @@
     // which translates to objc_storeStrong.  This isn't required, but
     // it's slightly nicer.
     } else if (CGM.getLangOpts().ObjCAutoRefCount && !IsAtomic) {
-      Kind = Expression;
+      // Using standard expression emission for the setter is only
+      // acceptable if the ivar is __strong, which won't be true if
+      // the property is annotated with __attribute__((NSObject)).
+      // TODO: falling all the way back to objc_setProperty here is
+      // just laziness, though;  we could still use objc_storeStrong
+      // if we hacked it right.
+      if (ivarType.getObjCLifetime() == Qualifiers::OCL_Strong)
+        Kind = Expression;
+      else
+        Kind = SetPropertyAndExpressionGet;
       return;
 
     // Otherwise, we need to at least use setProperty.  However, if
@@ -1696,9 +1705,13 @@
   // If the target runtime doesn't naturally support ARC, emit weak
   // references to the runtime support library.  We don't really
   // permit this to fail, but we need a particular relocation style.
-  if (!CGM.getLangOpts().ObjCRuntime.hasARC())
-    if (llvm::Function *f = dyn_cast<llvm::Function>(fn))
+  if (llvm::Function *f = dyn_cast<llvm::Function>(fn)) {
+    if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC())
       f->setLinkage(llvm::Function::ExternalWeakLinkage);
+    // set nonlazybind attribute for these APIs for performance.
+    if (fnName == "objc_retain" || fnName  == "objc_release")
+      f->addFnAttr(llvm::Attribute::NonLazyBind);
+  }
 
   return fn;
 }
@@ -2726,7 +2739,7 @@
 
   // Keep track of the current cleanup stack depth.
   RunCleanupsScope Scope(*this);
-  if (CGM.getLangOpts().ObjCRuntime.hasARC()) {
+  if (CGM.getLangOpts().ObjCRuntime.hasNativeARC()) {
     llvm::Value *token = EmitObjCAutoreleasePoolPush();
     EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token);
   } else {
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 9993f44..f1c5f19 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -653,8 +653,40 @@
     }
 };
 
-/// Class used when targeting the ObjFW runtime.
-class CGObjCObjFW: public CGObjCGCC {
+/// Support for the ObjFW runtime. Support here is due to
+/// Jonathan Schleifer <js@webkeks.org>, the ObjFW maintainer.
+class CGObjCObjFW: public CGObjCGNU {
+protected:
+  /// The GCC ABI message lookup function.  Returns an IMP pointing to the
+  /// method implementation for this message.
+  LazyRuntimeFunction MsgLookupFn;
+  /// The GCC ABI superclass message lookup function.  Takes a pointer to a
+  /// structure describing the receiver and the class, and a selector as
+  /// arguments.  Returns the IMP for the corresponding method.
+  LazyRuntimeFunction MsgLookupSuperFn;
+
+  virtual llvm::Value *LookupIMP(CodeGenFunction &CGF,
+                                 llvm::Value *&Receiver,
+                                 llvm::Value *cmd,
+                                 llvm::MDNode *node) {
+    CGBuilderTy &Builder = CGF.Builder;
+    llvm::Value *args[] = {
+            EnforceType(Builder, Receiver, IdTy),
+            EnforceType(Builder, cmd, SelectorTy) };
+    llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args);
+    imp->setMetadata(msgSendMDKind, node);
+    return imp.getInstruction();
+  }
+
+  virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
+                                      llvm::Value *ObjCSuper,
+                                      llvm::Value *cmd) {
+      CGBuilderTy &Builder = CGF.Builder;
+      llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper,
+          PtrToObjCSuperTy), cmd};
+      return Builder.CreateCall(MsgLookupSuperFn, lookupArgs);
+    }
+
   virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder,
                                      const std::string &Name, bool isWeak) {
     if (isWeak)
@@ -675,7 +707,13 @@
   }
 
 public:
-  CGObjCObjFW(CodeGenModule &Mod): CGObjCGCC(Mod) {}
+  CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {
+    // IMP objc_msg_lookup(id, SEL);
+    MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, NULL);
+    // IMP objc_msg_lookup_super(struct objc_super*, SEL);
+    MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
+                          PtrToObjCSuperTy, SelectorTy, NULL);
+  }
 };
 } // end anonymous namespace
 
@@ -2510,25 +2548,8 @@
     ExceptionAsObject = CGF.ObjCEHValueStack.back();
   }
   ExceptionAsObject = CGF.Builder.CreateBitCast(ExceptionAsObject, IdTy);
-
-  // Note: This may have to be an invoke, if we want to support constructs like:
-  // @try {
-  //  @throw(obj);
-  // }
-  // @catch(id) ...
-  //
-  // This is effectively turning @throw into an incredibly-expensive goto, but
-  // it may happen as a result of inlining followed by missed optimizations, or
-  // as a result of stupidity.
-  llvm::BasicBlock *UnwindBB = CGF.getInvokeDest();
-  if (!UnwindBB) {
-    CGF.Builder.CreateCall(ExceptionThrowFn, ExceptionAsObject);
-    CGF.Builder.CreateUnreachable();
-  } else {
-    CGF.Builder.CreateInvoke(ExceptionThrowFn, UnwindBB, UnwindBB,
-                             ExceptionAsObject);
-  }
-  // Clear the insertion point to indicate we are in unreachable code.
+  CGF.EmitCallOrInvoke(ExceptionThrowFn, ExceptionAsObject);
+  CGF.Builder.CreateUnreachable();
   CGF.Builder.ClearInsertionPoint();
 }
 
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 864b4eb..ef802a3 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -2515,7 +2515,7 @@
                                                    Values);
 
   std::string Name("\01L_OBJC_METACLASS_");
-  Name += ID->getNameAsCString();
+  Name += ID->getName();
 
   // Check for a forward reference.
   llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name);
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 33776b6..d78908d 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -1686,4 +1686,42 @@
   // MS-style inline assembly is not fully supported, so sema emits a warning.
   if (!CGM.getCodeGenOpts().EmitMicrosoftInlineAsm)
     return;
+
+  assert (S.isSimple() && "CodeGen can only handle simple MSAsmStmts.");
+
+  std::vector<llvm::Value*> Args;
+  std::vector<llvm::Type *> ArgTypes;
+  std::string Constraints;
+
+  // Clobbers
+  for (unsigned i = 0, e = S.getNumClobbers(); i != e; ++i) {
+    StringRef Clobber = S.getClobber(i);
+
+    if (Clobber != "memory" && Clobber != "cc")
+      Clobber = Target.getNormalizedGCCRegisterName(Clobber);
+
+    if (i != 0)
+      Constraints += ',';
+
+    Constraints += "~{";
+    Constraints += Clobber;
+    Constraints += '}';
+  }
+
+  // Add machine specific clobbers
+  std::string MachineClobbers = Target.getClobbers();
+  if (!MachineClobbers.empty()) {
+    if (!Constraints.empty())
+      Constraints += ',';
+    Constraints += MachineClobbers;
+  }
+
+  llvm::FunctionType *FTy =
+    llvm::FunctionType::get(VoidTy, ArgTypes, false);
+
+  llvm::InlineAsm *IA =
+    llvm::InlineAsm::get(FTy, *S.getAsmString(), Constraints, true);
+  llvm::CallInst *Result = Builder.CreateCall(IA, Args);
+  Result->addAttribute(~0, llvm::Attribute::NoUnwind);
+  Result->addAttribute(~0, llvm::Attribute::IANSDialect);
 }
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 3c0dd5d..cdaa26a 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -387,6 +387,9 @@
   if (!ResultType->isVoidType() && Slot.isNull())
     CGM.getCXXABI().EmitReturnFromThunk(*this, RV, ResultType);
 
+  // Disable the final ARC autorelease.
+  AutoreleaseResult = false;
+
   FinishFunction();
 
   // Set the right linkage.
diff --git a/lib/CodeGen/CGValue.h b/lib/CodeGen/CGValue.h
index a46f313..c2b8e4d 100644
--- a/lib/CodeGen/CGValue.h
+++ b/lib/CodeGen/CGValue.h
@@ -128,7 +128,7 @@
 
   // The alignment to use when accessing this lvalue.  (For vector elements,
   // this is the alignment of the whole vector.)
-  unsigned short Alignment;
+  int64_t Alignment;
 
   // objective-c's ivar
   bool Ivar:1;
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 6aa487d..76be85f 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -51,10 +51,13 @@
   )
 
 add_dependencies(clangCodeGen
+  ClangARMNeon
   ClangAttrClasses
   ClangAttrList
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticCommon
+  ClangDiagnosticFrontend
   ClangStmtNodes
   )
 
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 697571b..ed3e43b 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -2162,9 +2162,6 @@
 
   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
                               const ObjCIvarDecl *Ivar);
-  LValue EmitLValueForAnonRecordField(llvm::Value* Base,
-                                      const IndirectFieldDecl* Field,
-                                      unsigned CVRQualifiers);
   LValue EmitLValueForField(LValue Base, const FieldDecl* Field);
 
   /// EmitLValueForFieldInitialization - Like EmitLValueForField, except that
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index a666415..840a18e 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1682,6 +1682,18 @@
   if (NeedsGlobalCtor || NeedsGlobalDtor)
     EmitCXXGlobalVarDeclInitFunc(D, GV, NeedsGlobalCtor);
 
+  // If we are compiling with ASan, add metadata indicating dynamically
+  // initialized globals.
+  if (LangOpts.AddressSanitizer && NeedsGlobalCtor) {
+    llvm::Module &M = getModule();
+
+    llvm::NamedMDNode *DynamicInitializers =
+        M.getOrInsertNamedMetadata("llvm.asan.dynamically_initialized_globals");
+    llvm::Value *GlobalToAdd[] = { GV };
+    llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalToAdd);
+    DynamicInitializers->addOperand(ThisGlobal);
+  }
+
   // Emit global variable debug information.
   if (CGDebugInfo *DI = getModuleDebugInfo())
     if (getCodeGenOpts().DebugInfo >= CodeGenOptions::LimitedDebugInfo)
@@ -2636,7 +2648,7 @@
     const std::string &S = getModule().getModuleInlineAsm();
     if (S.empty())
       getModule().setModuleInlineAsm(AsmString);
-    else if (*--S.end() == '\n')
+    else if (S.end()[-1] == '\n')
       getModule().setModuleInlineAsm(S + AsmString.str());
     else
       getModule().setModuleInlineAsm(S + '\n' + AsmString.str());
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 06e1a3e..9c23ed9 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -413,12 +413,18 @@
 
 /// X86_32ABIInfo - The X86-32 ABI information.
 class X86_32ABIInfo : public ABIInfo {
+  enum Class {
+    Integer,
+    Float
+  };
+
   static const unsigned MinABIStackAlignInBytes = 4;
 
   bool IsDarwinVectorABI;
   bool IsSmallStructInRegABI;
   bool IsMMXDisabled;
   bool IsWin32FloatStructABI;
+  unsigned DefaultNumRegisterParameters;
 
   static bool isRegisterSize(unsigned Size) {
     return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
@@ -434,8 +440,11 @@
   /// \brief Return the alignment to use for the given type on the stack.
   unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const;
 
+  Class classify(QualType Ty) const;
   ABIArgInfo classifyReturnType(QualType RetTy,
                                 unsigned callingConvention) const;
+  ABIArgInfo classifyArgumentTypeWithReg(QualType RetTy,
+                                         unsigned &FreeRegs) const;
   ABIArgInfo classifyArgumentType(QualType RetTy) const;
 
 public:
@@ -444,16 +453,18 @@
   virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
                                  CodeGenFunction &CGF) const;
 
-  X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m, bool w)
+  X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m, bool w,
+                unsigned r)
     : ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p),
-      IsMMXDisabled(m), IsWin32FloatStructABI(w) {}
+      IsMMXDisabled(m), IsWin32FloatStructABI(w),
+      DefaultNumRegisterParameters(r) {}
 };
 
 class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
 public:
   X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT,
-      bool d, bool p, bool m, bool w)
-    :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m, w)) {}
+      bool d, bool p, bool m, bool w, unsigned r)
+    :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m, w, r)) {}
 
   void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
                            CodeGen::CodeGenModule &CGM) const;
@@ -690,6 +701,57 @@
   return ABIArgInfo::getIndirect(StackAlign);
 }
 
+X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const {
+  const Type *T = isSingleElementStruct(Ty, getContext());
+  if (!T)
+    T = Ty.getTypePtr();
+
+  if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
+    BuiltinType::Kind K = BT->getKind();
+    if (K == BuiltinType::Float || K == BuiltinType::Double)
+      return Float;
+  }
+  return Integer;
+}
+
+ABIArgInfo
+X86_32ABIInfo::classifyArgumentTypeWithReg(QualType Ty,
+                                           unsigned &FreeRegs) const {
+  // Common case first.
+  if (FreeRegs == 0)
+    return classifyArgumentType(Ty);
+
+  Class C = classify(Ty);
+  if (C == Float)
+    return classifyArgumentType(Ty);
+
+  unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
+  if (SizeInRegs == 0)
+    return classifyArgumentType(Ty);
+
+  if (SizeInRegs > FreeRegs) {
+    FreeRegs = 0;
+    return classifyArgumentType(Ty);
+  }
+  assert(SizeInRegs >= 1 && SizeInRegs <= 3);
+  FreeRegs -= SizeInRegs;
+
+  // If it is a simple scalar, keep the type so that we produce a cleaner IR.
+  ABIArgInfo Foo = classifyArgumentType(Ty);
+  if (Foo.isDirect() && !Foo.getDirectOffset() && !Foo.getPaddingType())
+    return ABIArgInfo::getDirectInReg(Foo.getCoerceToType());
+  if (Foo.isExtend())
+    return ABIArgInfo::getExtendInReg(Foo.getCoerceToType());
+
+  llvm::LLVMContext &LLVMContext = getVMContext();
+  llvm::Type *Int32 = llvm::Type::getInt32Ty(LLVMContext);
+  SmallVector<llvm::Type*, 3> Elements;
+  for (unsigned I = 0; I < SizeInRegs; ++I)
+    Elements.push_back(Int32);
+  llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
+  return ABIArgInfo::getDirectInReg(Result);
+}
+
 ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const {
   // FIXME: Set alignment on indirect arguments.
   if (isAggregateTypeForABI(Ty)) {
@@ -754,9 +816,23 @@
 void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
   FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
                                           FI.getCallingConvention());
+
+  unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() :
+    DefaultNumRegisterParameters;
+
+  // If the return value is indirect, then the hidden argument is consuming one
+  // integer register.
+  if (FI.getReturnInfo().isIndirect() && FreeRegs) {
+    --FreeRegs;
+    ABIArgInfo &Old = FI.getReturnInfo();
+    Old = ABIArgInfo::getIndirectInReg(Old.getIndirectAlign(),
+                                       Old.getIndirectByVal(),
+                                       Old.getIndirectRealign());
+  }
+
   for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
        it != ie; ++it)
-    it->info = classifyArgumentType(it->type);
+    it->info = classifyArgumentTypeWithReg(it->type, FreeRegs);
 }
 
 llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
@@ -2681,21 +2757,21 @@
     }
   }
 
+  // Support byval for ARM.
+  if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64) ||
+      getContext().getTypeAlign(Ty) > 64) {
+    return ABIArgInfo::getIndirect(0, /*ByVal=*/true);
+  }
+
   // Otherwise, pass by coercing to a structure of the appropriate size.
-  //
-  // FIXME: This doesn't handle alignment > 64 bits.
   llvm::Type* ElemTy;
   unsigned SizeRegs;
-  if (getContext().getTypeSizeInChars(Ty) <= CharUnits::fromQuantity(64)) {
+  // FIXME: Try to match the types of the arguments more accurately where
+  // we can.
+  if (getContext().getTypeAlign(Ty) <= 32) {
     ElemTy = llvm::Type::getInt32Ty(getVMContext());
     SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;
-  } else if (getABIKind() == ARMABIInfo::APCS) {
-    // Initial ARM ByVal support is APCS-only.
-    return ABIArgInfo::getIndirect(0, /*ByVal=*/true);
   } else {
-    // FIXME: This is kind of nasty... but there isn't much choice
-    // because most of the ARM calling conventions don't yet support
-    // byval.
     ElemTy = llvm::Type::getInt64Ty(getVMContext());
     SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64;
   }
@@ -3735,8 +3811,8 @@
 
     if (Triple.isOSDarwin())
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(
-                 Types, true, true, DisableMMX, false));
+               new X86_32TargetCodeGenInfo(Types, true, true, DisableMMX, false,
+                                           CodeGenOpts.NumRegisterParameters));
 
     switch (Triple.getOS()) {
     case llvm::Triple::Cygwin:
@@ -3745,19 +3821,22 @@
     case llvm::Triple::DragonFly:
     case llvm::Triple::FreeBSD:
     case llvm::Triple::OpenBSD:
+    case llvm::Triple::Bitrig:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(
-                 Types, false, true, DisableMMX, false));
+               new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX,
+                                           false,
+                                           CodeGenOpts.NumRegisterParameters));
 
     case llvm::Triple::Win32:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(
-                 Types, false, true, DisableMMX, true));
+               new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX, true,
+                                           CodeGenOpts.NumRegisterParameters));
 
     default:
       return *(TheTargetCodeGenInfo =
-               new X86_32TargetCodeGenInfo(
-                 Types, false, false, DisableMMX, false));
+               new X86_32TargetCodeGenInfo(Types, false, false, DisableMMX,
+                                           false,
+                                           CodeGenOpts.NumRegisterParameters));
     }
   }
 
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt
index d4d8848..4ada7d9 100644
--- a/lib/Driver/CMakeLists.txt
+++ b/lib/Driver/CMakeLists.txt
@@ -20,9 +20,10 @@
 
 add_dependencies(clangDriver
   ClangAttrList
+  ClangCC1AsOptions
+  ClangDiagnosticCommon
   ClangDiagnosticDriver
   ClangDriverOptions
-  ClangCC1AsOptions
   )
 
 target_link_libraries(clangDriver
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 7f6fcb1..240d66f 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -504,16 +504,34 @@
         // Strip away options not necessary to reproduce the crash.
         // FIXME: This doesn't work with quotes (e.g., -D "foo bar").
         SmallVector<std::string, 16> Flag;
+        Flag.push_back("-D ");
         Flag.push_back("-F");
         Flag.push_back("-I ");
+        Flag.push_back("-M ");
+        Flag.push_back("-MD ");
+        Flag.push_back("-MF ");
+        Flag.push_back("-MG ");
+        Flag.push_back("-MM ");
+        Flag.push_back("-MMD ");
+        Flag.push_back("-MP ");
+        Flag.push_back("-MQ ");
+        Flag.push_back("-MT ");
         Flag.push_back("-o ");
         Flag.push_back("-coverage-file ");
         Flag.push_back("-dependency-file ");
         Flag.push_back("-fdebug-compilation-dir ");
         Flag.push_back("-fmodule-cache-path ");
+        Flag.push_back("-idirafter ");
         Flag.push_back("-include ");
         Flag.push_back("-include-pch ");
+        Flag.push_back("-internal-isystem ");
+        Flag.push_back("-internal-externc-isystem ");
+        Flag.push_back("-iprefix ");
+        Flag.push_back("-iwithprefix ");
+        Flag.push_back("-iwithprefixbefore ");
         Flag.push_back("-isysroot ");
+        Flag.push_back("-isystem ");
+        Flag.push_back("-iquote ");
         Flag.push_back("-resource-dir ");
         Flag.push_back("-serialize-diagnostic-file ");
         for (unsigned i = 0, e = Flag.size(); i < e; ++i) {
@@ -524,7 +542,14 @@
 
             E = Cmd.find(" ", I + Flag[i].length());
             if (E == std::string::npos) break;
-            Cmd.erase(I, E - I + 1);
+            // The -D option is not removed.  Instead, the argument is quoted.
+            if (Flag[i] != "-D ") {
+              Cmd.erase(I, E - I + 1);
+            } else {
+              Cmd.insert(I+3, "\"");
+              Cmd.insert(++E, "\"");
+              I = E;
+            }
           } while(1);
         }
         // Append the new filename with correct preprocessed suffix.
@@ -956,7 +981,7 @@
        it != ie; ++it) {
     Arg *A = *it;
 
-    if (isa<InputOption>(A->getOption())) {
+    if (A->getOption().getKind() == Option::InputClass) {
       const char *Value = A->getValue(Args);
       types::ID Ty = types::TY_INVALID;
 
@@ -1106,18 +1131,27 @@
       if (Args.hasArg(options::OPT_Qunused_arguments))
         continue;
 
+      // Special case when final phase determined by binary name, rather than
+      // by a command-line argument with a corresponding Arg.
+      if (CCCIsCPP)
+        Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
+          << InputArg->getAsString(Args)
+          << getPhaseName(InitialPhase);
       // Special case '-E' warning on a previously preprocessed file to make
       // more sense.
-      if (InitialPhase == phases::Compile && FinalPhase == phases::Preprocess &&
-          getPreprocessedType(InputType) == types::TY_INVALID)
+      else if (InitialPhase == phases::Compile &&
+               FinalPhase == phases::Preprocess &&
+               getPreprocessedType(InputType) == types::TY_INVALID)
         Diag(clang::diag::warn_drv_preprocessed_input_file_unused)
           << InputArg->getAsString(Args)
-          << FinalPhaseArg->getOption().getName();
+          << !!FinalPhaseArg
+          << FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "";
       else
         Diag(clang::diag::warn_drv_input_file_unused)
           << InputArg->getAsString(Args)
           << getPhaseName(InitialPhase)
-          << FinalPhaseArg->getOption().getName();
+          << !!FinalPhaseArg
+          << FinalPhaseArg ? FinalPhaseArg->getOption().getName() : "";
       continue;
     }
 
@@ -1185,8 +1219,14 @@
     }
     return new PreprocessJobAction(Input, OutputTy);
   }
-  case phases::Precompile:
-    return new PrecompileJobAction(Input, types::TY_PCH);
+  case phases::Precompile: {
+    types::ID OutputTy = types::TY_PCH;
+    if (Args.hasArg(options::OPT_fsyntax_only)) {
+      // Syntax checks should not emit a PCH file
+      OutputTy = types::TY_Nothing;
+    }
+    return new PrecompileJobAction(Input, OutputTy);
+  }
   case phases::Compile: {
     if (Args.hasArg(options::OPT_fsyntax_only)) {
       return new CompileJobAction(Input, types::TY_Nothing);
@@ -1297,7 +1337,7 @@
       // Suppress the warning automatically if this is just a flag, and it is an
       // instance of an argument we already claimed.
       const Option &Opt = A->getOption();
-      if (isa<FlagOption>(Opt)) {
+      if (Opt.getKind() == Option::FlagClass) {
         bool DuplicateClaimed = false;
 
         for (arg_iterator it = C.getArgs().filtered_begin(&Opt),
@@ -1647,7 +1687,8 @@
   // FIXME: Grumble, makeUnique sometimes leaves the file around!?  PR3837.
   P.eraseFromDisk(false, 0);
 
-  P.appendSuffix(Suffix);
+  if (Suffix)
+    P.appendSuffix(Suffix);
   return P.str();
 }
 
@@ -1735,6 +1776,9 @@
     case llvm::Triple::OpenBSD:
       TC = new toolchains::OpenBSD(*this, Target, Args);
       break;
+    case llvm::Triple::Bitrig:
+      TC = new toolchains::Bitrig(*this, Target, Args);
+      break;
     case llvm::Triple::NetBSD:
       TC = new toolchains::NetBSD(*this, Target, Args);
       break;
diff --git a/lib/Driver/OptTable.cpp b/lib/Driver/OptTable.cpp
index a3e38b2..3ebc6d8 100644
--- a/lib/Driver/OptTable.cpp
+++ b/lib/Driver/OptTable.cpp
@@ -129,60 +129,16 @@
   delete[] Options;
 }
 
+bool OptTable::isOptionHelpHidden(OptSpecifier id) const {
+  return getInfo(id).Flags & options::HelpHidden;
+}
+
 Option *OptTable::CreateOption(unsigned id) const {
   const Info &info = getInfo(id);
-  const OptionGroup *Group =
-    cast_or_null<OptionGroup>(getOption(info.GroupID));
+  const Option *Group = getOption(info.GroupID);
   const Option *Alias = getOption(info.AliasID);
 
-  Option *Opt = 0;
-  switch (info.Kind) {
-  case Option::InputClass:
-    Opt = new InputOption(id); break;
-  case Option::UnknownClass:
-    Opt = new UnknownOption(id); break;
-  case Option::GroupClass:
-    Opt = new OptionGroup(id, info.Name, Group); break;
-  case Option::FlagClass:
-    Opt = new FlagOption(id, info.Name, Group, Alias); break;
-  case Option::JoinedClass:
-    Opt = new JoinedOption(id, info.Name, Group, Alias); break;
-  case Option::SeparateClass:
-    Opt = new SeparateOption(id, info.Name, Group, Alias); break;
-  case Option::CommaJoinedClass:
-    Opt = new CommaJoinedOption(id, info.Name, Group, Alias); break;
-  case Option::MultiArgClass:
-    Opt = new MultiArgOption(id, info.Name, Group, Alias, info.Param); break;
-  case Option::JoinedOrSeparateClass:
-    Opt = new JoinedOrSeparateOption(id, info.Name, Group, Alias); break;
-  case Option::JoinedAndSeparateClass:
-    Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
-  }
-
-  if (info.Flags & DriverOption)
-    Opt->setDriverOption(true);
-  if (info.Flags & LinkerInput)
-    Opt->setLinkerInput(true);
-  if (info.Flags & NoArgumentUnused)
-    Opt->setNoArgumentUnused(true);
-  if (info.Flags & 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->setRenderStyle(Option::RenderJoinedStyle);
-  }
-  if (info.Flags & RenderSeparate) {
-    assert((info.Kind == Option::JoinedOrSeparateClass ||
-            info.Kind == Option::JoinedClass) && "Invalid option.");
-    Opt->setRenderStyle(Option::RenderSeparateStyle);
-  }
-  if (info.Flags & Unsupported)
-    Opt->setUnsupported(true);
-  if (info.Flags & CC1Option)
-    Opt->setIsCC1Option(true);
+  Option *Opt = new Option(&info, id, Group, Alias);
 
   return Opt;
 }
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index 03360ea..57eaee2 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -17,42 +17,15 @@
 #include <algorithm>
 using namespace clang::driver;
 
-Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
-               const OptionGroup *_Group, const Option *_Alias)
-  : Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
-    Unsupported(false), LinkerInput(false), NoOptAsInput(false),
-    DriverOption(false), NoArgumentUnused(false), NoForward(false) {
+Option::Option(const OptTable::Info *info, OptSpecifier _ID,
+               const Option *_Group, const Option *_Alias)
+  : Info(info), ID(_ID.getID()), Group(_Group), Alias(_Alias) {
 
   // 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() {
@@ -60,7 +33,7 @@
 
 void Option::dump() const {
   llvm::errs() << "<";
-  switch (Kind) {
+  switch (getKind()) {
 #define P(N) case N: llvm::errs() << #N; break
     P(GroupClass);
     P(InputClass);
@@ -75,7 +48,7 @@
 #undef P
   }
 
-  llvm::errs() << " Name:\"" << Name << '"';
+  llvm::errs() << " Name:\"" << getName() << '"';
 
   if (Group) {
     llvm::errs() << " Group:";
@@ -87,8 +60,8 @@
     Alias->dump();
   }
 
-  if (const MultiArgOption *MOA = dyn_cast<MultiArgOption>(this))
-    llvm::errs() << " NumArgs:" << MOA->getNumArgs();
+  if (getKind() == MultiArgClass)
+    llvm::errs() << " NumArgs:" << getNumArgs();
 
   llvm::errs() << ">\n";
 }
@@ -107,174 +80,99 @@
   return false;
 }
 
-OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
-                         const OptionGroup *Group)
-  : Option(Option::GroupClass, ID, Name, Group, 0) {
-}
+Arg *Option::accept(const ArgList &Args, unsigned &Index) const {
+  switch (getKind()) {
+  case FlagClass:
+    if (getName().size() != strlen(Args.getArgString(Index)))
+      return 0;
 
-Arg *OptionGroup::accept(const ArgList &Args, unsigned &Index) const {
-  llvm_unreachable("accept() should never be called on an OptionGroup");
-}
-
-InputOption::InputOption(OptSpecifier ID)
-  : Option(Option::InputClass, ID, "<input>", 0, 0) {
-}
-
-Arg *InputOption::accept(const ArgList &Args, unsigned &Index) const {
-  llvm_unreachable("accept() should never be called on an InputOption");
-}
-
-UnknownOption::UnknownOption(OptSpecifier ID)
-  : Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
-}
-
-Arg *UnknownOption::accept(const ArgList &Args, unsigned &Index) const {
-  llvm_unreachable("accept() should never be called on an UnknownOption");
-}
-
-FlagOption::FlagOption(OptSpecifier ID, const char *Name,
-                       const OptionGroup *Group, const Option *Alias)
-  : Option(Option::FlagClass, ID, Name, Group, Alias) {
-}
-
-Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Matches iff this is an exact match.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index)))
-    return 0;
-
-  return new Arg(getUnaliasedOption(), Index++);
-}
-
-JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
-                           const OptionGroup *Group, const Option *Alias)
-  : Option(Option::JoinedClass, ID, Name, Group, Alias) {
-}
-
-Arg *JoinedOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Always matches.
-  const char *Value = Args.getArgString(Index) + getName().size();
-  return new Arg(getUnaliasedOption(), Index++, Value);
-}
-
-CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
-                                     const OptionGroup *Group,
-                                     const Option *Alias)
-  : Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
-}
-
-Arg *CommaJoinedOption::accept(const ArgList &Args,
-                               unsigned &Index) const {
-  // Always matches.
-  const char *Str = Args.getArgString(Index) + getName().size();
-  Arg *A = new Arg(getUnaliasedOption(), Index++);
-
-  // 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,
-                               const OptionGroup *Group, const Option *Alias)
-  : Option(Option::SeparateClass, ID, Name, Group, Alias) {
-}
-
-Arg *SeparateOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Matches iff this is an exact match.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index)))
-    return 0;
-
-  Index += 2;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
-
-  return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
-}
-
-MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
-                               const OptionGroup *Group, const Option *Alias,
-                               unsigned _NumArgs)
-  : Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
-  assert(NumArgs > 1  && "Invalid MultiArgOption!");
-}
-
-Arg *MultiArgOption::accept(const ArgList &Args, unsigned &Index) const {
-  // Matches iff this is an exact match.
-  // FIXME: Avoid strlen.
-  if (getName().size() != strlen(Args.getArgString(Index)))
-    return 0;
-
-  Index += 1 + NumArgs;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
-
-  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,
-                                               const OptionGroup *Group,
-                                               const Option *Alias)
-  : Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
-}
-
-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 (getName().size() != strlen(Args.getArgString(Index))) {
+    return new Arg(getUnaliasedOption(), Index++);
+  case JoinedClass: {
     const char *Value = Args.getArgString(Index) + getName().size();
-    return new Arg(this, Index++, Value);
+    return new Arg(getUnaliasedOption(), Index++, Value);
   }
+  case CommaJoinedClass: {
+    // Always matches.
+    const char *Str = Args.getArgString(Index) + getName().size();
+    Arg *A = new Arg(getUnaliasedOption(), Index++);
 
-  // Otherwise it must be separate.
-  Index += 2;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
+    // Parse out the comma separated values.
+    const char *Prev = Str;
+    for (;; ++Str) {
+      char c = *Str;
 
-  return new Arg(getUnaliasedOption(), Index - 2, Args.getArgString(Index - 1));
-}
+      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);
+        }
 
-JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
-                                                 const char *Name,
-                                                 const OptionGroup *Group,
-                                                 const Option *Alias)
-  : Option(Option::JoinedAndSeparateClass, ID, Name, Group, Alias) {
-}
+        if (!c)
+          break;
 
-Arg *JoinedAndSeparateOption::accept(const ArgList &Args,
-                                     unsigned &Index) const {
-  // Always matches.
+        Prev = Str + 1;
+      }
+    }
+    A->setOwnsValues(true);
 
-  Index += 2;
-  if (Index > Args.getNumInputArgStrings())
-    return 0;
+    return A;
+  }
+  case SeparateClass:
+    // Matches iff this is an exact match.
+    // FIXME: Avoid strlen.
+    if (getName().size() != strlen(Args.getArgString(Index)))
+      return 0;
 
-  return new Arg(getUnaliasedOption(), Index - 2,
-                 Args.getArgString(Index-2)+getName().size(),
-                 Args.getArgString(Index-1));
+    Index += 2;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    return new Arg(getUnaliasedOption(),
+                   Index - 2, Args.getArgString(Index - 1));
+  case MultiArgClass: {
+    // Matches iff this is an exact match.
+    // FIXME: Avoid strlen.
+    if (getName().size() != strlen(Args.getArgString(Index)))
+      return 0;
+
+    Index += 1 + getNumArgs();
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    Arg *A = new Arg(getUnaliasedOption(), Index - 1 - getNumArgs(),
+                      Args.getArgString(Index - getNumArgs()));
+    for (unsigned i = 1; i != getNumArgs(); ++i)
+      A->getValues().push_back(Args.getArgString(Index - getNumArgs() + i));
+    return A;
+  }
+  case JoinedOrSeparateClass: {
+    // If this is not an exact match, it is a joined arg.
+    // FIXME: Avoid strlen.
+    if (getName().size() != strlen(Args.getArgString(Index))) {
+      const char *Value = Args.getArgString(Index) + getName().size();
+      return new Arg(this, Index++, Value);
+    }
+
+    // Otherwise it must be separate.
+    Index += 2;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    return new Arg(getUnaliasedOption(),
+                   Index - 2, Args.getArgString(Index - 1));
+  }
+  case JoinedAndSeparateClass:
+    // Always matches.
+    Index += 2;
+    if (Index > Args.getNumInputArgStrings())
+      return 0;
+
+    return new Arg(getUnaliasedOption(), Index - 2,
+                   Args.getArgString(Index-2)+getName().size(),
+                   Args.getArgString(Index-1));
+  default:
+    llvm_unreachable("Invalid option kind!");
+  }
 }
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 4f3d33e..4625913 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -442,6 +442,20 @@
 void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
   const OptTable &Opts = getDriver().getOpts();
 
+  // Support allowing the SDKROOT environment variable used by xcrun and other
+  // Xcode tools to define the default sysroot, by making it the default for
+  // isysroot.
+  if (!Args.hasArg(options::OPT_isysroot)) {
+    if (char *env = ::getenv("SDKROOT")) {
+      // We only use this value as the default if it is an absolute path and
+      // exists.
+      if (llvm::sys::path::is_absolute(env) && llvm::sys::fs::exists(env)) {
+        Args.append(Args.MakeSeparateArg(
+                      0, Opts.getOption(options::OPT_isysroot), env));
+      }
+    }
+  }
+
   Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
   Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
   Arg *iOSSimVersion = Args.getLastArg(
@@ -937,8 +951,11 @@
   return !isTargetIPhoneOS();
 }
 
-bool Darwin::SupportsObjCARC() const {
-  return isTargetIPhoneOS() || !isMacosxVersionLT(10, 6);
+void Darwin::CheckObjCARC() const {
+  if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6))
+    return;
+  getDriver().Diag(diag::err_arc_unsupported_on_toolchain)
+    << 0; // "versions of Mac OS X prior to 10.6"
 }
 
 std::string
@@ -1103,6 +1120,9 @@
     "arm-linux-gnueabi",
     "arm-linux-androideabi"
   };
+  static const char *const ARMHFTriples[] = {
+    "arm-linux-gnueabihf",
+  };
 
   static const char *const X86_64LibDirs[] = { "/lib64", "/lib" };
   static const char *const X86_64Triples[] = {
@@ -1159,8 +1179,13 @@
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
     LibDirs.append(ARMLibDirs, ARMLibDirs + llvm::array_lengthof(ARMLibDirs));
-    TripleAliases.append(
-      ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      TripleAliases.append(
+        ARMHFTriples, ARMHFTriples + llvm::array_lengthof(ARMHFTriples));
+    } else {
+      TripleAliases.append(
+        ARMTriples, ARMTriples + llvm::array_lengthof(ARMTriples));
+    }
     break;
   case llvm::Triple::x86_64:
     LibDirs.append(
@@ -1559,6 +1584,67 @@
   return *T;
 }
 
+/// Bitrig - Bitrig tool chain which can call as(1) and ld(1) directly.
+
+Bitrig::Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
+  getFilePaths().push_back(getDriver().Dir + "/../lib");
+  getFilePaths().push_back("/usr/lib");
+}
+
+Tool &Bitrig::SelectTool(const Compilation &C, const JobAction &JA,
+                         const ActionList &Inputs) const {
+  Action::ActionClass Key;
+  if (getDriver().ShouldUseClangCompiler(C, JA, getTriple()))
+    Key = Action::AnalyzeJobClass;
+  else
+    Key = JA.getKind();
+
+  bool UseIntegratedAs = C.getArgs().hasFlag(options::OPT_integrated_as,
+                                             options::OPT_no_integrated_as,
+                                             IsIntegratedAssemblerDefault());
+
+  Tool *&T = Tools[Key];
+  if (!T) {
+    switch (Key) {
+    case Action::AssembleJobClass: {
+      if (UseIntegratedAs)
+        T = new tools::ClangAs(*this);
+      else
+        T = new tools::bitrig::Assemble(*this);
+      break;
+    }
+    case Action::LinkJobClass:
+      T = new tools::bitrig::Link(*this); break;
+    default:
+      T = &Generic_GCC::SelectTool(C, JA, Inputs);
+    }
+  }
+
+  return *T;
+}
+
+void Bitrig::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                          ArgStringList &CC1Args) const {
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  std::string Triple = getTriple().str();
+  if (Triple.substr(0, 5) == "amd64")
+    Triple.replace(0, 5, "x86_64");
+
+  addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2");
+  addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2/backward");
+  addSystemInclude(DriverArgs, CC1Args, "/usr/include/c++/4.6.2/" + Triple);
+
+}
+
+void Bitrig::AddCXXStdlibLibArgs(const ArgList &Args,
+                                 ArgStringList &CmdArgs) const {
+  CmdArgs.push_back("-lstdc++");
+}
+
 /// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
 
 FreeBSD::FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args)
@@ -1912,8 +1998,13 @@
     // regardless of what the actual target triple is.
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
-    if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
-      return "arm-linux-gnueabi";
+    if (TargetTriple.getEnvironment() == llvm::Triple::GNUEABIHF) {
+      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabihf"))
+        return "arm-linux-gnueabihf";
+    } else {
+      if (llvm::sys::fs::exists(SysRoot + "/lib/arm-linux-gnueabi"))
+        return "arm-linux-gnueabi";
+    }
     return TargetTriple.str();
   case llvm::Triple::x86:
     if (llvm::sys::fs::exists(SysRoot + "/lib/i386-linux-gnu"))
@@ -2161,6 +2252,9 @@
   const StringRef ARMMultiarchIncludeDirs[] = {
     "/usr/include/arm-linux-gnueabi"
   };
+  const StringRef ARMHFMultiarchIncludeDirs[] = {
+    "/usr/include/arm-linux-gnueabihf"
+  };
   const StringRef MIPSMultiarchIncludeDirs[] = {
     "/usr/include/mips-linux-gnu"
   };
@@ -2179,7 +2273,10 @@
   } else if (getTriple().getArch() == llvm::Triple::x86) {
     MultiarchIncludeDirs = X86MultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::arm) {
-    MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
+    if (getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+      MultiarchIncludeDirs = ARMHFMultiarchIncludeDirs;
+    else
+      MultiarchIncludeDirs = ARMMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::mips) {
     MultiarchIncludeDirs = MIPSMultiarchIncludeDirs;
   } else if (getTriple().getArch() == llvm::Triple::mipsel) {
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 7c163a0..752cdfd 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -354,7 +354,7 @@
 
   virtual bool SupportsObjCGC() const;
 
-  virtual bool SupportsObjCARC() const;
+  virtual void CheckObjCARC() const;
 
   virtual bool UseDwarfDebugFlags() const;
 
@@ -445,6 +445,26 @@
                            const ActionList &Inputs) const;
 };
 
+class LLVM_LIBRARY_VISIBILITY Bitrig : public Generic_ELF {
+public:
+  Bitrig(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
+
+  virtual bool IsMathErrnoDefault() const { return false; }
+  virtual bool IsObjCNonFragileABIDefault() const { return true; }
+  virtual bool IsObjCLegacyDispatchDefault() const { return false; }
+
+  virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+                           const ActionList &Inputs) const;
+
+  virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                            ArgStringList &CC1Args) const;
+  virtual void AddCXXStdlibLibArgs(const ArgList &Args,
+                                   ArgStringList &CmdArgs) const;
+  virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
+     return 1;
+  }
+};
+
 class LLVM_LIBRARY_VISIBILITY FreeBSD : public Generic_ELF {
 public:
   FreeBSD(const Driver &D, const llvm::Triple& Triple, const ArgList &Args);
@@ -538,6 +558,10 @@
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
 
+  virtual bool IsObjCDefaultSynthPropertiesDefault() const {
+    return true;
+  }
+
   virtual bool IsIntegratedAssemblerDefault() const;
   virtual bool IsUnwindTablesDefault() const;
   virtual const char *GetDefaultRelocationModel() const;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index df1d5bf..1142913 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -174,8 +174,10 @@
 
 /// \brief Determine whether we are linking the ObjC runtime.
 static bool isObjCRuntimeLinked(const ArgList &Args) {
-  if (isObjCAutoRefCount(Args))
+  if (isObjCAutoRefCount(Args)) {
+    Args.ClaimAllArgs(options::OPT_fobjc_link_runtime);
     return true;
+  }
   return Args.hasArg(options::OPT_fobjc_link_runtime);
 }
 
@@ -629,16 +631,11 @@
       break;
     }
 
-    case llvm::Triple::Linux: {
-      if (Triple.getEnvironment() == llvm::Triple::GNUEABI) {
-        FloatABI = "softfp";
-        break;
-      }
-    }
-    // fall through
-
     default:
       switch(Triple.getEnvironment()) {
+      case llvm::Triple::GNUEABIHF:
+        FloatABI = "hard";
+        break;
       case llvm::Triple::GNUEABI:
         FloatABI = "softfp";
         break;
@@ -685,6 +682,7 @@
     switch(Triple.getEnvironment()) {
     case llvm::Triple::ANDROIDEABI:
     case llvm::Triple::GNUEABI:
+    case llvm::Triple::GNUEABIHF:
       ABIName = "aapcs-linux";
       break;
     case llvm::Triple::EABI:
@@ -1101,6 +1099,11 @@
         CPUName = "x86-64";
       else if (getToolChain().getArch() == llvm::Triple::x86)
         CPUName = "i486";
+    } else if (getToolChain().getOS().startswith("bitrig"))  {
+      if (getToolChain().getArch() == llvm::Triple::x86_64)
+        CPUName = "x86-64";
+      else if (getToolChain().getArch() == llvm::Triple::x86)
+        CPUName = "i686";
     } else if (getToolChain().getOS().startswith("freebsd"))  {
       if (getToolChain().getArch() == llvm::Triple::x86_64)
         CPUName = "x86-64";
@@ -1537,7 +1540,9 @@
     // Use PCH if the user requested it.
     bool UsePCH = D.CCCUsePCH;
 
-    if (UsePCH)
+    if (JA.getType() == types::TY_Nothing)
+      CmdArgs.push_back("-fsyntax-only");
+    else if (UsePCH)
       CmdArgs.push_back("-emit-pch");
     else
       CmdArgs.push_back("-emit-pth");
@@ -2348,6 +2353,18 @@
   if (StackProtectorLevel) {
     CmdArgs.push_back("-stack-protector");
     CmdArgs.push_back(Args.MakeArgString(Twine(StackProtectorLevel)));
+
+    // --param ssp-buffer-size=
+    for (arg_iterator it = Args.filtered_begin(options::OPT__param),
+           ie = Args.filtered_end(); it != ie; ++it) {
+      StringRef Str((*it)->getValue(Args));
+      if (Str.startswith("ssp-buffer-size=")) {
+        CmdArgs.push_back("-stack-protector-buffer-size");
+        // FIXME: Verify the argument is a valid integer.
+        CmdArgs.push_back(Args.MakeArgString(Str.drop_front(16)));
+        (*it)->claim();
+      }
+    }
   }
 
   // Translate -mstackrealign
@@ -2536,8 +2553,7 @@
   // NOTE: This logic is duplicated in ToolChains.cpp.
   bool ARC = isObjCAutoRefCount(Args);
   if (ARC) {
-    if (!getToolChain().SupportsObjCARC())
-      D.Diag(diag::err_arc_unsupported);
+    getToolChain().CheckObjCARC();
 
     CmdArgs.push_back("-fobjc-arc");
 
@@ -4476,7 +4492,7 @@
       ObjCRuntime runtime =
         getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true);
       // We use arclite library for both ARC and subscripting support.
-      if ((!runtime.hasARC() && isObjCAutoRefCount(Args)) ||
+      if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) ||
           !runtime.hasSubscripting())
         getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs);
     }
@@ -4958,6 +4974,142 @@
   C.addCommand(new Command(JA, *this, Exec, CmdArgs));
 }
 
+void bitrig::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("as"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
+void bitrig::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 ((!Args.hasArg(options::OPT_nostdlib)) &&
+      (!Args.hasArg(options::OPT_shared))) {
+    CmdArgs.push_back("-e");
+    CmdArgs.push_back("__start");
+  }
+
+  if (Args.hasArg(options::OPT_static)) {
+    CmdArgs.push_back("-Bstatic");
+  } else {
+    if (Args.hasArg(options::OPT_rdynamic))
+      CmdArgs.push_back("-export-dynamic");
+    CmdArgs.push_back("--eh-frame-hdr");
+    CmdArgs.push_back("-Bdynamic");
+    if (Args.hasArg(options::OPT_shared)) {
+      CmdArgs.push_back("-shared");
+    } else {
+      CmdArgs.push_back("-dynamic-linker");
+      CmdArgs.push_back("/usr/libexec/ld.so");
+    }
+  }
+
+  if (Output.isFilename()) {
+    CmdArgs.push_back("-o");
+    CmdArgs.push_back(Output.getFilename());
+  } else {
+    assert(Output.isNothing() && "Invalid output.");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back(Args.MakeArgString(
+                                getToolChain().GetFilePath("gcrt0.o")));
+      else
+        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("crtbeginS.o")));
+    }
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+  Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs);
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    if (D.CCCIsCXX) {
+      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lm_p");
+      else
+        CmdArgs.push_back("-lm");
+    }
+
+    if (Args.hasArg(options::OPT_pthread))
+      CmdArgs.push_back("-lpthread");
+    if (!Args.hasArg(options::OPT_shared)) {
+      if (Args.hasArg(options::OPT_pg))
+        CmdArgs.push_back("-lc_p");
+      else
+        CmdArgs.push_back("-lc");
+    }
+
+    std::string myarch = "-lclang_rt.";
+    const llvm::Triple &T = getToolChain().getTriple();
+    llvm::Triple::ArchType Arch = T.getArch();
+    switch (Arch) {
+          case llvm::Triple::arm:
+            myarch += ("arm");
+            break;
+          case llvm::Triple::x86:
+            myarch += ("i386");
+            break;
+          case llvm::Triple::x86_64:
+            myarch += ("amd64");
+            break;
+          default:
+            assert(0 && "Unsupported architecture");
+     }
+     CmdArgs.push_back(Args.MakeArgString(myarch));
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtend.o")));
+    else
+      CmdArgs.push_back(Args.MakeArgString(
+                              getToolChain().GetFilePath("crtendS.o")));
+  }
+
+  const char *Exec =
+    Args.MakeArgString(getToolChain().GetProgramPath("ld"));
+  C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+}
+
 void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
                                      const InputInfo &Output,
                                      const InputInfoList &Inputs,
@@ -5003,8 +5155,14 @@
                                  const char *LinkingOutput) const {
   const Driver &D = getToolChain().getDriver();
   ArgStringList CmdArgs;
-  CmdArgs.push_back("--hash-style=both");
-  CmdArgs.push_back("--enable-new-dtags");
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
 
   if (!D.SysRoot.empty())
     CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
@@ -5021,6 +5179,14 @@
       CmdArgs.push_back("-dynamic-linker");
       CmdArgs.push_back("/libexec/ld-elf.so.1");
     }
+    if (getToolChain().getTriple().getOSMajorVersion() >= 9) {
+      llvm::Triple::ArchType Arch = getToolChain().getArch();
+      if (Arch == llvm::Triple::arm || Arch == llvm::Triple::sparc ||
+          Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64) {
+        CmdArgs.push_back("--hash-style=both");
+      }
+    }
+    CmdArgs.push_back("--enable-new-dtags");
   }
 
   // When building 32-bit code on FreeBSD/amd64, we have to explicitly
@@ -5432,7 +5598,7 @@
   Args.ClaimAllArgs(options::OPT_g_Group);
   // and "clang -emit-llvm foo.o -o foo"
   Args.ClaimAllArgs(options::OPT_emit_llvm);
-  // and for "clang -g foo.o -o foo". Other warning options are already
+  // and for "clang -w foo.o -o foo". Other warning options are already
   // handled somewhere else.
   Args.ClaimAllArgs(options::OPT_w);
 
@@ -5502,8 +5668,12 @@
     else if (ToolChain.getArch() == llvm::Triple::x86)
       CmdArgs.push_back("/lib/ld-linux.so.2");
     else if (ToolChain.getArch() == llvm::Triple::arm ||
-             ToolChain.getArch() == llvm::Triple::thumb)
-      CmdArgs.push_back("/lib/ld-linux.so.3");
+             ToolChain.getArch() == llvm::Triple::thumb) {
+      if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF)
+        CmdArgs.push_back("/lib/ld-linux-armhf.so.3");
+      else
+        CmdArgs.push_back("/lib/ld-linux.so.3");
+    }
     else if (ToolChain.getArch() == llvm::Triple::mips ||
              ToolChain.getArch() == llvm::Triple::mipsel)
       CmdArgs.push_back("/lib/ld.so.1");
@@ -5564,6 +5734,9 @@
     CmdArgs.push_back(Args.MakeArgString(Plugin));
   }
 
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
 
   if (D.CCCIsCXX &&
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index 0fc0690..999c57a 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -377,6 +377,36 @@
   };
 } // end namespace openbsd
 
+  /// bitrig -- Directly call GNU Binutils assembler and linker
+namespace bitrig {
+  class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
+  public:
+    Assemble(const ToolChain &TC) : Tool("bitrig::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("bitrig::Link", "linker", TC) {}
+
+    virtual bool hasIntegratedCPP() const { return false; }
+    virtual bool isLinkJob() const { return true; }
+
+    virtual void ConstructJob(Compilation &C, const JobAction &JA,
+                              const InputInfo &Output,
+                              const InputInfoList &Inputs,
+                              const ArgList &TCArgs,
+                              const char *LinkingOutput) const;
+  };
+} // end namespace bitrig
+
   /// freebsd -- Directly call GNU Binutils assembler and linker
 namespace freebsd {
   class LLVM_LIBRARY_VISIBILITY Assemble : public Tool  {
diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp
index 533e780..9d8fcfd 100644
--- a/lib/Driver/Types.cpp
+++ b/lib/Driver/Types.cpp
@@ -67,7 +67,8 @@
 bool types::canLipoType(ID Id) {
   return (Id == TY_Nothing ||
           Id == TY_Image ||
-          Id == TY_Object);
+          Id == TY_Object ||
+          Id == TY_LTO_BC);
 }
 
 bool types::isAcceptedByClang(ID Id) {
diff --git a/lib/Edit/CMakeLists.txt b/lib/Edit/CMakeLists.txt
index 251aa40..cce1c19 100644
--- a/lib/Edit/CMakeLists.txt
+++ b/lib/Edit/CMakeLists.txt
@@ -5,8 +5,13 @@
   )
 
 add_dependencies(clangEdit
+  ClangAttrClasses
+  ClangAttrList
+  ClangCommentNodes
+  ClangDeclNodes
   ClangDiagnosticCommon
-)
+  ClangStmtNodes
+  )
 
 target_link_libraries(clangEdit
   clangBasic
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 390ae09..4a8f88f 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -12,47 +12,117 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/ASTConsumers.h"
+#include "clang/Basic/FileManager.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
-#include "clang/Basic/FileManager.h"
 #include "clang/AST/AST.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/RecordLayout.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "llvm/Module.h"
-#include "llvm/Support/Timer.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Timer.h"
 using namespace clang;
 
 //===----------------------------------------------------------------------===//
 /// ASTPrinter - Pretty-printer and dumper of ASTs
 
 namespace {
-  class ASTPrinter : public ASTConsumer {
-    raw_ostream &Out;
-    bool Dump;
+  class ASTPrinter : public ASTConsumer,
+                     public RecursiveASTVisitor<ASTPrinter> {
+    typedef RecursiveASTVisitor<ASTPrinter> base;
 
   public:
-    ASTPrinter(raw_ostream* o = NULL, bool Dump = false)
-      : Out(o? *o : llvm::outs()), Dump(Dump) { }
+    ASTPrinter(raw_ostream *Out = NULL, bool Dump = false,
+               StringRef FilterString = "")
+        : Out(Out ? *Out : llvm::outs()), Dump(Dump),
+          FilterString(FilterString) {}
 
     virtual void HandleTranslationUnit(ASTContext &Context) {
-      PrintingPolicy Policy = Context.getPrintingPolicy();
-      Policy.Dump = Dump;
-      Context.getTranslationUnitDecl()->print(Out, Policy, /*Indentation=*/0,
-                                              /*PrintInstantiation=*/true);
+      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
+
+      if (FilterString.empty()) {
+        if (Dump)
+          D->dump(Out);
+        else
+          D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
+        return;
+      }
+
+      TraverseDecl(D);
     }
+
+    bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+    bool TraverseDecl(Decl *D) {
+      if (D == NULL)
+        return false;
+      if (filterMatches(D)) {
+        Out.changeColor(llvm::raw_ostream::BLUE) <<
+            (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n";
+        Out.resetColor();
+        if (Dump)
+          D->dump(Out);
+        else
+          D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
+        Out << "\n";
+        // Don't traverse child nodes to avoid output duplication.
+        return true;
+      }
+      return base::TraverseDecl(D);
+    }
+
+  private:
+    std::string getName(Decl *D) {
+      if (isa<NamedDecl>(D))
+        return cast<NamedDecl>(D)->getQualifiedNameAsString();
+      return "";
+    }
+    bool filterMatches(Decl *D) {
+      return getName(D).find(FilterString) != std::string::npos;
+    }
+
+    raw_ostream &Out;
+    bool Dump;
+    std::string FilterString;
+  };
+
+  class ASTDeclNodeLister : public ASTConsumer,
+                     public RecursiveASTVisitor<ASTDeclNodeLister> {
+  public:
+    ASTDeclNodeLister(raw_ostream *Out = NULL)
+        : Out(Out ? *Out : llvm::outs()) {}
+
+    virtual void HandleTranslationUnit(ASTContext &Context) {
+      TraverseDecl(Context.getTranslationUnitDecl());
+    }
+
+    bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+    virtual bool VisitNamedDecl(NamedDecl *D) {
+      Out << D->getQualifiedNameAsString() << "\n";
+      return true;
+    }
+
+  private:
+    raw_ostream &Out;
   };
 } // end anonymous namespace
 
-ASTConsumer *clang::CreateASTPrinter(raw_ostream* out) {
-  return new ASTPrinter(out);
+ASTConsumer *clang::CreateASTPrinter(raw_ostream *Out,
+                                     StringRef FilterString) {
+  return new ASTPrinter(Out, /*Dump=*/ false, FilterString);
 }
 
-ASTConsumer *clang::CreateASTDumper() {
-  return new ASTPrinter(0, true);
+ASTConsumer *clang::CreateASTDumper(StringRef FilterString) {
+  return new ASTPrinter(0, /*Dump=*/ true, FilterString);
+}
+
+ASTConsumer *clang::CreateASTDeclNodeLister() {
+  return new ASTDeclNodeLister(0);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index ea2f773..42a6772 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -271,43 +271,43 @@
   if (!ND)
     return 0;
   
-  unsigned Contexts = 0;
+  uint64_t 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))
-              | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1));
+      Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
+               |  (1LL << CodeCompletionContext::CCC_ObjCIvarList)
+               |  (1LL << CodeCompletionContext::CCC_ClassStructUnion)
+               |  (1LL << CodeCompletionContext::CCC_Statement)
+               |  (1LL << CodeCompletionContext::CCC_Type)
+               |  (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
 
     // In C++, types can appear in expressions contexts (for functional casts).
     if (LangOpts.CPlusPlus)
-      Contexts |= (1 << (CodeCompletionContext::CCC_Expression - 1));
+      Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
     
     // 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));
+      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
     
     // In Objective-C, you can only be a subclass of another Objective-C class
     if (isa<ObjCInterfaceDecl>(ND))
-      Contexts |= (1 << (CodeCompletionContext::CCC_ObjCInterfaceName - 1));
+      Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
 
     // Deal with tag names.
     if (isa<EnumDecl>(ND)) {
-      Contexts |= (1 << (CodeCompletionContext::CCC_EnumTag - 1));
+      Contexts |= (1LL << CodeCompletionContext::CCC_EnumTag);
       
       // 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));
+        Contexts |= (1LL << CodeCompletionContext::CCC_UnionTag);
       else
-        Contexts |= (1 << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
+        Contexts |= (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
       
       if (LangOpts.CPlusPlus)
         IsNestedNameSpecifier = true;
@@ -315,16 +315,16 @@
       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_ParenthesizedExpression - 1))
-             | (1 << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1));
+    Contexts = (1LL << CodeCompletionContext::CCC_Statement)
+             | (1LL << CodeCompletionContext::CCC_Expression)
+             | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
+             | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
   } else if (isa<ObjCProtocolDecl>(ND)) {
-    Contexts = (1 << (CodeCompletionContext::CCC_ObjCProtocolName - 1));
+    Contexts = (1LL << CodeCompletionContext::CCC_ObjCProtocolName);
   } else if (isa<ObjCCategoryDecl>(ND)) {
-    Contexts = (1 << (CodeCompletionContext::CCC_ObjCCategoryName - 1));
+    Contexts = (1LL << CodeCompletionContext::CCC_ObjCCategoryName);
   } else if (isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) {
-    Contexts = (1 << (CodeCompletionContext::CCC_Namespace - 1));
+    Contexts = (1LL << CodeCompletionContext::CCC_Namespace);
    
     // Part of the nested-name-specifier.
     IsNestedNameSpecifier = true;
@@ -399,23 +399,23 @@
       if (TheSema->Context.getLangOpts().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))
-          | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1));
+        uint64_t NNSContexts
+          = (1LL << CodeCompletionContext::CCC_TopLevel)
+          | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
+          | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
+          | (1LL << CodeCompletionContext::CCC_Statement)
+          | (1LL << CodeCompletionContext::CCC_Expression)
+          | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
+          | (1LL << CodeCompletionContext::CCC_EnumTag)
+          | (1LL << CodeCompletionContext::CCC_UnionTag)
+          | (1LL << CodeCompletionContext::CCC_ClassOrStructTag)
+          | (1LL << CodeCompletionContext::CCC_Type)
+          | (1LL << CodeCompletionContext::CCC_PotentiallyQualifiedName)
+          | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression);
 
         if (isa<NamespaceDecl>(Results[I].Declaration) ||
             isa<NamespaceAliasDecl>(Results[I].Declaration))
-          NNSContexts |= (1 << (CodeCompletionContext::CCC_Namespace - 1));
+          NNSContexts |= (1LL << CodeCompletionContext::CCC_Namespace);
 
         if (unsigned RemainingContexts 
                                 = NNSContexts & ~CachedResult.ShowInContexts) {
@@ -452,18 +452,18 @@
                                                 getCodeCompletionTUInfo(),
                                           IncludeBriefCommentsInCodeCompletion);
       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))
-        | (1 << (CodeCompletionContext::CCC_ParenthesizedExpression - 1))
-        | (1 << (CodeCompletionContext::CCC_OtherWithMacros - 1));
+        = (1LL << CodeCompletionContext::CCC_TopLevel)
+        | (1LL << CodeCompletionContext::CCC_ObjCInterface)
+        | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
+        | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
+        | (1LL << CodeCompletionContext::CCC_ClassStructUnion)
+        | (1LL << CodeCompletionContext::CCC_Statement)
+        | (1LL << CodeCompletionContext::CCC_Expression)
+        | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
+        | (1LL << CodeCompletionContext::CCC_MacroNameUse)
+        | (1LL << CodeCompletionContext::CCC_PreprocessorExpression)
+        | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
+        | (1LL << CodeCompletionContext::CCC_OtherWithMacros);
       
       CachedResult.Priority = Results[I].Priority;
       CachedResult.Kind = Results[I].CursorKind;
@@ -2061,7 +2061,7 @@
   /// results from an ASTUnit with the code-completion results provided to it,
   /// then passes the result on to 
   class AugmentedCodeCompleteConsumer : public CodeCompleteConsumer {
-    unsigned long long NormalContexts;
+    uint64_t NormalContexts;
     ASTUnit &AST;
     CodeCompleteConsumer &Next;
     
@@ -2074,24 +2074,24 @@
       // Compute the set of contexts in which we will look when we don't have
       // any information about the specific context.
       NormalContexts 
-        = (1LL << (CodeCompletionContext::CCC_TopLevel - 1))
-        | (1LL << (CodeCompletionContext::CCC_ObjCInterface - 1))
-        | (1LL << (CodeCompletionContext::CCC_ObjCImplementation - 1))
-        | (1LL << (CodeCompletionContext::CCC_ObjCIvarList - 1))
-        | (1LL << (CodeCompletionContext::CCC_Statement - 1))
-        | (1LL << (CodeCompletionContext::CCC_Expression - 1))
-        | (1LL << (CodeCompletionContext::CCC_ObjCMessageReceiver - 1))
-        | (1LL << (CodeCompletionContext::CCC_DotMemberAccess - 1))
-        | (1LL << (CodeCompletionContext::CCC_ArrowMemberAccess - 1))
-        | (1LL << (CodeCompletionContext::CCC_ObjCPropertyAccess - 1))
-        | (1LL << (CodeCompletionContext::CCC_ObjCProtocolName - 1))
-        | (1LL << (CodeCompletionContext::CCC_ParenthesizedExpression - 1))
-        | (1LL << (CodeCompletionContext::CCC_Recovery - 1));
+        = (1LL << CodeCompletionContext::CCC_TopLevel)
+        | (1LL << CodeCompletionContext::CCC_ObjCInterface)
+        | (1LL << CodeCompletionContext::CCC_ObjCImplementation)
+        | (1LL << CodeCompletionContext::CCC_ObjCIvarList)
+        | (1LL << CodeCompletionContext::CCC_Statement)
+        | (1LL << CodeCompletionContext::CCC_Expression)
+        | (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver)
+        | (1LL << CodeCompletionContext::CCC_DotMemberAccess)
+        | (1LL << CodeCompletionContext::CCC_ArrowMemberAccess)
+        | (1LL << CodeCompletionContext::CCC_ObjCPropertyAccess)
+        | (1LL << CodeCompletionContext::CCC_ObjCProtocolName)
+        | (1LL << CodeCompletionContext::CCC_ParenthesizedExpression)
+        | (1LL << CodeCompletionContext::CCC_Recovery);
 
       if (AST.getASTContext().getLangOpts().CPlusPlus)
-        NormalContexts |= (1LL << (CodeCompletionContext::CCC_EnumTag - 1))
-                   | (1LL << (CodeCompletionContext::CCC_UnionTag - 1))
-                   | (1LL << (CodeCompletionContext::CCC_ClassOrStructTag - 1));
+        NormalContexts |= (1LL << CodeCompletionContext::CCC_EnumTag)
+                       |  (1LL << CodeCompletionContext::CCC_UnionTag)
+                       |  (1LL << CodeCompletionContext::CCC_ClassOrStructTag);
     }
     
     virtual void ProcessCodeCompleteResults(Sema &S, 
@@ -2206,9 +2206,9 @@
                                             unsigned NumResults) { 
   // Merge the results we were given with the results we cached.
   bool AddedResult = false;
-  unsigned InContexts  
-    = (Context.getKind() == CodeCompletionContext::CCC_Recovery? NormalContexts
-                                        : (1ULL << (Context.getKind() - 1)));
+  uint64_t InContexts =
+      Context.getKind() == CodeCompletionContext::CCC_Recovery
+        ? NormalContexts : (1LL << Context.getKind());
   // Contains the set of names that are hidden by "local" completion results.
   llvm::StringSet<llvm::BumpPtrAllocator> HiddenNames;
   typedef CodeCompletionResult Result;
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 345dda0..0566d54 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -33,12 +33,16 @@
 add_dependencies(clangFrontend
   ClangAttrClasses
   ClangAttrList
+  ClangAttrParsedAttrList
+  ClangCommentNodes
+  ClangDeclNodes
+  ClangDiagnosticAST
+  ClangDiagnosticCommon
+  ClangDiagnosticDriver
   ClangDiagnosticFrontend
   ClangDiagnosticLex
   ClangDiagnosticSema
   ClangDriverOptions
-  ClangCommentNodes
-  ClangDeclNodes
   ClangStmtNodes
   )
 
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 58a6b8d..3e66613 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -447,7 +447,7 @@
 
 void PTHWriter::GeneratePTH(const std::string &MainFile) {
   // Generate the prologue.
-  Out << "cfe-pth";
+  Out << "cfe-pth" << '\0';
   Emit32(PTHManager::Version);
 
   // Leave 4 words for the prologue.
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 5fa01d3..95f9c38 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -147,7 +147,7 @@
                   getAnalysisPurgeModeName(Opts.AnalysisPurgeOpt));
   if (!Opts.AnalyzeSpecificFunction.empty())
     Res.push_back("-analyze-function", Opts.AnalyzeSpecificFunction);
-  if (Opts.IPAMode != Inlining)
+  if (Opts.IPAMode != BasicInlining)
     Res.push_back("-analyzer-ipa", getAnalysisIPAModeName(Opts.IPAMode));
   if (Opts.InliningMode != NoRedundancy)
     Res.push_back("-analyzer-inlining-mode",
@@ -434,6 +434,7 @@
   case frontend::PluginAction:
     llvm_unreachable("Invalid kind!");
 
+  case frontend::ASTDeclList:            return "-ast-list";
   case frontend::ASTDump:                return "-ast-dump";
   case frontend::ASTDumpXML:             return "-ast-dump-xml";
   case frontend::ASTPrint:               return "-ast-print";
@@ -558,6 +559,8 @@
     for(unsigned i = 0, e = Opts.PluginArgs.size(); i != e; ++i)
       Res.push_back("-plugin-arg-" + Opts.ActionName, Opts.PluginArgs[i]);
   }
+  if (!Opts.ASTDumpFilter.empty())
+    Res.push_back("-ast-dump-filter", Opts.ASTDumpFilter);
   for (unsigned i = 0, e = Opts.Plugins.size(); i != e; ++i)
     Res.push_back("-load", Opts.Plugins[i]);
   for (unsigned i = 0, e = Opts.AddPluginActions.size(); i != e; ++i) {
@@ -809,7 +812,7 @@
   Res.push_back("-fobjc-runtime=" + Opts.ObjCRuntime.getAsString());
   if (Opts.ObjCAutoRefCount)
     Res.push_back("-fobjc-arc");
-  if (Opts.ObjCRuntimeHasWeak)
+  if (Opts.ObjCARCWeak)
     Res.push_back("-fobjc-runtime-has-weak");
   if (!Opts.ObjCInferRelatedResultType)
     Res.push_back("-fno-objc-infer-related-result-type");
@@ -1124,7 +1127,6 @@
   Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
   Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
   Opts.CFGAddImplicitDtors = Args.hasArg(OPT_analysis_CFGAddImplicitDtors);
-  Opts.CFGAddInitializers = Args.hasArg(OPT_analysis_CFGAddInitializers);
   Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
   Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
   Opts.MaxLoop = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
@@ -1265,6 +1267,8 @@
   Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file);
   Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
   Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
+  Opts.SSPBufferSize =
+    Args.getLastArgIntValue(OPT_stack_protector_buffer_size, 8, Diags);
   Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
   if (Arg *A = Args.getLastArg(OPT_mstack_alignment)) {
     StringRef Val = A->getValue(Args);
@@ -1436,6 +1440,8 @@
     switch (A->getOption().getID()) {
     default:
       llvm_unreachable("Invalid option in group!");
+    case OPT_ast_list:
+      Opts.ProgramAction = frontend::ASTDeclList; break;
     case OPT_ast_dump:
       Opts.ProgramAction = frontend::ASTDump; break;
     case OPT_ast_dump_xml:
@@ -1542,6 +1548,7 @@
   Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
   Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
   Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
+  Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter);
 
   Opts.CodeCompleteOpts.IncludeMacros
     = Args.hasArg(OPT_code_completion_macros);
@@ -1936,13 +1943,15 @@
       Opts.setGC(LangOptions::HybridGC);
     else if (Args.hasArg(OPT_fobjc_arc)) {
       Opts.ObjCAutoRefCount = 1;
-      if (!Opts.ObjCRuntime.isNonFragile())
-        Diags.Report(diag::err_arc_nonfragile_abi);
-    }
+      if (!Opts.ObjCRuntime.allowsARC())
+        Diags.Report(diag::err_arc_unsupported_on_runtime);
 
-    Opts.ObjCRuntimeHasWeak = Opts.ObjCRuntime.hasWeak();
-    if (Args.hasArg(OPT_fobjc_runtime_has_weak))
-      Opts.ObjCRuntimeHasWeak = 1;
+      // Only set ObjCARCWeak if ARC is enabled.
+      if (Args.hasArg(OPT_fobjc_runtime_has_weak))
+        Opts.ObjCARCWeak = 1;
+      else
+        Opts.ObjCARCWeak = Opts.ObjCRuntime.allowsWeak();
+    }
 
     if (Args.hasArg(OPT_fno_objc_infer_related_result_type))
       Opts.ObjCInferRelatedResultType = 0;
@@ -2091,9 +2100,10 @@
                                  Opts.Deprecated);
 
   // FIXME: Eliminate this dependency.
-  unsigned Opt = getOptimizationLevel(Args, IK, Diags);
+  unsigned Opt = getOptimizationLevel(Args, IK, Diags),
+       OptSize = getOptimizationLevelSize(Args, IK, Diags);
   Opts.Optimize = Opt != 0;
-  Opts.OptimizeSize = getOptimizationLevelSize(Args, IK, Diags);
+  Opts.OptimizeSize = OptSize != 0;
 
   // This is the __NO_INLINE__ define, which just depends on things like the
   // optimization level and -fno-inline, not actually whether the backend has
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index fb53c71..a4321e7 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -162,6 +162,7 @@
   setCurrentInput(Input);
   setCompilerInstance(&CI);
 
+  bool HasBegunSourceFile = false;
   if (!BeginInvocation(CI))
     goto failure;
 
@@ -214,6 +215,7 @@
 
     // Inform the diagnostic client we are processing a source file.
     CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), 0);
+    HasBegunSourceFile = true;
 
     // Initialize the action.
     if (!BeginSourceFileAction(CI, Input.File))
@@ -228,6 +230,7 @@
   // Inform the diagnostic client we are processing a source file.
   CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
                                            &CI.getPreprocessor());
+  HasBegunSourceFile = true;
 
   // Initialize the action.
   if (!BeginSourceFileAction(CI, Input.File))
@@ -309,7 +312,8 @@
     CI.setFileManager(0);
   }
 
-  CI.getDiagnosticClient().EndSourceFile();
+  if (HasBegunSourceFile)
+    CI.getDiagnosticClient().EndSourceFile();
   setCurrentInput(FrontendInputFile());
   setCompilerInstance(0);
   return false;
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index b699ae8..24960cf 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -47,13 +47,18 @@
 ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
                                                StringRef InFile) {
   if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
-    return CreateASTPrinter(OS);
+    return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter);
   return 0;
 }
 
 ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
                                               StringRef InFile) {
-  return CreateASTDumper();
+  return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter);
+}
+
+ASTConsumer *ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  StringRef InFile) {
+  return CreateASTDeclNodeLister();
 }
 
 ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI,
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index e5a8ca4..8178f7a 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -217,6 +217,8 @@
     switch (os) {
     case llvm::Triple::FreeBSD:
     case llvm::Triple::NetBSD:
+    case llvm::Triple::OpenBSD:
+    case llvm::Triple::Bitrig:
       break;
     default:
       // FIXME: temporary hack: hard-coded paths.
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 3979731..edb0710 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -247,7 +247,7 @@
         << "};\n"
         << "\n";
       
-    if (LangOpts.ObjCRuntimeHasWeak) {
+    if (LangOpts.ObjCARCWeak) {
       Out << "template<typename _Tp>\n"
           << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n"
           << "  enum { __value = 0 };\n"
@@ -445,6 +445,26 @@
 
   // Initialize target-specific preprocessor defines.
 
+  // __BYTE_ORDER__ was added in GCC 4.6. It's analogous
+  // to the macro __BYTE_ORDER (no trailing underscores)
+  // from glibc's <endian.h> header.
+  // We don't support the PDP-11 as a target, but include
+  // the define so it can still be compared against.
+  Builder.defineMacro("__ORDER_LITTLE_ENDIAN__", "1234");
+  Builder.defineMacro("__ORDER_BIG_ENDIAN__",    "4321");
+  Builder.defineMacro("__ORDER_PDP_ENDIAN__",    "3412");
+  if (TI.isBigEndian())
+    Builder.defineMacro("__BYTE_ORDER__", "__ORDER_BIG_ENDIAN__");
+  else
+    Builder.defineMacro("__BYTE_ORDER__", "__ORDER_LITTLE_ENDIAN__");
+
+
+  if (TI.getPointerWidth(0) == 64 && TI.getLongWidth() == 64
+      && TI.getIntWidth() == 32) {
+    Builder.defineMacro("_LP64");
+    Builder.defineMacro("__LP64__");
+  }
+
   // Define type sizing macros based on the target properties.
   assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
   Builder.defineMacro("__CHAR_BIT__", "8");
diff --git a/lib/Frontend/LayoutOverrideSource.cpp b/lib/Frontend/LayoutOverrideSource.cpp
index eb7865e..e023250 100644
--- a/lib/Frontend/LayoutOverrideSource.cpp
+++ b/lib/Frontend/LayoutOverrideSource.cpp
@@ -9,6 +9,7 @@
 #include "clang/Frontend/LayoutOverrideSource.h"
 #include "clang/AST/Decl.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cctype>
 #include <fstream>
 #include <string>
 
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 7e0bc6b..5311ed5 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -26,6 +26,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/ErrorHandling.h"
+#include <cctype>
 #include <cstdio>
 using namespace clang;
 
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index a20f30d..5a40368 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -50,13 +50,10 @@
   
 class SDiagsRenderer : public DiagnosticNoteRenderer {
   SDiagsWriter &Writer;
-  RecordData &Record;
 public:
-  SDiagsRenderer(SDiagsWriter &Writer, RecordData &Record,
-                 const LangOptions &LangOpts,
+  SDiagsRenderer(SDiagsWriter &Writer, const LangOptions &LangOpts,
                  const DiagnosticOptions &DiagOpts)
-    : DiagnosticNoteRenderer(LangOpts, DiagOpts),
-      Writer(Writer), Record(Record){}
+    : DiagnosticNoteRenderer(LangOpts, DiagOpts), Writer(Writer) {}
 
   virtual ~SDiagsRenderer() {}
   
@@ -73,15 +70,16 @@
                                  DiagnosticsEngine::Level Level,
                                  ArrayRef<CharSourceRange> Ranges,
                                  const SourceManager &SM) {}
-  
-  void emitNote(SourceLocation Loc, StringRef Message, const SourceManager *SM);
-  
+
+  virtual void emitNote(SourceLocation Loc, StringRef Message,
+                        const SourceManager *SM);
+
   virtual void emitCodeContext(SourceLocation Loc,
                                DiagnosticsEngine::Level Level,
                                SmallVectorImpl<CharSourceRange>& Ranges,
                                ArrayRef<FixItHint> Hints,
                                const SourceManager &SM);
-  
+
   virtual void beginDiagnostic(DiagOrStoredDiag D,
                                DiagnosticsEngine::Level Level);
   virtual void endDiagnostic(DiagOrStoredDiag D,
@@ -91,13 +89,12 @@
 class SDiagsWriter : public DiagnosticConsumer {
   friend class SDiagsRenderer;
 public:  
-  explicit SDiagsWriter(llvm::raw_ostream *os, const DiagnosticOptions &diags) 
-    : LangOpts(0), DiagOpts(diags),
-      Stream(Buffer), OS(os), inNonNoteDiagnostic(false)
-  { 
+  explicit SDiagsWriter(llvm::raw_ostream *os, const DiagnosticOptions &diags)
+    : LangOpts(0), DiagOpts(diags), Stream(Buffer), OS(os),
+      EmittedAnyDiagBlocks(false) {
     EmitPreamble();
   }
-  
+
   ~SDiagsWriter() {}
   
   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
@@ -124,7 +121,26 @@
 
   /// \brief Emit the META data block.
   void EmitMetaBlock();
-  
+
+  /// \brief Start a DIAG block.
+  void EnterDiagBlock();
+
+  /// \brief End a DIAG block.
+  void ExitDiagBlock();
+
+  /// \brief Emit a DIAG record.
+  void EmitDiagnosticMessage(SourceLocation Loc,
+                             PresumedLoc PLoc,
+                             DiagnosticsEngine::Level Level,
+                             StringRef Message,
+                             const SourceManager *SM,
+                             DiagOrStoredDiag D);
+
+  /// \brief Emit FIXIT and SOURCE_RANGE records for a diagnostic.
+  void EmitCodeContext(SmallVectorImpl<CharSourceRange> &Ranges,
+                       ArrayRef<FixItHint> Hints,
+                       const SourceManager &SM);
+
   /// \brief Emit a record for a CharSourceRange.
   void EmitCharSourceRange(CharSourceRange R, const SourceManager &SM);
   
@@ -190,10 +206,11 @@
 
   /// \brief Map for uniquing strings.
   DiagFlagsTy DiagFlags;
-  
-  /// \brief Flag indicating whether or not we are in the process of
-  /// emitting a non-note diagnostic.
-  bool inNonNoteDiagnostic;
+
+  /// \brief Whether we have already started emission of any DIAG blocks. Once
+  /// this becomes \c true, we never close a DIAG block until we know that we're
+  /// starting another one or we're done.
+  bool EmittedAnyDiagBlocks;
 };
 } // end anonymous namespace
 
@@ -474,31 +491,69 @@
 
 void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                     const Diagnostic &Info) {
+  // Enter the block for a non-note diagnostic immediately, rather than waiting
+  // for beginDiagnostic, in case associated notes are emitted before we get
+  // there.
   if (DiagLevel != DiagnosticsEngine::Note) {
-    if (inNonNoteDiagnostic) {
-      // We have encountered a non-note diagnostic.  Finish up the previous
-      // diagnostic block before starting a new one.
-      Stream.ExitBlock();
-    }
-    inNonNoteDiagnostic = true;
+    if (EmittedAnyDiagBlocks)
+      ExitDiagBlock();
+
+    EnterDiagBlock();
+    EmittedAnyDiagBlocks = true;
   }
 
   // Compute the diagnostic text.
-  diagBuf.clear();   
+  diagBuf.clear();
   Info.FormatDiagnostic(diagBuf);
 
-  const SourceManager *
-    SM = Info.hasSourceManager() ? &Info.getSourceManager() : 0;
-  SDiagsRenderer Renderer(*this, Record, *LangOpts, DiagOpts);
+  if (Info.getLocation().isInvalid()) {
+    // Special-case diagnostics with no location. We may not have entered a
+    // source file in this case, so we can't use the normal DiagnosticsRenderer
+    // machinery.
+    EmitDiagnosticMessage(SourceLocation(), PresumedLoc(), DiagLevel,
+                          diagBuf, 0, &Info);
+    return;
+  }
+
+  assert(Info.hasSourceManager() && LangOpts &&
+         "Unexpected diagnostic with valid location outside of a source file");
+  SDiagsRenderer Renderer(*this, *LangOpts, DiagOpts);
   Renderer.emitDiagnostic(Info.getLocation(), DiagLevel,
                           diagBuf.str(),
                           Info.getRanges(),
                           llvm::makeArrayRef(Info.getFixItHints(),
                                              Info.getNumFixItHints()),
-                          SM,
+                          &Info.getSourceManager(),
                           &Info);
 }
 
+void SDiagsWriter::EmitDiagnosticMessage(SourceLocation Loc,
+                                         PresumedLoc PLoc,
+                                         DiagnosticsEngine::Level Level,
+                                         StringRef Message,
+                                         const SourceManager *SM,
+                                         DiagOrStoredDiag D) {
+  // Emit the RECORD_DIAG record.
+  Record.clear();
+  Record.push_back(RECORD_DIAG);
+  Record.push_back(Level);
+  AddLocToRecord(Loc, SM, PLoc, Record);
+
+  if (const Diagnostic *Info = D.dyn_cast<const Diagnostic*>()) {
+    // Emit the category string lazily and get the category ID.
+    unsigned DiagID = DiagnosticIDs::getCategoryNumberForDiag(Info->getID());
+    Record.push_back(getEmitCategory(DiagID));
+    // Emit the diagnostic flag string lazily and get the mapped ID.
+    Record.push_back(getEmitDiagnosticFlag(Level, Info->getID()));
+  } else {
+    Record.push_back(getEmitCategory());
+    Record.push_back(getEmitDiagnosticFlag(Level));
+  }
+
+  Record.push_back(Message.size());
+  Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG), Record, Message);
+}
+
 void
 SDiagsRenderer::emitDiagnosticMessage(SourceLocation Loc,
                                       PresumedLoc PLoc,
@@ -507,94 +562,80 @@
                                       ArrayRef<clang::CharSourceRange> Ranges,
                                       const SourceManager *SM,
                                       DiagOrStoredDiag D) {
-  // Emit the RECORD_DIAG record.
-  Writer.Record.clear();
-  Writer.Record.push_back(RECORD_DIAG);
-  Writer.Record.push_back(Level);
-  Writer.AddLocToRecord(Loc, SM, PLoc, Record);
+  Writer.EmitDiagnosticMessage(Loc, PLoc, Level, Message, SM, D);
+}
 
-  if (const Diagnostic *Info = D.dyn_cast<const Diagnostic*>()) {
-    // Emit the category string lazily and get the category ID.
-    unsigned DiagID = DiagnosticIDs::getCategoryNumberForDiag(Info->getID());
-    Writer.Record.push_back(Writer.getEmitCategory(DiagID));
-    // Emit the diagnostic flag string lazily and get the mapped ID.
-    Writer.Record.push_back(Writer.getEmitDiagnosticFlag(Level, Info->getID()));
-  }
-  else {
-    Writer.Record.push_back(Writer.getEmitCategory());
-    Writer.Record.push_back(Writer.getEmitDiagnosticFlag(Level));
-  }
+void SDiagsWriter::EnterDiagBlock() {
+  Stream.EnterSubblock(BLOCK_DIAG, 4);
+}
 
-  Writer.Record.push_back(Message.size());
-  Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_DIAG),
-                                   Writer.Record, Message);
+void SDiagsWriter::ExitDiagBlock() {
+  Stream.ExitBlock();
 }
 
 void SDiagsRenderer::beginDiagnostic(DiagOrStoredDiag D,
                                      DiagnosticsEngine::Level Level) {
-  Writer.Stream.EnterSubblock(BLOCK_DIAG, 4);  
+  if (Level == DiagnosticsEngine::Note)
+    Writer.EnterDiagBlock();
 }
 
 void SDiagsRenderer::endDiagnostic(DiagOrStoredDiag D,
                                    DiagnosticsEngine::Level Level) {
-  if (D && Level != DiagnosticsEngine::Note)
-    return;
-  Writer.Stream.ExitBlock();
+  // Only end note diagnostics here, because we can't be sure when we've seen
+  // the last note associated with a non-note diagnostic.
+  if (Level == DiagnosticsEngine::Note)
+    Writer.ExitDiagBlock();
+}
+
+void SDiagsWriter::EmitCodeContext(SmallVectorImpl<CharSourceRange> &Ranges,
+                                   ArrayRef<FixItHint> Hints,
+                                   const SourceManager &SM) {
+  // Emit Source Ranges.
+  for (ArrayRef<CharSourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
+       I != E; ++I)
+    if (I->isValid())
+      EmitCharSourceRange(*I, SM);
+
+  // Emit FixIts.
+  for (ArrayRef<FixItHint>::iterator I = Hints.begin(), E = Hints.end();
+       I != E; ++I) {
+    const FixItHint &Fix = *I;
+    if (Fix.isNull())
+      continue;
+    Record.clear();
+    Record.push_back(RECORD_FIXIT);
+    AddCharSourceRangeToRecord(Fix.RemoveRange, Record, SM);
+    Record.push_back(Fix.CodeToInsert.size());
+    Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_FIXIT), Record,
+                              Fix.CodeToInsert);
+  }
 }
 
 void SDiagsRenderer::emitCodeContext(SourceLocation Loc,
                                      DiagnosticsEngine::Level Level,
                                      SmallVectorImpl<CharSourceRange> &Ranges,
                                      ArrayRef<FixItHint> Hints,
-                                     const SourceManager &SM) {  
-  // Emit Source Ranges.
-  for (ArrayRef<CharSourceRange>::iterator it=Ranges.begin(), ei=Ranges.end();
-       it != ei; ++it) {
-    if (it->isValid())
-      Writer.EmitCharSourceRange(*it, SM);
-  }
-  
-  // Emit FixIts.
-  for (ArrayRef<FixItHint>::iterator it = Hints.begin(), et = Hints.end();
-       it != et; ++it) {
-    const FixItHint &fix = *it;
-    if (fix.isNull())
-      continue;
-    Writer.Record.clear();
-    Writer.Record.push_back(RECORD_FIXIT);
-    Writer.AddCharSourceRangeToRecord(fix.RemoveRange, Record, SM);
-    Writer.Record.push_back(fix.CodeToInsert.size());
-    Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_FIXIT), Record,
-                                     fix.CodeToInsert);    
-  }
+                                     const SourceManager &SM) {
+  Writer.EmitCodeContext(Ranges, Hints, SM);
 }
 
 void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message,
                               const SourceManager *SM) {
-  Writer.Stream.EnterSubblock(BLOCK_DIAG, 4);
-  RecordData Record;
-  Record.push_back(RECORD_DIAG);
-  Record.push_back(DiagnosticsEngine::Note);
-  Writer.AddLocToRecord(Loc, Record, SM);
-  Record.push_back(Writer.getEmitCategory());
-  Record.push_back(Writer.getEmitDiagnosticFlag(DiagnosticsEngine::Note));
-  Record.push_back(Message.size());
-  Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_DIAG),
-                                   Record, Message);
-  Writer.Stream.ExitBlock();
+  Writer.EnterDiagBlock();
+  PresumedLoc PLoc = SM ? SM->getPresumedLoc(Loc) : PresumedLoc();
+  Writer.EmitDiagnosticMessage(Loc, PLoc, DiagnosticsEngine::Note,
+                               Message, SM, DiagOrStoredDiag());
+  Writer.ExitDiagBlock();
 }
 
 void SDiagsWriter::finish() {
-  if (inNonNoteDiagnostic) {
-    // Finish off any diagnostics we were in the process of emitting.
-    Stream.ExitBlock();
-    inNonNoteDiagnostic = false;
-  }
+  // Finish off any diagnostic we were in the process of emitting.
+  if (EmittedAnyDiagBlocks)
+    ExitDiagBlock();
 
   // Write the generated bitstream to "Out".
   OS->write((char *)&Buffer.front(), Buffer.size());
   OS->flush();
-  
+
   OS.reset(0);
 }
-
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index 7c2b037..9bb3e1d 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -20,6 +20,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include <algorithm>
+#include <cctype>
 
 using namespace clang;
 
@@ -904,8 +905,6 @@
 
   unsigned LineNo = SM.getLineNumber(FID, FileOffset);
   unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
-  unsigned CaretEndColNo
-    = ColNo + Lexer::MeasureTokenLength(Loc, SM, LangOpts);
 
   // Rewind from the current position to the start of the line.
   const char *TokPtr = BufStart+FileOffset;
@@ -918,11 +917,6 @@
   while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')
     ++LineEnd;
 
-  // FIXME: This shouldn't be necessary, but the CaretEndColNo can extend past
-  // the source line length as currently being computed. See
-  // test/Misc/message-length.c.
-  CaretEndColNo = std::min(CaretEndColNo, unsigned(LineEnd - LineStart));
-
   // Copy the line of code into an std::string for ease of manipulation.
   std::string SourceLine(LineStart, LineEnd);
 
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index 8aa65f1..e0acd42 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -15,10 +15,12 @@
 #include "clang/Frontend/VerifyDiagnosticConsumer.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/TextDiagnosticBuffer.h"
+#include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cctype>
 
 using namespace clang;
 typedef VerifyDiagnosticConsumer::Directive Directive;
@@ -26,46 +28,117 @@
 typedef VerifyDiagnosticConsumer::ExpectedData ExpectedData;
 
 VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &_Diags)
-  : Diags(_Diags), PrimaryClient(Diags.getClient()),
-    OwnsPrimaryClient(Diags.ownsClient()),
-    Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0) 
+  : Diags(_Diags),
+    PrimaryClient(Diags.getClient()), OwnsPrimaryClient(Diags.ownsClient()),
+    Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0),
+    LangOpts(0), SrcManager(0), ActiveSourceFiles(0)
 {
   Diags.takeClient();
+  if (Diags.hasSourceManager())
+    setSourceManager(Diags.getSourceManager());
 }
 
 VerifyDiagnosticConsumer::~VerifyDiagnosticConsumer() {
+  assert(!ActiveSourceFiles && "Incomplete parsing of source files!");
+  assert(!CurrentPreprocessor && "CurrentPreprocessor should be invalid!");
+  SrcManager = 0;
   CheckDiagnostics();  
   Diags.takeClient();
   if (OwnsPrimaryClient)
     delete PrimaryClient;
 }
 
+#ifndef NDEBUG
+namespace {
+class VerifyFileTracker : public PPCallbacks {
+  VerifyDiagnosticConsumer &Verify;
+  SourceManager &SM;
+
+public:
+  VerifyFileTracker(VerifyDiagnosticConsumer &Verify, SourceManager &SM)
+    : Verify(Verify), SM(SM) { }
+
+  /// \brief Hook into the preprocessor and update the list of parsed
+  /// files when the preprocessor indicates a new file is entered.
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                           SrcMgr::CharacteristicKind FileType,
+                           FileID PrevFID) {
+    Verify.UpdateParsedFileStatus(SM, SM.getFileID(Loc),
+                                  VerifyDiagnosticConsumer::IsParsed);
+  }
+};
+} // End anonymous namespace.
+#endif
+
 // DiagnosticConsumer interface.
 
 void VerifyDiagnosticConsumer::BeginSourceFile(const LangOptions &LangOpts,
                                                const Preprocessor *PP) {
-  CurrentPreprocessor = PP;
-  if (PP) const_cast<Preprocessor*>(PP)->addCommentHandler(this);
+  // Attach comment handler on first invocation.
+  if (++ActiveSourceFiles == 1) {
+    if (PP) {
+      CurrentPreprocessor = PP;
+      this->LangOpts = &LangOpts;
+      setSourceManager(PP->getSourceManager());
+      const_cast<Preprocessor*>(PP)->addCommentHandler(this);
+#ifndef NDEBUG
+      // Debug build tracks parsed files.
+      VerifyFileTracker *V = new VerifyFileTracker(*this, *SrcManager);
+      const_cast<Preprocessor*>(PP)->addPPCallbacks(V);
+#endif
+    }
+  }
 
+  assert((!PP || CurrentPreprocessor == PP) && "Preprocessor changed!");
   PrimaryClient->BeginSourceFile(LangOpts, PP);
 }
 
 void VerifyDiagnosticConsumer::EndSourceFile() {
-  if (CurrentPreprocessor)
-    const_cast<Preprocessor*>(CurrentPreprocessor)->removeCommentHandler(this);
-  CheckDiagnostics();
-
+  assert(ActiveSourceFiles && "No active source files!");
   PrimaryClient->EndSourceFile();
 
-  CurrentPreprocessor = 0;
+  // Detach comment handler once last active source file completed.
+  if (--ActiveSourceFiles == 0) {
+    if (CurrentPreprocessor)
+      const_cast<Preprocessor*>(CurrentPreprocessor)->removeCommentHandler(this);
+
+    // Check diagnostics once last file completed.
+    CheckDiagnostics();
+    CurrentPreprocessor = 0;
+    LangOpts = 0;
+  }
 }
 
 void VerifyDiagnosticConsumer::HandleDiagnostic(
       DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) {
-  if (Info.hasSourceManager()) {
-    const SourceManager &SM = Info.getSourceManager();
-    FilesWithDiagnostics.insert(SM.getFileID(Info.getLocation()));
+  if (Info.hasSourceManager())
+    setSourceManager(Info.getSourceManager());
+
+#ifndef NDEBUG
+  // Debug build tracks unparsed files for possible
+  // unparsed expected-* directives.
+  if (SrcManager) {
+    SourceLocation Loc = Info.getLocation();
+    if (Loc.isValid()) {
+      ParsedStatus PS = IsUnparsed;
+
+      Loc = SrcManager->getExpansionLoc(Loc);
+      FileID FID = SrcManager->getFileID(Loc);
+
+      const FileEntry *FE = SrcManager->getFileEntryForID(FID);
+      if (FE && CurrentPreprocessor && SrcManager->isLoadedFileID(FID)) {
+        // If the file is a modules header file it shall not be parsed
+        // for expected-* directives.
+        HeaderSearch &HS = CurrentPreprocessor->getHeaderSearchInfo();
+        if (HS.findModuleForHeader(FE))
+          PS = IsUnparsedNoDirectives;
+      }
+
+      UpdateParsedFileStatus(*SrcManager, FID, PS);
+    }
   }
+#endif
+
   // Send the diagnostic to the buffer, we will check it once we reach the end
   // of the source file (or are destructed).
   Buffer->HandleDiagnostic(DiagLevel, Info);
@@ -192,7 +265,7 @@
 /// diagnostics. If so, then put them in the appropriate directive list.
 ///
 /// Returns true if any valid directives were found.
-static bool ParseDirective(StringRef S, ExpectedData &ED, SourceManager &SM,
+static bool ParseDirective(StringRef S, ExpectedData *ED, SourceManager &SM,
                            SourceLocation Pos, DiagnosticsEngine &Diags) {
   // A single comment may contain multiple directives.
   bool FoundDirective = false;
@@ -210,15 +283,20 @@
     // Next token: { error | warning | note }
     DirectiveList* DL = NULL;
     if (PH.Next("error"))
-      DL = &ED.Errors;
+      DL = ED ? &ED->Errors : NULL;
     else if (PH.Next("warning"))
-      DL = &ED.Warnings;
+      DL = ED ? &ED->Warnings : NULL;
     else if (PH.Next("note"))
-      DL = &ED.Notes;
+      DL = ED ? &ED->Notes : NULL;
     else
       continue;
     PH.Advance();
 
+    // If a directive has been found but we're not interested
+    // in storing the directive information, return now.
+    if (!DL)
+      return true;
+
     // Default directive kind.
     bool RegexKind = false;
     const char* KindStr = "string";
@@ -360,9 +438,7 @@
   // Fold any "\<EOL>" sequences
   size_t loc = C.find('\\');
   if (loc == StringRef::npos) {
-    if (ParseDirective(C, ED, SM, CommentBegin, PP.getDiagnostics()))
-      if (const FileEntry *E = SM.getFileEntryForID(SM.getFileID(CommentBegin)))
-        FilesWithDirectives.insert(E);
+    ParseDirective(C, &ED, SM, CommentBegin, PP.getDiagnostics());
     return false;
   }
 
@@ -392,24 +468,25 @@
   }
 
   if (!C2.empty())
-    if (ParseDirective(C2, ED, SM, CommentBegin, PP.getDiagnostics()))
-      if (const FileEntry *E = SM.getFileEntryForID(SM.getFileID(CommentBegin)))
-        FilesWithDirectives.insert(E);
+    ParseDirective(C2, &ED, SM, CommentBegin, PP.getDiagnostics());
   return false;
 }
 
-/// FindExpectedDiags - Lex the main source file to find all of the
-//   expected errors and warnings.
-static void FindExpectedDiags(const Preprocessor &PP, ExpectedData &ED,
-                              FileID FID) {
+#ifndef NDEBUG
+/// \brief Lex the specified source file to determine whether it contains
+/// any expected-* directives.  As a Lexer is used rather than a full-blown
+/// Preprocessor, directives inside skipped #if blocks will still be found.
+///
+/// \return true if any directives were found.
+static bool findDirectives(SourceManager &SM, FileID FID,
+                           const LangOptions &LangOpts) {
   // Create a raw lexer to pull all the comments out of FID.
   if (FID.isInvalid())
-    return;
+    return false;
 
-  SourceManager& SM = PP.getSourceManager();
   // Create a lexer to lex all the tokens of the main file in raw mode.
   const llvm::MemoryBuffer *FromFile = SM.getBuffer(FID);
-  Lexer RawLex(FID, FromFile, SM, PP.getLangOpts());
+  Lexer RawLex(FID, FromFile, SM, LangOpts);
 
   // Return comments as tokens, this is how we find expected diagnostics.
   RawLex.SetCommentRetentionState(true);
@@ -420,13 +497,17 @@
     RawLex.Lex(Tok);
     if (!Tok.is(tok::comment)) continue;
 
-    std::string Comment = PP.getSpelling(Tok);
+    std::string Comment = RawLex.getSpelling(Tok, SM, LangOpts);
     if (Comment.empty()) continue;
 
-    // Find all expected errors/warnings/notes.
-    ParseDirective(Comment, ED, SM, Tok.getLocation(), PP.getDiagnostics());
-  };
+    // Find first directive.
+    if (ParseDirective(Comment, 0, SM, Tok.getLocation(),
+                       SM.getDiagnostics()))
+      return true;
+  }
+  return false;
 }
+#endif // !NDEBUG
 
 /// \brief Takes a list of diagnostics that have been generated but not matched
 /// by an expected-* directive and produces a diagnostic to the user from this.
@@ -546,35 +627,87 @@
   return NumProblems;
 }
 
+void VerifyDiagnosticConsumer::UpdateParsedFileStatus(SourceManager &SM,
+                                                      FileID FID,
+                                                      ParsedStatus PS) {
+  // Check SourceManager hasn't changed.
+  setSourceManager(SM);
+
+#ifndef NDEBUG
+  if (FID.isInvalid())
+    return;
+
+  const FileEntry *FE = SM.getFileEntryForID(FID);
+
+  if (PS == IsParsed) {
+    // Move the FileID from the unparsed set to the parsed set.
+    UnparsedFiles.erase(FID);
+    ParsedFiles.insert(std::make_pair(FID, FE));
+  } else if (!ParsedFiles.count(FID) && !UnparsedFiles.count(FID)) {
+    // Add the FileID to the unparsed set if we haven't seen it before.
+
+    // Check for directives.
+    bool FoundDirectives;
+    if (PS == IsUnparsedNoDirectives)
+      FoundDirectives = false;
+    else
+      FoundDirectives = !LangOpts || findDirectives(SM, FID, *LangOpts);
+
+    // Add the FileID to the unparsed set.
+    UnparsedFiles.insert(std::make_pair(FID,
+                                      UnparsedFileStatus(FE, FoundDirectives)));
+  }
+#endif
+}
+
 void VerifyDiagnosticConsumer::CheckDiagnostics() {
   // Ensure any diagnostics go to the primary client.
   bool OwnsCurClient = Diags.ownsClient();
   DiagnosticConsumer *CurClient = Diags.takeClient();
   Diags.setClient(PrimaryClient, false);
 
-  // If we have a preprocessor, scan the source for expected diagnostic
-  // markers. If not then any diagnostics are unexpected.
-  if (CurrentPreprocessor) {
-    SourceManager &SM = CurrentPreprocessor->getSourceManager();
-    // Only check for expectations in other diagnostic locations not
-    // captured during normal parsing.
-    // FIXME: This check is currently necessary while synthesized files may
-    // not have their expected-* directives captured during parsing.  These
-    // cases should be fixed and the following loop replaced with one which
-    // checks only during a debug build and asserts on a mismatch.
-    for (FilesWithDiagnosticsSet::iterator I = FilesWithDiagnostics.begin(),
-                                         End = FilesWithDiagnostics.end();
-            I != End; ++I) {
-      const FileEntry *E = SM.getFileEntryForID(*I);
-      if (!E || !FilesWithDirectives.count(E)) {
-        if (E)
-          FilesWithDirectives.insert(E);
-        FindExpectedDiags(*CurrentPreprocessor, ED, *I);
+#ifndef NDEBUG
+  // In a debug build, scan through any files that may have been missed
+  // during parsing and issue a fatal error if directives are contained
+  // within these files.  If a fatal error occurs, this suggests that
+  // this file is being parsed separately from the main file, in which
+  // case consider moving the directives to the correct place, if this
+  // is applicable.
+  if (UnparsedFiles.size() > 0) {
+    // Generate a cache of parsed FileEntry pointers for alias lookups.
+    llvm::SmallPtrSet<const FileEntry *, 8> ParsedFileCache;
+    for (ParsedFilesMap::iterator I = ParsedFiles.begin(),
+                                End = ParsedFiles.end(); I != End; ++I) {
+      if (const FileEntry *FE = I->second)
+        ParsedFileCache.insert(FE);
+    }
+
+    // Iterate through list of unparsed files.
+    for (UnparsedFilesMap::iterator I = UnparsedFiles.begin(),
+                                  End = UnparsedFiles.end(); I != End; ++I) {
+      const UnparsedFileStatus &Status = I->second;
+      const FileEntry *FE = Status.getFile();
+
+      // Skip files that have been parsed via an alias.
+      if (FE && ParsedFileCache.count(FE))
+        continue;
+
+      // Report a fatal error if this file contained directives.
+      if (Status.foundDirectives()) {
+        llvm::report_fatal_error(Twine("-verify directives found after rather"
+                                       " than during normal parsing of ",
+                                 StringRef(FE ? FE->getName() : "(unknown)")));
       }
     }
 
+    // UnparsedFiles has been processed now, so clear it.
+    UnparsedFiles.clear();
+  }
+#endif // !NDEBUG
+
+  if (SrcManager) {
     // Check that the expected diagnostics occurred.
-    NumErrors += CheckResults(Diags, SM, *Buffer, ED);
+    NumErrors += CheckResults(Diags, *SrcManager, *Buffer, ED);
   } else {
     NumErrors += (PrintUnexpected(Diags, 0, Buffer->err_begin(),
                                   Buffer->err_end(), "error") +
diff --git a/lib/FrontendTool/CMakeLists.txt b/lib/FrontendTool/CMakeLists.txt
index 47cdf17..fe9d589 100644
--- a/lib/FrontendTool/CMakeLists.txt
+++ b/lib/FrontendTool/CMakeLists.txt
@@ -3,7 +3,9 @@
   )
 
 add_dependencies(clangFrontendTool
+  ClangDiagnosticCommon
   ClangDiagnosticFrontend
+  ClangDriverOptions
   )
 
 target_link_libraries(clangFrontendTool
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 2662844..bd50083 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -32,6 +32,7 @@
   using namespace clang::frontend;
 
   switch (CI.getFrontendOpts().ProgramAction) {
+  case ASTDeclList:            return new ASTDeclListAction();
   case ASTDump:                return new ASTDumpAction();
   case ASTDumpXML:             return new ASTDumpXMLAction();
   case ASTPrint:               return new ASTPrintAction();
diff --git a/lib/Lex/CMakeLists.txt b/lib/Lex/CMakeLists.txt
index 7399de1..241abbc 100644
--- a/lib/Lex/CMakeLists.txt
+++ b/lib/Lex/CMakeLists.txt
@@ -27,8 +27,9 @@
   )
 
 add_dependencies(clangLex
-  ClangDiagnosticLex
   ClangAttrSpellings
+  ClangDiagnosticCommon
+  ClangDiagnosticLex
   )
 
 target_link_libraries(clangLex
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index a75c45e..bb3a673 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -442,11 +442,19 @@
       // Leave CurDir unset.
       // This file is a system header or C++ unfriendly if the old file is.
       //
-      // Note that the temporary 'DirInfo' is required here, as either call to
-      // getFileInfo could resize the vector and we don't want to rely on order
-      // of evaluation.
-      unsigned DirInfo = getFileInfo(CurFileEnt).DirInfo;
-      getFileInfo(FE).DirInfo = DirInfo;
+      // Note that we only use one of FromHFI/ToHFI at once, due to potential
+      // reallocation of the underlying vector potentially making the first
+      // reference binding dangling.
+      HeaderFileInfo &FromHFI = getFileInfo(CurFileEnt);
+      unsigned DirInfo = FromHFI.DirInfo;
+      bool IndexHeaderMapHeader = FromHFI.IndexHeaderMapHeader;
+      StringRef Framework = FromHFI.Framework;
+
+      HeaderFileInfo &ToHFI = getFileInfo(FE);
+      ToHFI.DirInfo = DirInfo;
+      ToHFI.IndexHeaderMapHeader = IndexHeaderMapHeader;
+      ToHFI.Framework = Framework;
+
       if (SearchPath != NULL) {
         StringRef SearchPathRef(CurFileEnt->getDir()->getName());
         SearchPath->clear();
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 52a094a..5212dd8 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -544,7 +544,6 @@
     if (InPreprocessorDirective) {
       // If we've hit the end of the file, we're done.
       if (TheTok.getKind() == tok::eof) {
-        InPreprocessorDirective = false;
         break;
       }
       
@@ -1769,7 +1768,7 @@
     // Skip escaped characters.
     if (C == '\\') {
       // Skip the escaped character.
-      C = getAndAdvanceChar(CurPtr, Result);
+      getAndAdvanceChar(CurPtr, Result);
     } else if (C == '\n' || C == '\r' ||             // Newline.
                (C == 0 && (CurPtr-1 == BufferEnd ||  // End of file.
                            isCodeCompletionPoint(CurPtr-1)))) {
@@ -1817,7 +1816,7 @@
     if (C == '\\') {
       // Skip the escaped character.
       // FIXME: UCN's
-      C = getAndAdvanceChar(CurPtr, Result);
+      getAndAdvanceChar(CurPtr, Result);
     } else if (C == '\n' || C == '\r' ||             // Newline.
                (C == 0 && CurPtr-1 == BufferEnd)) {  // End of file.
       if (!isLexingRawMode() && !LangOpts.AsmPreprocessor)
@@ -1938,8 +1937,6 @@
         CurPtr = EscapePtr-2;
       else
         break; // This is a newline, we're done.
-
-      C = *CurPtr;
     }
 
     // Otherwise, this is a hard case.  Fall back on getAndAdvanceChar to
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index c9d400f..96d6b2c 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -619,6 +619,7 @@
            .Case("address_sanitizer", LangOpts.AddressSanitizer)
            .Case("attribute_analyzer_noreturn", true)
            .Case("attribute_availability", true)
+           .Case("attribute_availability_with_message", true)
            .Case("attribute_cf_returns_not_retained", true)
            .Case("attribute_cf_returns_retained", true)
            .Case("attribute_deprecated_with_message", true)
@@ -640,8 +641,7 @@
            // Objective-C features
            .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
            .Case("objc_arc", LangOpts.ObjCAutoRefCount)
-           .Case("objc_arc_weak", LangOpts.ObjCAutoRefCount && 
-                 LangOpts.ObjCRuntimeHasWeak)
+           .Case("objc_arc_weak", LangOpts.ObjCARCWeak)
            .Case("objc_default_synthesize_properties", LangOpts.ObjC2)
            .Case("objc_fixed_enum", LangOpts.ObjC2)
            .Case("objc_instancetype", LangOpts.ObjC2)
@@ -1053,7 +1053,7 @@
     if (Tok.is(tok::l_paren)) {
       // Read the identifier
       Lex(Tok);
-      if (Tok.is(tok::identifier)) {
+      if (Tok.is(tok::identifier) || Tok.is(tok::kw_const)) {
         FeatureII = Tok.getIdentifierInfo();
 
         // Read the ')'.
diff --git a/lib/Lex/PTHLexer.cpp b/lib/Lex/PTHLexer.cpp
index f104f96..67738e9 100644
--- a/lib/Lex/PTHLexer.cpp
+++ b/lib/Lex/PTHLexer.cpp
@@ -452,14 +452,14 @@
   const unsigned char *BufEnd = (unsigned char*)File->getBufferEnd();
 
   // Check the prologue of the file.
-  if ((BufEnd - BufBeg) < (signed)(sizeof("cfe-pth") + 3 + 4) ||
-      memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) {
+  if ((BufEnd - BufBeg) < (signed)(sizeof("cfe-pth") + 4 + 4) ||
+      memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth")) != 0) {
     Diags.Report(diag::err_invalid_pth_file) << file;
     return 0;
   }
 
   // Read the PTH version.
-  const unsigned char *p = BufBeg + (sizeof("cfe-pth") - 1);
+  const unsigned char *p = BufBeg + (sizeof("cfe-pth"));
   unsigned Version = ReadLE32(p);
 
   if (Version < PTHManager::Version) {
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index c9cc4ad..b7f7d1d 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -1009,7 +1009,7 @@
     if (II->isStr("assert")) {
       llvm_unreachable("This is an assertion!");
     } else if (II->isStr("crash")) {
-      *(volatile int*) 0x11 = 0;
+      LLVM_BUILTIN_TRAP;
     } else if (II->isStr("parser_crash")) {
       Token Crasher;
       Crasher.setKind(tok::annot_pragma_parser_crash);
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index c699c4a..614530c 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -237,6 +237,20 @@
   llvm::errs() << (NumFastTokenPaste+NumTokenPaste)
              << " token paste (##) operations performed, "
              << NumFastTokenPaste << " on the fast path.\n";
+
+  llvm::errs() << "\nPreprocessor Memory: " << getTotalMemory() << "B total";
+
+  llvm::errs() << "\n  BumpPtr: " << BP.getTotalMemory();
+  llvm::errs() << "\n  Macro Expanded Tokens: "
+               << llvm::capacity_in_bytes(MacroExpandedTokens);
+  llvm::errs() << "\n  Predefines Buffer: " << Predefines.capacity();
+  llvm::errs() << "\n  Macros: " << llvm::capacity_in_bytes(Macros);
+  llvm::errs() << "\n  #pragma push_macro Info: "
+               << llvm::capacity_in_bytes(PragmaPushMacroInfo);
+  llvm::errs() << "\n  Poison Reasons: "
+               << llvm::capacity_in_bytes(PoisonReasons);
+  llvm::errs() << "\n  Comment Handlers: "
+               << llvm::capacity_in_bytes(CommentHandlers) << "\n";
 }
 
 Preprocessor::macro_iterator
diff --git a/lib/Lex/TokenConcatenation.cpp b/lib/Lex/TokenConcatenation.cpp
index 84a46ed..dd7ebb0 100644
--- a/lib/Lex/TokenConcatenation.cpp
+++ b/lib/Lex/TokenConcatenation.cpp
@@ -14,6 +14,7 @@
 #include "clang/Lex/TokenConcatenation.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/Support/ErrorHandling.h"
+#include <cctype>
 using namespace clang;
 
 
diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt
index 38338bc..55e2aeb 100644
--- a/lib/Parse/CMakeLists.txt
+++ b/lib/Parse/CMakeLists.txt
@@ -16,12 +16,14 @@
 
 add_dependencies(clangParse
   ClangAttrClasses
+  ClangAttrLateParsed
   ClangAttrList
+  ClangAttrParsedAttrList
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticCommon
   ClangDiagnosticParse
   ClangStmtNodes
-  ClangAttrLateParsed
   )
 
 target_link_libraries(clangParse
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index c6a7d05..85d3f5a 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -68,7 +68,6 @@
         .Default(false);
 }
 
-
 /// ParseGNUAttributes - Parse a non-empty attributes list.
 ///
 /// [GNU] attributes:
@@ -193,6 +192,11 @@
     ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
     return;
   }
+  // Type safety attributes have their own grammar.
+  if (AttrName->isStr("type_tag_for_datatype")) {
+    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
+    return;
+  }
 
   ConsumeParen(); // ignore the left paren loc for now
 
@@ -847,10 +851,6 @@
     Actions.ActOnStartDelayedMemberDeclarations(getCurScope(),
                                                 Class.TagOrTemplate);
   if (!Class.LateParsedDeclarations.empty()) {
-    // Allow 'this' within late-parsed attributes.
-    Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate,
-                                     /*TypeQuals=*/0);
-
     for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){
       Class.LateParsedDeclarations[i]->ParseLexedAttributes();
     }
@@ -866,7 +866,8 @@
 void Parser::ParseLexedAttributeList(LateParsedAttrList &LAs, Decl *D,
                                      bool EnterScope, bool OnDefinition) {
   for (unsigned i = 0, ni = LAs.size(); i < ni; ++i) {
-    LAs[i]->addDecl(D);
+    if (D)
+      LAs[i]->addDecl(D);
     ParseLexedAttribute(*LAs[i], EnterScope, OnDefinition);
     delete LAs[i];
   }
@@ -899,34 +900,43 @@
   ParsedAttributes Attrs(AttrFactory);
   SourceLocation endLoc;
 
-  if (LA.Decls.size() == 1) {
+  if (LA.Decls.size() > 0) {
     Decl *D = LA.Decls[0];
+    NamedDecl *ND  = dyn_cast<NamedDecl>(D);
+    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
 
-    // If the Decl is templatized, add template parameters to scope.
-    bool HasTemplateScope = EnterScope && D->isTemplateDecl();
-    ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
-    if (HasTemplateScope)
-      Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
+    // Allow 'this' within late-parsed attributes.
+    Sema::CXXThisScopeRAII ThisScope(Actions, RD,
+                                     /*TypeQuals=*/0,
+                                     ND && RD && ND->isCXXInstanceMember());
 
-    // If the Decl is on a function, add function parameters to the scope.
-    bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate();
-    ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope);
-    if (HasFunctionScope)
-      Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
+    if (LA.Decls.size() == 1) {
+      // If the Decl is templatized, add template parameters to scope.
+      bool HasTemplateScope = EnterScope && D->isTemplateDecl();
+      ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope);
+      if (HasTemplateScope)
+        Actions.ActOnReenterTemplateScope(Actions.CurScope, D);
 
-    ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+      // If the Decl is on a function, add function parameters to the scope.
+      bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate();
+      ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope);
+      if (HasFunScope)
+        Actions.ActOnReenterFunctionContext(Actions.CurScope, D);
 
-    if (HasFunctionScope) {
-      Actions.ActOnExitFunctionContext();
-      FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
+      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
+
+      if (HasFunScope) {
+        Actions.ActOnExitFunctionContext();
+        FnScope.Exit();  // Pop scope, and remove Decls from IdResolver
+      }
+      if (HasTemplateScope) {
+        TempScope.Exit();
+      }
+    } else {
+      // If there are multiple decls, then the decl cannot be within the
+      // function scope.
+      ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
     }
-    if (HasTemplateScope) {
-      TempScope.Exit();
-    }
-  } else if (LA.Decls.size() > 0) {
-    // If there are multiple decls, then the decl cannot be within the
-    // function scope.
-    ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc);
   } else {
     Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName();
   }
@@ -1019,6 +1029,70 @@
     *EndLoc = T.getCloseLocation();
 }
 
+void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
+                                              SourceLocation AttrNameLoc,
+                                              ParsedAttributes &Attrs,
+                                              SourceLocation *EndLoc) {
+  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
+
+  BalancedDelimiterTracker T(*this, tok::l_paren);
+  T.consumeOpen();
+
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_expected_ident);
+    T.skipToEnd();
+    return;
+  }
+  IdentifierInfo *ArgumentKind = Tok.getIdentifierInfo();
+  SourceLocation ArgumentKindLoc = ConsumeToken();
+
+  if (Tok.isNot(tok::comma)) {
+    Diag(Tok, diag::err_expected_comma);
+    T.skipToEnd();
+    return;
+  }
+  ConsumeToken();
+
+  SourceRange MatchingCTypeRange;
+  TypeResult MatchingCType = ParseTypeName(&MatchingCTypeRange);
+  if (MatchingCType.isInvalid()) {
+    T.skipToEnd();
+    return;
+  }
+
+  bool LayoutCompatible = false;
+  bool MustBeNull = false;
+  while (Tok.is(tok::comma)) {
+    ConsumeToken();
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_expected_ident);
+      T.skipToEnd();
+      return;
+    }
+    IdentifierInfo *Flag = Tok.getIdentifierInfo();
+    if (Flag->isStr("layout_compatible"))
+      LayoutCompatible = true;
+    else if (Flag->isStr("must_be_null"))
+      MustBeNull = true;
+    else {
+      Diag(Tok, diag::err_type_safety_unknown_flag) << Flag;
+      T.skipToEnd();
+      return;
+    }
+    ConsumeToken(); // consume flag
+  }
+
+  if (!T.consumeClose()) {
+    Attrs.addNewTypeTagForDatatype(&AttrName, AttrNameLoc, 0, AttrNameLoc,
+                                   ArgumentKind, ArgumentKindLoc,
+                                   MatchingCType.release(), LayoutCompatible,
+                                   MustBeNull, AttributeList::AS_GNU);
+  }
+
+  if (EndLoc)
+    *EndLoc = T.getCloseLocation();
+}
+
 /// DiagnoseProhibitedCXX11Attribute - We have found the opening square brackets
 /// of a C++11 attribute-specifier in a location where an attribute is not
 /// permitted. By C++11 [dcl.attr.grammar]p6, this is ill-formed. Diagnose this
@@ -1340,12 +1414,7 @@
       // 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.
-      // FIXME. Delayed parsing not done for c/c++ functions nested in namespace
-      !isDeclarationAfterDeclarator() && 
-      (!CurParsedObjCImpl || Tok.isNot(tok::l_brace) || 
-       (getLangOpts().CPlusPlus && 
-        (D.getCXXScopeSpec().isSet() || 
-         !Actions.CurContext->isTranslationUnit())))) {
+      !isDeclarationAfterDeclarator()) {
 
     if (isStartOfFunctionDefinition(D)) {
       if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
@@ -1401,14 +1470,6 @@
     DeclsInGroup.push_back(FirstDecl);
 
   bool ExpectSemi = Context != Declarator::ForContext;
-
-  if (CurParsedObjCImpl && D.isFunctionDeclarator() &&
-      Tok.is(tok::l_brace)) {
-    // Consume the tokens and store them for later parsing.
-    StashAwayMethodOrFunctionBodyTokens(FirstDecl);
-    CurParsedObjCImpl->HasCFunction = true;
-    ExpectSemi = false;
-  }
   
   // If we don't have a comma, it is either the end of the list (a ';') or an
   // error, bail out.
@@ -1580,6 +1641,7 @@
 
       if (Tok.is(tok::code_completion)) {
         Actions.CodeCompleteInitializer(getCurScope(), ThisDecl);
+        Actions.FinalizeDeclaration(ThisDecl);
         cutOffParsing();
         return 0;
       }
@@ -2666,15 +2728,15 @@
     // cv-qualifier:
     case tok::kw_const:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const, Loc, PrevSpec, DiagID,
-                                 getLangOpts());
+                                 getLangOpts(), /*IsTypeSpec*/true);
       break;
     case tok::kw_volatile:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
-                                 getLangOpts());
+                                 getLangOpts(), /*IsTypeSpec*/true);
       break;
     case tok::kw_restrict:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
-                                 getLangOpts());
+                                 getLangOpts(), /*IsTypeSpec*/true);
       break;
 
     // C++ typename-specifier:
@@ -2772,7 +2834,7 @@
 /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
 ///
 void Parser::
-ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
+ParseStructDeclaration(ParsingDeclSpec &DS, FieldCallback &Fields) {
 
   if (Tok.is(tok::kw___extension__)) {
     // __extension__ silences extension warnings in the subexpression.
@@ -2787,7 +2849,9 @@
   // 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(getCurScope(), AS_none, DS);
+    Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none,
+                                                       DS);
+    DS.complete(TheDecl);
     return;
   }
 
@@ -2795,8 +2859,7 @@
   bool FirstDeclarator = true;
   SourceLocation CommaLoc;
   while (1) {
-    ParsingDeclRAIIObject PD(*this, ParsingDeclRAIIObject::NoParent);
-    FieldDeclarator DeclaratorInfo(DS);
+    ParsingFieldDeclarator DeclaratorInfo(*this, DS);
     DeclaratorInfo.D.setCommaLoc(CommaLoc);
 
     // Attributes are only allowed here on successive declarators.
@@ -2824,8 +2887,7 @@
     MaybeParseGNUAttributes(DeclaratorInfo.D);
 
     // We're done with this declarator;  invoke the callback.
-    Decl *D = Fields.invoke(DeclaratorInfo);
-    PD.complete(D);
+    Fields.invoke(DeclaratorInfo);
 
     // If we don't have a comma, it is either the end of the list (a ';')
     // or an error, bail out.
@@ -2880,9 +2942,6 @@
       continue;
     }
 
-    // Parse all the comma separated declarators.
-    DeclSpec DS(AttrFactory);
-
     if (!Tok.is(tok::at)) {
       struct CFieldCallback : FieldCallback {
         Parser &P;
@@ -2893,16 +2952,18 @@
                        SmallVectorImpl<Decl *> &FieldDecls) :
           P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
 
-        virtual Decl *invoke(FieldDeclarator &FD) {
+        void invoke(ParsingFieldDeclarator &FD) {
           // Install the declarator into the current TagDecl.
           Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl,
                               FD.D.getDeclSpec().getSourceRange().getBegin(),
                                                  FD.D, FD.BitfieldSize);
           FieldDecls.push_back(Field);
-          return Field;
+          FD.complete(Field);
         }
       } Callback(*this, TagDecl, FieldDecls);
 
+      // Parse all the comma separated declarators.
+      ParsingDeclSpec DS(*this);
       ParseStructDeclaration(DS, Callback);
     } else { // Handle @defs
       ConsumeToken();
@@ -3109,6 +3170,8 @@
       // anything that's a simple-type-specifier followed by '(' as an
       // expression. This suffices because function types are not valid
       // underlying types anyway.
+      EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                   Sema::ConstantEvaluated);
       TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
       // If the next token starts an expression, we know we're parsing a
       // bit-field. This is the common case.
@@ -3869,15 +3932,15 @@
 
     case tok::kw_const:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_const   , Loc, PrevSpec, DiagID,
-                                 getLangOpts());
+                                 getLangOpts(), /*IsTypeSpec*/false);
       break;
     case tok::kw_volatile:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_volatile, Loc, PrevSpec, DiagID,
-                                 getLangOpts());
+                                 getLangOpts(), /*IsTypeSpec*/false);
       break;
     case tok::kw_restrict:
       isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID,
-                                 getLangOpts());
+                                 getLangOpts(), /*IsTypeSpec*/false);
       break;
 
     // OpenCL qualifiers:
@@ -4288,7 +4351,7 @@
     D.SetIdentifier(0, Tok.getLocation());
   } else {
     if (Tok.getKind() == tok::annot_pragma_parser_crash)
-      *(volatile int*) 0x11 = 0;
+      LLVM_BUILTIN_TRAP;
     if (D.getContext() == Declarator::MemberContext)
       Diag(Tok, diag::err_expected_member_name_or_semi)
         << D.getDeclSpec().getSourceRange();
@@ -4317,17 +4380,20 @@
       // The paren may be part of a C++ direct initializer, eg. "int x(1);".
       // In such a case, check if we actually have a function declarator; if it
       // is not, the declarator has been fully parsed.
+      bool IsAmbiguous = false;
       if (getLangOpts().CPlusPlus && D.mayBeFollowedByCXXDirectInit()) {
-        // When not in file scope, warn for ambiguous function declarators, just
-        // in case the author intended it as a variable definition.
-        bool warnIfAmbiguous = D.getContext() != Declarator::FileContext;
-        if (!isCXXFunctionDeclarator(warnIfAmbiguous))
+        // The name of the declarator, if any, is tentatively declared within
+        // a possible direct initializer.
+        TentativelyDeclaredIdentifiers.push_back(D.getIdentifier());
+        bool IsFunctionDecl = isCXXFunctionDeclarator(&IsAmbiguous);
+        TentativelyDeclaredIdentifiers.pop_back();
+        if (!IsFunctionDecl)
           break;
       }
       ParsedAttributes attrs(AttrFactory);
       BalancedDelimiterTracker T(*this, tok::l_paren);
       T.consumeOpen();
-      ParseFunctionDeclarator(D, attrs, T);
+      ParseFunctionDeclarator(D, attrs, T, IsAmbiguous);
       PrototypeScope.Exit();
     } else if (Tok.is(tok::l_square)) {
       ParseBracketDeclarator(D);
@@ -4444,7 +4510,7 @@
   // function prototype scope, including parameter declarators.
   ParseScope PrototypeScope(this,
                             Scope::FunctionPrototypeScope|Scope::DeclScope);
-  ParseFunctionDeclarator(D, attrs, T, RequiresArg);
+  ParseFunctionDeclarator(D, attrs, T, false, RequiresArg);
   PrototypeScope.Exit();
 }
 
@@ -4470,6 +4536,7 @@
 void Parser::ParseFunctionDeclarator(Declarator &D,
                                      ParsedAttributes &FirstArgAttrs,
                                      BalancedDelimiterTracker &Tracker,
+                                     bool IsAmbiguous,
                                      bool RequiresArg) {
   assert(getCurScope()->isFunctionPrototypeScope() &&
          "Should call from a Function scope");
@@ -4587,7 +4654,7 @@
   // Remember that we parsed a function type, and remember the attributes.
   D.AddTypeInfo(DeclaratorChunk::getFunction(HasProto,
                                              /*isVariadic=*/EllipsisLoc.isValid(),
-                                             EllipsisLoc,
+                                             IsAmbiguous, EllipsisLoc,
                                              ParamInfo.data(), ParamInfo.size(),
                                              DS.getTypeQualifiers(),
                                              RefQualifierIsLValueRef,
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 7f268b5..8d4668b 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2415,7 +2415,7 @@
   } else {
     // Otherwise, pretend we saw (void).
     ParsedAttributes attrs(AttrFactory);
-    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
+    ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false, false,
                                                        SourceLocation(),
                                                        0, 0, 0,
                                                        true, SourceLocation(),
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 39ef38f..baad166 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -642,7 +642,13 @@
   while (Tok.isNot(tok::r_square)) {
     if (!first) {
       if (Tok.isNot(tok::comma)) {
-        if (Tok.is(tok::code_completion)) {
+        // Provide a completion for a lambda introducer here. Except
+        // in Objective-C, where this is Almost Surely meant to be a message
+        // send. In that case, fail here and let the ObjC message
+        // expression parser perform the completion.
+        if (Tok.is(tok::code_completion) &&
+            !(getLangOpts().ObjC1 && Intro.Default == LCD_None &&
+              !Intro.Captures.empty())) {
           Actions.CodeCompleteLambdaIntroducer(getCurScope(), Intro, 
                                                /*AfterAmpersand=*/false);
           ConsumeCodeCompletionToken();
@@ -804,7 +810,7 @@
 
     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
                                            /*isVariadic=*/EllipsisLoc.isValid(),
-                                           EllipsisLoc,
+                                           /*isAmbiguous=*/false, EllipsisLoc,
                                            ParamInfo.data(), ParamInfo.size(),
                                            DS.getTypeQualifiers(),
                                            /*RefQualifierIsLValueRef=*/true,
@@ -849,6 +855,7 @@
     ParsedAttributes Attr(AttrFactory);
     D.AddTypeInfo(DeclaratorChunk::getFunction(/*hasProto=*/true,
                      /*isVariadic=*/false,
+                     /*isAmbiguous=*/false,
                      /*EllipsisLoc=*/SourceLocation(),
                      /*Params=*/0, /*NumParams=*/0,
                      /*TypeQuals=*/0,
@@ -919,10 +926,11 @@
 
   // Check for "<::" which is parsed as "[:".  If found, fix token stream,
   // diagnose error, suggest fix, and recover parsing.
-  Token Next = NextToken();
-  if (Tok.is(tok::l_square) && Tok.getLength() == 2 && Next.is(tok::colon) &&
-      areTokensAdjacent(Tok, Next))
-    FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true);
+  if (Tok.is(tok::l_square) && Tok.getLength() == 2) {
+    Token Next = NextToken();
+    if (Next.is(tok::colon) && areTokensAdjacent(Tok, Next))
+      FixDigraph(*this, PP, Tok, Next, Kind, /*AtDigraph*/true);
+  }
 
   if (ExpectAndConsume(tok::less, diag::err_expected_less_after, CastName))
     return ExprError();
@@ -981,6 +989,21 @@
 
   ExprResult Result;
 
+  // C++0x [expr.typeid]p3:
+  //   When typeid is applied to an expression other than an lvalue of a
+  //   polymorphic class type [...] The expression is an unevaluated
+  //   operand (Clause 5).
+  //
+  // Note that we can't tell whether the expression is an lvalue of a
+  // polymorphic class type until after we've parsed the expression; we
+  // speculatively assume the subexpression is unevaluated, and fix it up
+  // later.
+  //
+  // We enter the unevaluated context before trying to determine whether we
+  // have a type-id, because the tentative parse logic will try to resolve
+  // names, and must treat them as unevaluated.
+  EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
+
   if (isTypeIdInParens()) {
     TypeResult Ty = ParseTypeName();
 
@@ -993,16 +1016,6 @@
     Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
                                     Ty.get().getAsOpaquePtr(), RParenLoc);
   } else {
-    // C++0x [expr.typeid]p3:
-    //   When typeid is applied to an expression other than an lvalue of a
-    //   polymorphic class type [...] The expression is an unevaluated
-    //   operand (Clause 5).
-    //
-    // Note that we can't tell whether the expression is an lvalue of a
-    // polymorphic class type until after we've parsed the expression; we
-    // speculatively assume the subexpression is unevaluated, and fix it up
-    // later.
-    EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
     Result = ParseExpression();
 
     // Match the ')'.
@@ -2396,10 +2409,14 @@
   // Array delete?
   bool ArrayDelete = false;
   if (Tok.is(tok::l_square) && NextToken().is(tok::r_square)) {
-    // FIXME: This could be the start of a lambda-expression. We should
-    // disambiguate this, but that will require arbitrary lookahead if
-    // the next token is '(':
-    //   delete [](int*){ /* ... */
+    // C++11 [expr.delete]p1:
+    //   Whenever the delete keyword is followed by empty square brackets, it
+    //   shall be interpreted as [array delete].
+    //   [Footnote: A lambda expression with a lambda-introducer that consists
+    //              of empty square brackets can follow the delete keyword if
+    //              the lambda expression is enclosed in parentheses.]
+    // FIXME: Produce a better diagnostic if the '[]' is unambiguously a
+    //        lambda-introducer.
     ArrayDelete = true;
     BalancedDelimiterTracker T(*this, tok::l_square);
 
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 857040f..db35a38 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -308,16 +308,16 @@
     MethodImplKind(MethodImplKind) {
   }
 
-  Decl *invoke(FieldDeclarator &FD) {
+  void invoke(ParsingFieldDeclarator &FD) {
     if (FD.D.getIdentifier() == 0) {
       P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
         << FD.D.getSourceRange();
-      return 0;
+      return;
     }
     if (FD.BitfieldSize) {
       P.Diag(AtLoc, diag::err_objc_property_bitfield)
         << FD.D.getSourceRange();
-      return 0;
+      return;
     }
 
     // Install the property declarator into interfaceDecl.
@@ -344,7 +344,7 @@
     if (!isOverridingProperty)
       Props.push_back(Property);
 
-    return Property;
+    FD.complete(Property);
   }
 };
 
@@ -375,9 +375,9 @@
   while (1) {
     // If this is a method prototype, parse it.
     if (Tok.is(tok::minus) || Tok.is(tok::plus)) {
-      Decl *methodPrototype =
-        ParseObjCMethodPrototype(MethodImplKind, false);
-      allMethods.push_back(methodPrototype);
+      if (Decl *methodPrototype =
+          ParseObjCMethodPrototype(MethodImplKind, false))
+        allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
       // method definitions.
       if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
@@ -493,7 +493,7 @@
                                     OCDS, AtLoc, LParenLoc, MethodImplKind);
 
       // Parse all the comma separated declarators.
-      DeclSpec DS(AttrFactory);
+      ParsingDeclSpec DS(*this);
       ParseStructDeclaration(DS, Callback);
 
       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list);
@@ -1001,8 +1001,8 @@
   if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name.
     Diag(Tok, diag::err_expected_selector_for_method)
       << SourceRange(mLoc, Tok.getLocation());
-    // Skip until we get a ; or {}.
-    SkipUntil(tok::r_brace);
+    // Skip until we get a ; or @.
+    SkipUntil(tok::at, true /*StopAtSemi*/, true /*don't consume*/);
     return 0;
   }
 
@@ -1306,7 +1306,7 @@
         P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
       }
 
-      Decl *invoke(FieldDeclarator &FD) {
+      void invoke(ParsingFieldDeclarator &FD) {
         P.Actions.ActOnObjCContainerStartDefinition(IDecl);
         // Install the declarator into the interface decl.
         Decl *Field
@@ -1316,12 +1316,12 @@
         P.Actions.ActOnObjCContainerFinishDefinition();
         if (Field)
           AllIvarDecls.push_back(Field);
-        return Field;
+        FD.complete(Field);
       }
     } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
     
     // Parse all the comma separated declarators.
-    DeclSpec DS(AttrFactory);
+    ParsingDeclSpec DS(*this);
     ParseStructDeclaration(DS, Callback);
 
     if (Tok.is(tok::semi)) {
@@ -1616,8 +1616,8 @@
   SourceLocation classLoc = ConsumeToken(); // consume class-name;
   ExpectAndConsume(tok::semi, diag::err_expected_semi_after, 
                    "@compatibility_alias");
-  return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc,
-                                        classId, classLoc);
+  return Actions.ActOnCompatibilityAlias(atLoc, aliasId, aliasLoc,
+                                         classId, classLoc);
 }
 
 ///   property-synthesis:
@@ -1927,11 +1927,35 @@
   LexedMethod* LM = new LexedMethod(this, MDecl);
   CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
   CachedTokens &Toks = LM->Toks;
-  // Begin by storing the '{' token.
+  // Begin by storing the '{' or 'try' or ':' token.
   Toks.push_back(Tok);
+  if (Tok.is(tok::kw_try)) {
+    ConsumeToken();
+    if (Tok.is(tok::colon)) {
+      Toks.push_back(Tok);
+      ConsumeToken();
+      while (Tok.isNot(tok::l_brace)) {
+        ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
+        ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
+      }
+    }
+    Toks.push_back(Tok); // also store '{'
+  }
+  else if (Tok.is(tok::colon)) {
+    ConsumeToken();
+    while (Tok.isNot(tok::l_brace)) {
+      ConsumeAndStoreUntil(tok::l_paren, Toks, /*StopAtSemi=*/false);
+      ConsumeAndStoreUntil(tok::r_paren, Toks, /*StopAtSemi=*/false);
+    }
+    Toks.push_back(Tok); // also store '{'
+  }
   ConsumeBrace();
   // Consume everything up to (and including) the matching right brace.
   ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+  while (Tok.is(tok::kw_catch)) {
+    ConsumeAndStoreUntil(tok::l_brace, Toks, /*StopAtSemi=*/false);
+    ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
+  }
 }
 
 ///   objc-method-def: objc-method-proto ';'[opt] '{' body '}'
@@ -1971,15 +1995,10 @@
 
   // Allow the rest of sema to find private method decl implementations.
   Actions.AddAnyMethodToGlobalPool(MDecl);
-
-  if (CurParsedObjCImpl) {
-    // Consume the tokens and store them for later parsing.
-    StashAwayMethodOrFunctionBodyTokens(MDecl);
-  } else {
-    ConsumeBrace();
-    SkipUntil(tok::r_brace, /*StopAtSemi=*/false);
-  }
-
+  assert (CurParsedObjCImpl 
+          && "ParseObjCMethodDefinition - Method out of @implementation");
+  // Consume the tokens and store them for later parsing.
+  StashAwayMethodOrFunctionBodyTokens(MDecl);
   return MDecl;
 }
 
@@ -2868,8 +2887,9 @@
   // Consume the previously pushed token.
   ConsumeAnyToken();
     
-  assert(Tok.is(tok::l_brace) && "Inline objective-c method not starting with '{'");
-  SourceLocation BraceLoc = Tok.getLocation();
+  assert((Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
+          Tok.is(tok::colon)) && 
+          "Inline objective-c method not starting with '{' or 'try' or ':'");
   // Enter a scope for the method or c-fucntion body.
   ParseScope BodyScope(this,
                        parseMethod
@@ -2878,28 +2898,18 @@
     
   // Tell the actions module that we have entered a method or c-function definition 
   // with the specified Declarator for the method/function.
-  Actions.ActOnStartOfObjCMethodOrCFunctionDef(getCurScope(), MCDecl, parseMethod);
-    
-  if (SkipFunctionBodies && trySkippingFunctionBody()) {
-    BodyScope.Exit();
-    (void)Actions.ActOnFinishFunctionBody(MCDecl, 0);
-    return;
+  if (parseMethod)
+    Actions.ActOnStartOfObjCMethodDef(getCurScope(), MCDecl);
+  else
+    Actions.ActOnStartOfFunctionDef(getCurScope(), MCDecl);
+  if (Tok.is(tok::kw_try))
+    MCDecl = ParseFunctionTryBlock(MCDecl, BodyScope);
+  else {
+    if (Tok.is(tok::colon))
+      ParseConstructorInitializer(MCDecl);
+    MCDecl = ParseFunctionStatementBody(MCDecl, BodyScope);
   }
-    
-  StmtResult FnBody(ParseCompoundStatementBody());
-    
-  // If the function body could not be parsed, make a bogus compoundstmt.
-  if (FnBody.isInvalid()) {
-    Sema::CompoundScopeRAII CompoundScope(Actions);
-    FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
-                                       MultiStmtArg(Actions), false);
-  }
-    
-  // Leave the function body scope.
-  BodyScope.Exit();
-    
-  (void)Actions.ActOnFinishFunctionBody(MCDecl, FnBody.take());
-
+  
   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
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index e13ce6b..091d4aa 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -17,6 +17,7 @@
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/PrettyDeclStackTrace.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/TypoCorrection.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Basic/SourceManager.h"
@@ -130,96 +131,38 @@
       return ParseLabeledStatement(Attrs);
     }
 
+    // Look up the identifier, and typo-correct it to a keyword if it's not
+    // found.
     if (Next.isNot(tok::coloncolon)) {
-      CXXScopeSpec SS;
-      IdentifierInfo *Name = Tok.getIdentifierInfo();
-      SourceLocation NameLoc = Tok.getLocation();
-
-      if (getLangOpts().CPlusPlus)
-        CheckForTemplateAndDigraph(Next, ParsedType(),
-                                   /*EnteringContext=*/false, *Name, SS);
-
-      Sema::NameClassification Classification
-        = Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next);
-      switch (Classification.getKind()) {
-      case Sema::NC_Keyword:
-        // The identifier was corrected to a keyword. Update the token
-        // to this keyword, and try again.
-        if (Name->getTokenID() != tok::identifier) {
-          Tok.setIdentifierInfo(Name);
-          Tok.setKind(Name->getTokenID());
-          goto Retry;
-        }
-
-        // Fall through via the normal error path.
-        // FIXME: This seems like it could only happen for context-sensitive
-        // keywords.
-
-      case Sema::NC_Error:
+      // Try to limit which sets of keywords should be included in typo
+      // correction based on what the next token is.
+      // FIXME: Pass the next token into the CorrectionCandidateCallback and
+      //        do this filtering in a more fine-grained manner.
+      CorrectionCandidateCallback DefaultValidator;
+      DefaultValidator.WantTypeSpecifiers =
+          Next.is(tok::l_paren) || Next.is(tok::less) ||
+          Next.is(tok::identifier) || Next.is(tok::star) ||
+          Next.is(tok::amp) || Next.is(tok::l_square);
+      DefaultValidator.WantExpressionKeywords =
+          Next.is(tok::l_paren) || Next.is(tok::identifier) ||
+          Next.is(tok::arrow) || Next.is(tok::period);
+      DefaultValidator.WantRemainingKeywords =
+          Next.is(tok::l_paren) || Next.is(tok::semi) ||
+          Next.is(tok::identifier) || Next.is(tok::l_brace);
+      DefaultValidator.WantCXXNamedCasts = false;
+      if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator)
+            == ANK_Error) {
         // Handle errors here by skipping up to the next semicolon or '}', and
         // eat the semicolon if that's what stopped us.
         SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
         if (Tok.is(tok::semi))
           ConsumeToken();
         return StmtError();
+      }
 
-      case Sema::NC_Unknown:
-        // Either we don't know anything about this identifier, or we know that
-        // we're in a syntactic context we haven't handled yet.
-        break;
-
-      case Sema::NC_Type:
-        Tok.setKind(tok::annot_typename);
-        setTypeAnnotation(Tok, Classification.getType());
-        Tok.setAnnotationEndLoc(NameLoc);
-        PP.AnnotateCachedTokens(Tok);
-        break;
-
-      case Sema::NC_Expression:
-        Tok.setKind(tok::annot_primary_expr);
-        setExprAnnotation(Tok, Classification.getExpression());
-        Tok.setAnnotationEndLoc(NameLoc);
-        PP.AnnotateCachedTokens(Tok);
-        break;
-
-      case Sema::NC_TypeTemplate:
-      case Sema::NC_FunctionTemplate: {
-        ConsumeToken(); // the identifier
-        UnqualifiedId Id;
-        Id.setIdentifier(Name, NameLoc);
-        if (AnnotateTemplateIdToken(
-                            TemplateTy::make(Classification.getTemplateName()),
-                                    Classification.getTemplateNameKind(),
-                                    SS, SourceLocation(), Id,
-                                    /*AllowTypeAnnotation=*/false)) {
-          // Handle errors here by skipping up to the next semicolon or '}', and
-          // eat the semicolon if that's what stopped us.
-          SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
-          if (Tok.is(tok::semi))
-            ConsumeToken();
-          return StmtError();
-        }
-
-        // If the next token is '::', jump right into parsing a
-        // nested-name-specifier. We don't want to leave the template-id
-        // hanging.
-        if (NextToken().is(tok::coloncolon) && TryAnnotateCXXScopeToken(false)){
-          // Handle errors here by skipping up to the next semicolon or '}', and
-          // eat the semicolon if that's what stopped us.
-          SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true);
-          if (Tok.is(tok::semi))
-            ConsumeToken();
-          return StmtError();
-        }
-
-        // We've annotated a template-id, so try again now.
+      // If the identifier was typo-corrected, try again.
+      if (Tok.isNot(tok::identifier))
         goto Retry;
-      }
-
-      case Sema::NC_NestedNameSpecifier:
-        // FIXME: Implement this!
-        break;
-      }
     }
 
     // Fall through
@@ -1495,17 +1438,16 @@
   StmtResult ForEachStmt;
 
   if (ForRange) {
-    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, T.getOpenLocation(),
-                                                FirstPart.take(),
+    ForRangeStmt = Actions.ActOnCXXForRangeStmt(ForLoc, FirstPart.take(),
                                                 ForRangeInit.ColonLoc,
                                                 ForRangeInit.RangeExpr.get(),
-                                                T.getCloseLocation());
+                                                T.getCloseLocation(), true);
 
 
   // Similarly, we need to do the semantic analysis for a for-range
   // statement immediately in order to close over temporaries correctly.
   } else if (ForEach) {
-    ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc, T.getOpenLocation(),
+    ForEachStmt = Actions.ActOnObjCForCollectionStmt(ForLoc,
                                                      FirstPart.take(),
                                                      Collection.take(),
                                                      T.getCloseLocation());
@@ -1638,41 +1580,6 @@
   return Actions.ActOnReturnStmt(ReturnLoc, R.take());
 }
 
-// needSpaceAsmToken - This function handles whitespace around asm punctuation.
-// Returns true if a space should be emitted.
-static inline bool needSpaceAsmToken(Token currTok) {
-  static Token prevTok;
-
-  // No need for space after prevToken.
-  switch(prevTok.getKind()) {
-  default:
-    break;
-  case tok::l_square:
-  case tok::r_square:
-  case tok::l_brace:
-  case tok::r_brace:
-  case tok::colon:
-    prevTok = currTok;
-    return false;
-  }
-
-  // No need for a space before currToken.
-  switch(currTok.getKind()) {
-  default:
-    break;
-  case tok::l_square:
-  case tok::r_square:
-  case tok::l_brace:
-  case tok::r_brace:
-  case tok::comma:
-  case tok::colon:
-    prevTok = currTok;
-    return false;
-  }
-  prevTok = currTok;
-  return true;
-}
-
 /// ParseMicrosoftAsmStatement. When -fms-extensions/-fasm-blocks is enabled,
 /// this routine is called to collect the tokens for an MS asm statement.
 ///
@@ -1692,136 +1599,98 @@
   SourceManager &SrcMgr = PP.getSourceManager();
   SourceLocation EndLoc = AsmLoc;
   SmallVector<Token, 4> AsmToks;
-  SmallVector<unsigned, 4> LineEnds;
-  do {
-    bool InBraces = false;
-    unsigned short savedBraceCount = 0;
-    bool InAsmComment = false;
-    FileID FID;
-    unsigned LineNo = 0;
-    unsigned NumTokensRead = 0;
-    SourceLocation LBraceLoc;
 
-    if (Tok.is(tok::l_brace)) {
-      // Braced inline asm: consume the opening brace.
-      InBraces = true;
-      savedBraceCount = BraceCount;
-      EndLoc = LBraceLoc = ConsumeBrace();
-      ++NumTokensRead;
-    } else {
-      // Single-line inline asm; compute which line it is on.
-      std::pair<FileID, unsigned> ExpAsmLoc =
-          SrcMgr.getDecomposedExpansionLoc(EndLoc);
-      FID = ExpAsmLoc.first;
-      LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
-    }
+  bool InBraces = false;
+  unsigned short savedBraceCount = 0;
+  bool InAsmComment = false;
+  FileID FID;
+  unsigned LineNo = 0;
+  unsigned NumTokensRead = 0;
+  SourceLocation LBraceLoc;
 
-    SourceLocation TokLoc = Tok.getLocation();
-    do {
-      // If we hit EOF, we're done, period.
-      if (Tok.is(tok::eof))
-        break;
-
-      // The asm keyword is a statement separator, so multiple asm statements
-      // are allowed.
-      if (!InAsmComment && Tok.is(tok::kw_asm))
-        break;
-
-      if (!InAsmComment && Tok.is(tok::semi)) {
-        // A semicolon in an asm is the start of a comment.
-        InAsmComment = true;
-        if (InBraces) {
-          // Compute which line the comment is on.
-          std::pair<FileID, unsigned> ExpSemiLoc =
-              SrcMgr.getDecomposedExpansionLoc(TokLoc);
-          FID = ExpSemiLoc.first;
-          LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
-        }
-      } else if (!InBraces || InAsmComment) {
-        // If end-of-line is significant, check whether this token is on a
-        // new line.
-        std::pair<FileID, unsigned> ExpLoc =
-            SrcMgr.getDecomposedExpansionLoc(TokLoc);
-        if (ExpLoc.first != FID ||
-            SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
-          // If this is a single-line __asm, we're done.
-          if (!InBraces)
-            break;
-          // We're no longer in a comment.
-          InAsmComment = false;
-        } else if (!InAsmComment && Tok.is(tok::r_brace)) {
-          // Single-line asm always ends when a closing brace is seen.
-          // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
-          // does MSVC do here?
-          break;
-        }
-      }
-      if (!InAsmComment && InBraces && Tok.is(tok::r_brace) &&
-          BraceCount == (savedBraceCount + 1)) {
-        // Consume the closing brace, and finish
-        EndLoc = ConsumeBrace();
-        break;
-      }
-
-      // Consume the next token; make sure we don't modify the brace count etc.
-      // if we are in a comment.
-      EndLoc = TokLoc;
-      if (InAsmComment)
-        PP.Lex(Tok);
-      else {
-        AsmToks.push_back(Tok);
-        ConsumeAnyToken();
-      }
-      TokLoc = Tok.getLocation();
-      ++NumTokensRead;
-    } while (1);
-
-    LineEnds.push_back(AsmToks.size());
-
-    if (InBraces && BraceCount != savedBraceCount) {
-      // __asm without closing brace (this can happen at EOF).
-      Diag(Tok, diag::err_expected_rbrace);
-      Diag(LBraceLoc, diag::note_matching) << "{";
-      return StmtError();
-    } else if (NumTokensRead == 0) {
-      // Empty __asm.
-      Diag(Tok, diag::err_expected_lbrace);
-      return StmtError();
-    }
-    // Multiple adjacent asm's form together into a single asm statement
-    // in the AST.
-    if (!Tok.is(tok::kw_asm))
-      break;
-    EndLoc = ConsumeToken();
-  } while (1);
-
-  // Collect the tokens into a string
-  SmallString<512> Asm;
-  SmallString<512> TokenBuf;
-  TokenBuf.resize(512);
-  unsigned AsmLineNum = 0;
-  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
-    const char *ThisTokBuf = &TokenBuf[0];
-    bool StringInvalid = false;
-    unsigned ThisTokLen =
-      Lexer::getSpelling(AsmToks[i], ThisTokBuf, PP.getSourceManager(),
-                         PP.getLangOpts(), &StringInvalid);
-    if (i && (!AsmLineNum || i != LineEnds[AsmLineNum-1]) &&
-        needSpaceAsmToken(AsmToks[i]))
-      Asm += ' ';
-    Asm += StringRef(ThisTokBuf, ThisTokLen);
-    if (i + 1 == LineEnds[AsmLineNum] && i + 1 != AsmToks.size()) {
-      Asm += '\n';
-      ++AsmLineNum;
-    }
+  if (Tok.is(tok::l_brace)) {
+    // Braced inline asm: consume the opening brace.
+    InBraces = true;
+    savedBraceCount = BraceCount;
+    EndLoc = LBraceLoc = ConsumeBrace();
+    ++NumTokensRead;
+  } else {
+    // Single-line inline asm; compute which line it is on.
+    std::pair<FileID, unsigned> ExpAsmLoc =
+      SrcMgr.getDecomposedExpansionLoc(EndLoc);
+    FID = ExpAsmLoc.first;
+    LineNo = SrcMgr.getLineNumber(FID, ExpAsmLoc.second);
   }
 
-  // FIXME: We should be passing the tokens and source locations, rather than
-  // (or possibly in addition to the) AsmString.  Sema is going to interact with
-  // MC to determine Constraints, Clobbers, etc., which would be simplest to
-  // do with the tokens.
-  std::string AsmString = Asm.c_str();
-  return Actions.ActOnMSAsmStmt(AsmLoc, AsmString, EndLoc);
+  SourceLocation TokLoc = Tok.getLocation();
+  do {
+    // If we hit EOF, we're done, period.
+    if (Tok.is(tok::eof))
+      break;
+
+    if (!InAsmComment && Tok.is(tok::semi)) {
+      // A semicolon in an asm is the start of a comment.
+      InAsmComment = true;
+      if (InBraces) {
+        // Compute which line the comment is on.
+        std::pair<FileID, unsigned> ExpSemiLoc =
+          SrcMgr.getDecomposedExpansionLoc(TokLoc);
+        FID = ExpSemiLoc.first;
+        LineNo = SrcMgr.getLineNumber(FID, ExpSemiLoc.second);
+      }
+    } else if (!InBraces || InAsmComment) {
+      // If end-of-line is significant, check whether this token is on a
+      // new line.
+      std::pair<FileID, unsigned> ExpLoc =
+        SrcMgr.getDecomposedExpansionLoc(TokLoc);
+      if (ExpLoc.first != FID ||
+          SrcMgr.getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
+        // If this is a single-line __asm, we're done.
+        if (!InBraces)
+          break;
+        // We're no longer in a comment.
+        InAsmComment = false;
+      } else if (!InAsmComment && Tok.is(tok::r_brace)) {
+        // Single-line asm always ends when a closing brace is seen.
+        // FIXME: This is compatible with Apple gcc's -fasm-blocks; what
+        // does MSVC do here?
+        break;
+      }
+    }
+    if (!InAsmComment && InBraces && Tok.is(tok::r_brace) &&
+        BraceCount == (savedBraceCount + 1)) {
+      // Consume the closing brace, and finish
+      EndLoc = ConsumeBrace();
+      break;
+    }
+
+    // Consume the next token; make sure we don't modify the brace count etc.
+    // if we are in a comment.
+    EndLoc = TokLoc;
+    if (InAsmComment)
+      PP.Lex(Tok);
+    else {
+      AsmToks.push_back(Tok);
+      ConsumeAnyToken();
+    }
+    TokLoc = Tok.getLocation();
+    ++NumTokensRead;
+  } while (1);
+
+  if (InBraces && BraceCount != savedBraceCount) {
+    // __asm without closing brace (this can happen at EOF).
+    Diag(Tok, diag::err_expected_rbrace);
+    Diag(LBraceLoc, diag::note_matching) << "{";
+    return StmtError();
+  } else if (NumTokensRead == 0) {
+    // Empty __asm.
+    Diag(Tok, diag::err_expected_lbrace);
+    return StmtError();
+  }
+
+  // FIXME: We should be passing source locations for better diagnostics.
+  return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc,
+                                llvm::makeArrayRef(AsmToks), EndLoc);
 }
 
 /// ParseAsmStatement - Parse a GNU extended asm statement.
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 8cf1c29..653f6c2 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -623,6 +623,8 @@
     // declarator-id
     if (Tok.is(tok::annot_cxxscope))
       ConsumeToken();
+    else
+      TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
     ConsumeToken();
   } else if (Tok.is(tok::l_paren)) {
     ConsumeParen();
@@ -671,7 +673,7 @@
       // initializer that follows the declarator. Note that ctor-style
       // initializers are not possible in contexts where abstract declarators
       // are allowed.
-      if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*warnIfAmbiguous*/))
+      if (!mayBeAbstract && !isCXXFunctionDeclarator())
         break;
 
       // direct-declarator '(' parameter-declaration-clause ')'
@@ -824,6 +826,12 @@
   return TPResult::Ambiguous();
 }
 
+bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
+  return std::find(TentativelyDeclaredIdentifiers.begin(),
+                   TentativelyDeclaredIdentifiers.end(), II)
+      != TentativelyDeclaredIdentifiers.end();
+}
+
 /// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
 /// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
 /// be either a decl-specifier or a function-style cast, and TPResult::Error()
@@ -831,7 +839,10 @@
 ///
 /// If HasMissingTypename is provided, a name with a dependent scope specifier
 /// will be treated as ambiguous if the 'typename' keyword is missing. If this
-/// happens, *HasMissingTypename will be set to 'true'.
+/// happens, *HasMissingTypename will be set to 'true'. This will also be used
+/// as an indicator that undeclared identifiers (which will trigger a later
+/// parse error) should be treated as types. Returns TPResult::Ambiguous() in
+/// such cases.
 ///
 ///         decl-specifier:
 ///           storage-class-specifier
@@ -927,22 +938,64 @@
 Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
                                   bool *HasMissingTypename) {
   switch (Tok.getKind()) {
-  case tok::identifier:   // foo::bar
+  case tok::identifier: {
     // Check for need to substitute AltiVec __vector keyword
     // for "vector" identifier.
     if (TryAltiVecVectorToken())
       return TPResult::True();
-    // Fall through.
+
+    const Token &Next = NextToken();
+    // In 'foo bar', 'foo' is always a type name outside of Objective-C.
+    if (!getLangOpts().ObjC1 && Next.is(tok::identifier))
+      return TPResult::True();
+
+    if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
+      // Determine whether this is a valid expression. If not, we will hit
+      // a parse error one way or another. In that case, tell the caller that
+      // this is ambiguous. Typo-correct to type and expression keywords and
+      // to types and identifiers, in order to try to recover from errors.
+      CorrectionCandidateCallback TypoCorrection;
+      TypoCorrection.WantRemainingKeywords = false;
+      switch (TryAnnotateName(false /* no nested name specifier */,
+                              &TypoCorrection)) {
+      case ANK_Error:
+        return TPResult::Error();
+      case ANK_TentativeDecl:
+        return TPResult::False();
+      case ANK_TemplateName:
+        // A bare type template-name which can't be a template template
+        // argument is an error, and was probably intended to be a type.
+        return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
+      case ANK_Unresolved:
+        return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False();
+      case ANK_Success:
+        break;
+      }
+      assert(Tok.isNot(tok::identifier) &&
+             "TryAnnotateName succeeded without producing an annotation");
+    } else {
+      // This might possibly be a type with a dependent scope specifier and
+      // a missing 'typename' keyword. Don't use TryAnnotateName in this case,
+      // since it will annotate as a primary expression, and we want to use the
+      // "missing 'typename'" logic.
+      if (TryAnnotateTypeOrScopeToken())
+        return TPResult::Error();
+      // If annotation failed, assume it's a non-type.
+      // FIXME: If this happens due to an undeclared identifier, treat it as
+      // ambiguous.
+      if (Tok.is(tok::identifier))
+        return TPResult::False();
+    }
+
+    // We annotated this token as something. Recurse to handle whatever we got.
+    return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
+  }
+
   case tok::kw_typename:  // typename T::type
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
     if (TryAnnotateTypeOrScopeToken())
       return TPResult::Error();
-    if (Tok.is(tok::identifier)) {
-      const Token &Next = NextToken();
-      return (!getLangOpts().ObjC1 && Next.is(tok::identifier)) ?
-          TPResult::True() : TPResult::False();
-    }
     return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
 
   case tok::coloncolon: {    // ::foo::bar
@@ -1073,6 +1126,28 @@
             *HasMissingTypename = true;
             return TPResult::Ambiguous();
           }
+        } else {
+          // Try to resolve the name. If it doesn't exist, assume it was
+          // intended to name a type and keep disambiguating.
+          switch (TryAnnotateName(false /* SS is not dependent */)) {
+          case ANK_Error:
+            return TPResult::Error();
+          case ANK_TentativeDecl:
+            return TPResult::False();
+          case ANK_TemplateName:
+            // A bare type template-name which can't be a template template
+            // argument is an error, and was probably intended to be a type.
+            return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
+          case ANK_Unresolved:
+            return HasMissingTypename ? TPResult::Ambiguous()
+                                      : TPResult::False();
+          case ANK_Success:
+            // Annotated it, check again.
+            assert(Tok.isNot(tok::annot_cxxscope) ||
+                   NextToken().isNot(tok::identifier));
+            return isCXXDeclarationSpecifier(BracedCastResult,
+                                             HasMissingTypename);
+          }
         }
       }
       return TPResult::False();
@@ -1267,7 +1342,7 @@
 /// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
 ///         exception-specification[opt]
 ///
-bool Parser::isCXXFunctionDeclarator(bool warnIfAmbiguous) {
+bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
 
   // C++ 8.2p1:
   // The ambiguity arising from the similarity between a function-style cast and
@@ -1304,23 +1379,13 @@
     }
   }
 
-  SourceLocation TPLoc = Tok.getLocation();
   PA.Revert();
 
+  if (IsAmbiguous && TPR == TPResult::Ambiguous())
+    *IsAmbiguous = true;
+
   // In case of an error, let the declaration parsing code handle it.
-  if (TPR == TPResult::Error())
-    return true;
-
-  if (TPR == TPResult::Ambiguous()) {
-    // Function declarator has precedence over constructor-style initializer.
-    // Emit a warning just in case the author intended a variable definition.
-    if (warnIfAmbiguous)
-      Diag(Tok, diag::warn_parens_disambiguated_as_function_decl)
-        << SourceRange(Tok.getLocation(), TPLoc);
-    return true;
-  }
-
-  return TPR == TPResult::True();
+  return TPR != TPResult::False();
 }
 
 /// parameter-declaration-clause:
@@ -1344,7 +1409,7 @@
 Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration) {
 
   if (Tok.is(tok::r_paren))
-    return TPResult::True();
+    return TPResult::Ambiguous();
 
   //   parameter-declaration-list[opt] '...'[opt]
   //   parameter-declaration-list ',' '...'
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 7314228..bee802f 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -808,27 +808,6 @@
          Tok.is(tok::kw_try);          // X() try { ... }
 }
 
-/// \brief Determine whether the current token, if it occurs after a
-/// a function declarator, indicates the start of a function definition
-/// inside an objective-C class implementation and thus can be delay parsed. 
-bool Parser::isStartOfDelayParsedFunctionDefinition(
-                                       const ParsingDeclarator &Declarator) {
-  if (!CurParsedObjCImpl ||
-      !Declarator.isFunctionDeclarator())
-    return false;
-  if (Tok.is(tok::l_brace))   // int X() {}
-    return true;
-
-  // Handle K&R C argument lists: int X(f) int f; {}
-  if (!getLangOpts().CPlusPlus &&
-      Declarator.getFunctionTypeInfo().isKNRPrototype()) 
-    return isDeclarationSpecifier();
-  
-  return getLangOpts().CPlusPlus &&
-           (Tok.is(tok::colon) ||         // X() : Base() {} (used for ctors)
-            Tok.is(tok::kw_try));          // X() try { ... }
-}
-
 /// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
 /// a declaration.  We can't tell which we have until we read up to the
 /// compound-statement in function-definition. TemplateParams, if
@@ -1025,7 +1004,28 @@
     }
     return DP;
   }
-
+  else if (CurParsedObjCImpl && 
+           !TemplateInfo.TemplateParams &&
+           (Tok.is(tok::l_brace) || Tok.is(tok::kw_try) ||
+            Tok.is(tok::colon)) && 
+      Actions.CurContext->isTranslationUnit()) {
+    MultiTemplateParamsArg TemplateParameterLists(Actions, 0, 0);
+    ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
+    Scope *ParentScope = getCurScope()->getParent();
+    
+    D.setFunctionDefinitionKind(FDK_Definition);
+    Decl *FuncDecl = Actions.HandleDeclarator(ParentScope, D,
+                                        move(TemplateParameterLists));
+    D.complete(FuncDecl);
+    D.getMutableDeclSpec().abort();
+    if (FuncDecl) {
+      // Consume the tokens and store them for later parsing.
+      StashAwayMethodOrFunctionBodyTokens(FuncDecl);
+      CurParsedObjCImpl->HasCFunction = true;
+      return FuncDecl;
+    }
+  }
+      
   // Enter a scope for the function body.
   ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope);
 
@@ -1301,6 +1301,143 @@
   return Id;
 }
 
+void Parser::AnnotateScopeToken(CXXScopeSpec &SS, bool IsNewAnnotation) {
+  // Push the current token back into the token stream (or revert it if it is
+  // cached) and use an annotation scope token for current token.
+  if (PP.isBacktrackEnabled())
+    PP.RevertCachedTokens(1);
+  else
+    PP.EnterToken(Tok);
+  Tok.setKind(tok::annot_cxxscope);
+  Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS));
+  Tok.setAnnotationRange(SS.getRange());
+
+  // In case the tokens were cached, have Preprocessor replace them
+  // with the annotation token.  We don't need to do this if we've
+  // just reverted back to a prior state.
+  if (IsNewAnnotation)
+    PP.AnnotateCachedTokens(Tok);
+}
+
+/// \brief Attempt to classify the name at the current token position. This may
+/// form a type, scope or primary expression annotation, or replace the token
+/// with a typo-corrected keyword. This is only appropriate when the current
+/// name must refer to an entity which has already been declared.
+///
+/// \param IsAddressOfOperand Must be \c true if the name is preceded by an '&'
+///        and might possibly have a dependent nested name specifier.
+/// \param CCC Indicates how to perform typo-correction for this name. If NULL,
+///        no typo correction will be performed.
+Parser::AnnotatedNameKind
+Parser::TryAnnotateName(bool IsAddressOfOperand,
+                        CorrectionCandidateCallback *CCC) {
+  assert(Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope));
+
+  const bool EnteringContext = false;
+  const bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
+
+  CXXScopeSpec SS;
+  if (getLangOpts().CPlusPlus &&
+      ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
+    return ANK_Error;
+
+  if (Tok.isNot(tok::identifier) || SS.isInvalid()) {
+    if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, false, SS,
+                                                  !WasScopeAnnotation))
+      return ANK_Error;
+    return ANK_Unresolved;
+  }
+
+  IdentifierInfo *Name = Tok.getIdentifierInfo();
+  SourceLocation NameLoc = Tok.getLocation();
+
+  // FIXME: Move the tentative declaration logic into ClassifyName so we can
+  // typo-correct to tentatively-declared identifiers.
+  if (isTentativelyDeclared(Name)) {
+    // Identifier has been tentatively declared, and thus cannot be resolved as
+    // an expression. Fall back to annotating it as a type.
+    if (TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, false, SS,
+                                                  !WasScopeAnnotation))
+      return ANK_Error;
+    return Tok.is(tok::annot_typename) ? ANK_Success : ANK_TentativeDecl;
+  }
+
+  Token Next = NextToken();
+
+  // Look up and classify the identifier. We don't perform any typo-correction
+  // after a scope specifier, because in general we can't recover from typos
+  // there (eg, after correcting 'A::tempalte B<X>::C', we would need to jump
+  // back into scope specifier parsing).
+  Sema::NameClassification Classification
+    = Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next,
+                           IsAddressOfOperand, SS.isEmpty() ? CCC : 0);
+
+  switch (Classification.getKind()) {
+  case Sema::NC_Error:
+    return ANK_Error;
+
+  case Sema::NC_Keyword:
+    // The identifier was typo-corrected to a keyword.
+    Tok.setIdentifierInfo(Name);
+    Tok.setKind(Name->getTokenID());
+    PP.TypoCorrectToken(Tok);
+    if (SS.isNotEmpty())
+      AnnotateScopeToken(SS, !WasScopeAnnotation);
+    // We've "annotated" this as a keyword.
+    return ANK_Success;
+
+  case Sema::NC_Unknown:
+    // It's not something we know about. Leave it unannotated.
+    break;
+
+  case Sema::NC_Type:
+    Tok.setKind(tok::annot_typename);
+    setTypeAnnotation(Tok, Classification.getType());
+    Tok.setAnnotationEndLoc(NameLoc);
+    if (SS.isNotEmpty())
+      Tok.setLocation(SS.getBeginLoc());
+    PP.AnnotateCachedTokens(Tok);
+    return ANK_Success;
+
+  case Sema::NC_Expression:
+    Tok.setKind(tok::annot_primary_expr);
+    setExprAnnotation(Tok, Classification.getExpression());
+    Tok.setAnnotationEndLoc(NameLoc);
+    if (SS.isNotEmpty())
+      Tok.setLocation(SS.getBeginLoc());
+    PP.AnnotateCachedTokens(Tok);
+    return ANK_Success;
+
+  case Sema::NC_TypeTemplate:
+    if (Next.isNot(tok::less)) {
+      // This may be a type template being used as a template template argument.
+      if (SS.isNotEmpty())
+        AnnotateScopeToken(SS, !WasScopeAnnotation);
+      return ANK_TemplateName;
+    }
+    // Fall through.
+  case Sema::NC_FunctionTemplate: {
+    // We have a type or function template followed by '<'.
+    ConsumeToken();
+    UnqualifiedId Id;
+    Id.setIdentifier(Name, NameLoc);
+    if (AnnotateTemplateIdToken(
+            TemplateTy::make(Classification.getTemplateName()),
+            Classification.getTemplateNameKind(), SS, SourceLocation(), Id))
+      return ANK_Error;
+    return ANK_Success;
+  }
+
+  case Sema::NC_NestedNameSpecifier:
+    llvm_unreachable("already parsed nested name specifier");
+  }
+
+  // Unable to classify the name, but maybe we can annotate a scope specifier.
+  if (SS.isNotEmpty())
+    AnnotateScopeToken(SS, !WasScopeAnnotation);
+  return ANK_Unresolved;
+}
+
 /// 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
@@ -1404,13 +1541,24 @@
   }
 
   // Remembers whether the token was originally a scope annotation.
-  bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope);
+  bool WasScopeAnnotation = Tok.is(tok::annot_cxxscope);
 
   CXXScopeSpec SS;
   if (getLangOpts().CPlusPlus)
     if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext))
       return true;
 
+  return TryAnnotateTypeOrScopeTokenAfterScopeSpec(EnteringContext, NeedType,
+                                                   SS, !WasScopeAnnotation);
+}
+
+/// \brief Try to annotate a type or scope token, having already parsed an
+/// optional scope specifier. \p IsNewScope should be \c true unless the scope
+/// specifier was extracted from an existing tok::annot_cxxscope annotation.
+bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext,
+                                                       bool NeedType,
+                                                       CXXScopeSpec &SS,
+                                                       bool IsNewScope) {
   if (Tok.is(tok::identifier)) {
     IdentifierInfo *CorrectedII = 0;
     // Determine whether the identifier is a type name.
@@ -1492,21 +1640,7 @@
     return false;
 
   // A C++ scope specifier that isn't followed by a typename.
-  // Push the current token back into the token stream (or revert it if it is
-  // cached) and use an annotation scope token for current token.
-  if (PP.isBacktrackEnabled())
-    PP.RevertCachedTokens(1);
-  else
-    PP.EnterToken(Tok);
-  Tok.setKind(tok::annot_cxxscope);
-  Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS));
-  Tok.setAnnotationRange(SS.getRange());
-
-  // In case the tokens were cached, have Preprocessor replace them
-  // with the annotation token.  We don't need to do this if we've
-  // just reverted back to the state we were in before being called.
-  if (!wasScopeAnnotation)
-    PP.AnnotateCachedTokens(Tok);
+  AnnotateScopeToken(SS, IsNewScope);
   return false;
 }
 
@@ -1529,19 +1663,7 @@
   if (SS.isEmpty())
     return false;
 
-  // Push the current token back into the token stream (or revert it if it is
-  // cached) and use an annotation scope token for current token.
-  if (PP.isBacktrackEnabled())
-    PP.RevertCachedTokens(1);
-  else
-    PP.EnterToken(Tok);
-  Tok.setKind(tok::annot_cxxscope);
-  Tok.setAnnotationValue(Actions.SaveNestedNameSpecifierAnnotation(SS));
-  Tok.setAnnotationRange(SS.getRange());
-
-  // In case the tokens were cached, have Preprocessor replace them with the
-  // annotation token.
-  PP.AnnotateCachedTokens(Tok);
+  AnnotateScopeToken(SS, true);
   return false;
 }
 
diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h
index e13c4cf..455c4af 100644
--- a/lib/Parse/RAIIObjectsForParser.h
+++ b/lib/Parse/RAIIObjectsForParser.h
@@ -218,6 +218,28 @@
     }
   };
 
+  /// A class for parsing a field declarator.
+  class ParsingFieldDeclarator : public FieldDeclarator {
+    ParsingDeclRAIIObject ParsingRAII;
+
+  public:
+    ParsingFieldDeclarator(Parser &P, const ParsingDeclSpec &DS)
+      : FieldDeclarator(DS), ParsingRAII(P, &DS.getDelayedDiagnosticPool()) {
+    }
+
+    const ParsingDeclSpec &getDeclSpec() const {
+      return static_cast<const ParsingDeclSpec&>(D.getDeclSpec());
+    }
+
+    ParsingDeclSpec &getMutableDeclSpec() const {
+      return const_cast<ParsingDeclSpec&>(getDeclSpec());
+    }
+
+    void complete(Decl *D) {
+      ParsingRAII.complete(D);
+    }
+  };
+
   /// ExtensionRAIIObject - This saves the state of extension warnings when
   /// constructed and disables them.  When destructed, it restores them back to
   /// the way they used to be.  This is used to handle __extension__ in the
diff --git a/lib/Rewrite/CMakeLists.txt b/lib/Rewrite/CMakeLists.txt
index d8d90fa..af8f6d4 100644
--- a/lib/Rewrite/CMakeLists.txt
+++ b/lib/Rewrite/CMakeLists.txt
@@ -17,8 +17,11 @@
 add_dependencies(clangRewrite
   ClangAttrClasses
   ClangAttrList
+  ClangAttrParsedAttrList
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticCommon
+  ClangDiagnosticFrontend
   ClangStmtNodes
   )
 
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index e2da26f..236b98f 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -325,11 +325,12 @@
       " .msgControl { background-color:#bbbbbb; color:#000000 }\n"
       " .mrange { background-color:#dfddf3 }\n"
       " .mrange { border-bottom:1px solid #6F9DBE }\n"
-      " .PathIndex { font-weight: bold; padding:0px 5px 0px 5px; "
+      " .PathIndex { font-weight: bold; padding:0px 5px; "
         "margin-right:5px; }\n"
       " .PathIndex { -webkit-border-radius:8px }\n"
       " .PathIndexEvent { background-color:#bfba87 }\n"
       " .PathIndexControl { background-color:#8c8c8c }\n"
+      " .PathNav a { text-decoration:none; font-size: larger }\n"
       " .CodeInsertionHint { font-weight: bold; background-color: #10dd10 }\n"
       " .CodeRemovalHint { background-color:#de1010 }\n"
       " .CodeRemovalHint { border-bottom:1px solid #6F9DBE }\n"
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index 256984d..9c98a7f 100644
--- a/lib/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Rewrite/RewriteModernObjC.cpp
@@ -241,7 +241,7 @@
       // Get the new text.
       std::string SStr;
       llvm::raw_string_ostream S(SStr);
-      New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
+      New->printPretty(S, 0, PrintingPolicy(LangOpts));
       const std::string &Str = S.str();
 
       // If replacement succeeded or warning disabled return with no warning.
@@ -2549,8 +2549,7 @@
   // 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));
+  Exp->getString()->printPretty(prettyBuf, 0, PrintingPolicy(LangOpts));
   Preamble += prettyBuf.str();
   Preamble += ",";
   Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
@@ -3103,7 +3102,9 @@
   // build type for containing the objc_msgSend_stret object.
   static unsigned stretCount=0;
   std::string name = "__Stret"; name += utostr(stretCount);
-  std::string str = "struct "; str += name;
+  std::string str = 
+    "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
+  str += "struct "; str += name;
   str += " {\n\t";
   str += name;
   str += "(id receiver, SEL sel";
@@ -3139,7 +3140,14 @@
   str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
   str += " s;\n";
   str += "};\n\n";
-  SourceLocation FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+    FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
+  else {
+    assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+
   InsertText(FunLocStart, str);
   ++stretCount;
   
@@ -4339,7 +4347,7 @@
     std::string SStr;
   
     llvm::raw_string_ostream constructorExprBuf(SStr);
-    GlobalConstructionExp->printPretty(constructorExprBuf, *Context, 0,
+    GlobalConstructionExp->printPretty(constructorExprBuf, 0,
                                          PrintingPolicy(LangOpts));
     globalBuf += constructorExprBuf.str();
     globalBuf += ";\n";
@@ -5608,7 +5616,7 @@
     // Get the new text.
     std::string SStr;
     llvm::raw_string_ostream Buf(SStr);
-    Replacement->printPretty(Buf, *Context);
+    Replacement->printPretty(Buf);
     const std::string &Str = Buf.str();
 
     printf("CAST = %s\n", &Str[0]);
@@ -5959,11 +5967,6 @@
     Preamble += "#define __block\n";
     Preamble += "#define __weak\n";
   }
-  Preamble += "\n#if defined(_MSC_VER)\n";
-  Preamble += "#include <string.h>\n";
-  Preamble += "#else\n";
-  Preamble += "extern \"C\" void * memset(void *b, int c, unsigned long len);\n";
-  Preamble += "#endif\n";
   
   // Declarations required for modern objective-c array and dictionary literals.
   Preamble += "\n#include <stdarg.h>\n";
diff --git a/lib/Rewrite/RewriteObjC.cpp b/lib/Rewrite/RewriteObjC.cpp
index 425cd77..37c17e6 100644
--- a/lib/Rewrite/RewriteObjC.cpp
+++ b/lib/Rewrite/RewriteObjC.cpp
@@ -227,7 +227,7 @@
       // Get the new text.
       std::string SStr;
       llvm::raw_string_ostream S(SStr);
-      New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
+      New->printPretty(S, 0, PrintingPolicy(LangOpts));
       const std::string &Str = S.str();
 
       // If replacement succeeded or warning disabled return with no warning.
@@ -1720,8 +1720,7 @@
                                       CK, syncExpr);
   std::string syncExprBufS;
   llvm::raw_string_ostream syncExprBuf(syncExprBufS);
-  syncExpr->printPretty(syncExprBuf, *Context, 0,
-                        PrintingPolicy(LangOpts));
+  syncExpr->printPretty(syncExprBuf, 0, PrintingPolicy(LangOpts));
   syncBuf += syncExprBuf.str();
   syncBuf += ");";
   
@@ -2553,8 +2552,7 @@
   // 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));
+  Exp->getString()->printPretty(prettyBuf, 0, PrintingPolicy(LangOpts));
   Preamble += prettyBuf.str();
   Preamble += ",";
   Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
@@ -4885,7 +4883,7 @@
     // Get the new text.
     std::string SStr;
     llvm::raw_string_ostream Buf(SStr);
-    Replacement->printPretty(Buf, *Context);
+    Replacement->printPretty(Buf);
     const std::string &Str = Buf.str();
 
     printf("CAST = %s\n", &Str[0]);
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 19a7d6f..93be773 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -182,13 +182,6 @@
       HasFakeEdge = true;
       continue;
     }
-    if (const AsmStmt *AS = dyn_cast<AsmStmt>(S)) {
-      if (AS->isMSAsm()) {
-        HasFakeEdge = true;
-        HasLiveReturn = true;
-        continue;
-      }
-    }
     if (isa<MSAsmStmt>(S)) {
       // TODO: Verify this is correct.
       HasFakeEdge = true;
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index 0f209fd..7c79879 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -21,6 +21,8 @@
 
 size_t AttributeList::allocated_size() const {
   if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
+  else if (IsTypeTagForDatatype)
+    return AttributeFactory::TypeTagForDatatypeAllocSize;
   return (sizeof(AttributeList) + NumArgs * sizeof(Expr*));
 }
 
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 58cab5a..872ac89 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -1,3 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
+  support
+  mc
+  )
+
 add_clang_library(clangSema
   AnalysisBasedWarnings.cpp
   AttributeList.cpp
@@ -32,6 +39,7 @@
   SemaOverload.cpp
   SemaPseudoObject.cpp
   SemaStmt.cpp
+  SemaStmtAsm.cpp
   SemaStmtAttr.cpp
   SemaTemplate.cpp
   SemaTemplateDeduction.cpp
@@ -46,14 +54,17 @@
   ClangARMNeon
   ClangAttrClasses
   ClangAttrList
-  ClangDiagnosticComment
-  ClangDiagnosticSema
-  ClangCommentNodes
-  ClangDeclNodes
-  ClangStmtNodes
-  ClangAttrTemplateInstantiate
   ClangAttrParsedAttrList
   ClangAttrParsedAttrKinds
+  ClangAttrTemplateInstantiate
+  ClangCommentNodes
+  ClangDeclNodes
+  ClangDiagnosticAST
+  ClangDiagnosticComment
+  ClangDiagnosticCommon
+  ClangDiagnosticParse
+  ClangDiagnosticSema
+  ClangStmtNodes
   )
 
 target_link_libraries(clangSema
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index 3cce8cb..d12ca78 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -145,6 +145,7 @@
 /// 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,
+                                             bool isAmbiguous,
                                              SourceLocation EllipsisLoc,
                                              ParamInfo *ArgInfo,
                                              unsigned NumArgs,
@@ -173,6 +174,7 @@
   I.Fun.AttrList                = 0;
   I.Fun.hasPrototype            = hasProto;
   I.Fun.isVariadic              = isVariadic;
+  I.Fun.isAmbiguous             = isAmbiguous;
   I.Fun.EllipsisLoc             = EllipsisLoc.getRawEncoding();
   I.Fun.DeleteArgInfo           = false;
   I.Fun.TypeQuals               = TypeQuals;
@@ -668,9 +670,11 @@
 }
 
 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)
+                           unsigned &DiagID, const LangOptions &Lang,
+                           bool IsTypeSpec) {
+  // Duplicates are permitted in C99, and are permitted in C++11 unless the
+  // cv-qualifier appears as a type-specifier.
+  if ((TypeQualifiers & T) && !Lang.C99 && (!Lang.CPlusPlus0x || IsTypeSpec))
     return BadSpecifier(T, T, PrevSpec, DiagID);
   TypeQualifiers |= T;
 
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 0569a37..62c7375 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -97,8 +97,6 @@
     NSArrayDecl(0), ArrayWithObjectsMethod(0),
     NSDictionaryDecl(0), DictionaryWithObjectsMethod(0),
     GlobalNewDeleteDeclared(false), 
-    ObjCShouldCallSuperDealloc(false),
-    ObjCShouldCallSuperFinalize(false),
     TUKind(TUKind),
     NumSFINAEErrors(0), InFunctionDeclarator(0),
     AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
@@ -509,6 +507,11 @@
   assert(DelayedDiagnostics.getCurrentPool() == NULL
          && "reached end of translation unit with a pool attached?");
 
+  // If code completion is enabled, don't perform any end-of-translation-unit
+  // work.
+  if (PP.isCodeCompletionEnabled())
+    return;
+
   // Only complete translation units define vtables and perform implicit
   // instantiations.
   if (TUKind == TU_Complete) {
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index f71a388..3481171 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -1632,25 +1632,6 @@
   return CheckAccess(*this, UseLoc, AccessEntity);
 } 
 
-/// Checks direct (i.e. non-inherited) access to an arbitrary class
-/// member.
-Sema::AccessResult Sema::CheckDirectMemberAccess(SourceLocation UseLoc,
-                                                 NamedDecl *Target,
-                                           const PartialDiagnostic &Diag) {
-  AccessSpecifier Access = Target->getAccess();
-  if (!getLangOpts().AccessControl ||
-      Access == AS_public)
-    return AR_accessible;
-
-  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Target->getDeclContext());
-  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
-                      DeclAccessPair::make(Target, Access),
-                      QualType());
-  Entity.setDiag(Diag);
-  return CheckAccess(*this, UseLoc, Entity);
-}
-                                           
-
 /// Checks access to an overloaded operator new or delete.
 Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
                                                SourceRange PlacementRange,
@@ -1693,6 +1674,44 @@
   return CheckAccess(*this, OpLoc, Entity);
 }
 
+/// Checks access to the target of a friend declaration.
+Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
+  assert(isa<CXXMethodDecl>(target) ||
+         (isa<FunctionTemplateDecl>(target) &&
+          isa<CXXMethodDecl>(cast<FunctionTemplateDecl>(target)
+                               ->getTemplatedDecl())));
+
+  // Friendship lookup is a redeclaration lookup, so there's never an
+  // inheritance path modifying access.
+  AccessSpecifier access = target->getAccess();
+
+  if (!getLangOpts().AccessControl || access == AS_public)
+    return AR_accessible;
+
+  CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(target);
+  if (!method)
+    method = cast<CXXMethodDecl>(
+                     cast<FunctionTemplateDecl>(target)->getTemplatedDecl());
+  assert(method->getQualifier());
+
+  AccessTarget entity(Context, AccessTarget::Member,
+                      cast<CXXRecordDecl>(target->getDeclContext()),
+                      DeclAccessPair::make(target, access),
+                      /*no instance context*/ QualType());
+  entity.setDiag(diag::err_access_friend_function)
+    << method->getQualifierLoc().getSourceRange();
+
+  // We need to bypass delayed-diagnostics because we might be called
+  // while the ParsingDeclarator is active.
+  EffectiveContext EC(CurContext);
+  switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
+  case AR_accessible: return Sema::AR_accessible;
+  case AR_inaccessible: return Sema::AR_inaccessible;
+  case AR_dependent: return Sema::AR_dependent;
+  }
+  llvm_unreachable("falling off end");
+}
+
 Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
                                                     DeclAccessPair Found) {
   if (!getLangOpts().AccessControl ||
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 8199751..6c513b9 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -1477,6 +1477,21 @@
   Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;
 }
 
+static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr,
+                                  QualType DestType) {
+  QualType SrcType = SrcExpr.get()->getType();
+  if (const PointerType *SrcPtrTy = SrcType->getAs<PointerType>())
+    if (SrcPtrTy->isObjCSelType()) {
+      QualType DT = DestType;
+      if (isa<PointerType>(DestType))
+        DT = DestType->getPointeeType();
+      if (!DT.getUnqualifiedType()->isVoidType())
+        Self.Diag(SrcExpr.get()->getExprLoc(),
+                  diag::warn_cast_pointer_from_sel)
+        << SrcType << DestType << SrcExpr.get()->getSourceRange();
+    }
+}
+
 static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
                                         QualType DestType, bool CStyle,
                                         const SourceRange &OpRange,
@@ -1721,7 +1736,9 @@
   if (CStyle && DestType->isObjCObjectPointerType()) {
     return TC_Success;
   }
-    
+  if (CStyle)
+    DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
+  
   // Not casting away constness, so the only remaining check is for compatible
   // pointer categories.
 
@@ -1886,6 +1903,43 @@
     SrcExpr = ExprError();
 }
 
+/// DiagnoseBadFunctionCast - Warn whenever a function call is cast to a 
+///  non-matching type. Such as enum function call to int, int call to
+/// pointer; etc. Cast to 'void' is an exception.
+static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr,
+                                  QualType DestType) {
+  if (Self.Diags.getDiagnosticLevel(diag::warn_bad_function_cast,
+                                    SrcExpr.get()->getExprLoc()) 
+        == DiagnosticsEngine::Ignored)
+    return;
+  
+  if (!isa<CallExpr>(SrcExpr.get()))
+    return;
+  
+  QualType SrcType = SrcExpr.get()->getType();
+  if (DestType.getUnqualifiedType()->isVoidType())
+    return;
+  if ((SrcType->isAnyPointerType() || SrcType->isBlockPointerType())
+      && (DestType->isAnyPointerType() || DestType->isBlockPointerType()))
+    return;
+  if (SrcType->isIntegerType() && DestType->isIntegerType() &&
+      (SrcType->isBooleanType() == DestType->isBooleanType()) &&
+      (SrcType->isEnumeralType() == DestType->isEnumeralType()))
+    return;
+  if (SrcType->isRealFloatingType() && DestType->isRealFloatingType())
+    return;
+  if (SrcType->isEnumeralType() && DestType->isEnumeralType())
+    return;
+  if (SrcType->isComplexType() && DestType->isComplexType())
+    return;
+  if (SrcType->isComplexIntegerType() && DestType->isComplexIntegerType())
+    return;
+  
+  Self.Diag(SrcExpr.get()->getExprLoc(),
+            diag::warn_bad_function_cast)
+            << SrcType << DestType << SrcExpr.get()->getSourceRange();
+}
+
 /// Check the semantics of a C-style cast operation, in C.
 void CastOperation::CheckCStyleCast() {
   assert(!Self.getLangOpts().CPlusPlus);
@@ -2058,7 +2112,8 @@
       return;
     }
   }
-  
+  DiagnoseCastOfObjCSEL(Self, SrcExpr, DestType);
+  DiagnoseBadFunctionCast(Self, SrcExpr, DestType);
   Kind = Self.PrepareScalarCast(SrcExpr, DestType);
   if (SrcExpr.isInvalid())
     return;
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 73f9b01..2559f00 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -355,7 +355,7 @@
 bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   llvm::APSInt Result;
 
-  unsigned mask = 0;
+  uint64_t mask = 0;
   unsigned TV = 0;
   int PtrArgNum = -1;
   bool HasConstPtr = false;
@@ -373,7 +373,7 @@
       return true;
     
     TV = Result.getLimitedValue(64);
-    if ((TV > 63) || (mask & (1 << TV)) == 0)
+    if ((TV > 63) || (mask & (1ULL << TV)) == 0)
       return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code)
         << TheCall->getArg(ImmArg)->getSourceRange();
   }
@@ -513,6 +513,13 @@
          I = FDecl->specific_attr_begin<NonNullAttr>(),
          E = FDecl->specific_attr_end<NonNullAttr>(); I != E; ++I)
     CheckNonNullArguments(*I, Args, Loc);
+
+  // Type safety checking.
+  for (specific_attr_iterator<ArgumentWithTypeTagAttr>
+         i = FDecl->specific_attr_begin<ArgumentWithTypeTagAttr>(),
+         e = FDecl->specific_attr_end<ArgumentWithTypeTagAttr>(); i != e; ++i) {
+    CheckArgumentWithTypeTag(*i, Args);
+  }
 }
 
 /// CheckConstructorCall - Check a constructor call for correctness and safety
@@ -2271,7 +2278,7 @@
                          const analyze_printf::OptionalFlag &ignoredFlag,
                          const analyze_printf::OptionalFlag &flag,
                          const char *startSpecifier, unsigned specifierLen);
-  bool checkForCStrMembers(const analyze_printf::ArgTypeResult &ATR,
+  bool checkForCStrMembers(const analyze_printf::ArgType &AT,
                            const Expr *E, const CharSourceRange &CSR);
 
 };  
@@ -2320,12 +2327,12 @@
 
       QualType T = Arg->getType();
 
-      const analyze_printf::ArgTypeResult &ATR = Amt.getArgType(S.Context);
-      assert(ATR.isValid());
+      const analyze_printf::ArgType &AT = Amt.getArgType(S.Context);
+      assert(AT.isValid());
 
-      if (!ATR.matchesType(S.Context, T)) {
+      if (!AT.matchesType(S.Context, T)) {
         EmitFormatDiagnostic(S.PDiag(diag::warn_printf_asterisk_wrong_type)
-                               << k << ATR.getRepresentativeTypeName(S.Context)
+                               << k << AT.getRepresentativeTypeName(S.Context)
                                << T << Arg->getSourceRange(),
                              getLocationOfByte(Amt.getStart()),
                              /*IsStringLocation*/true,
@@ -2424,10 +2431,10 @@
 }
 
 // Check if a (w)string was passed when a (w)char* was needed, and offer a
-// better diagnostic if so. ATR is assumed to be valid.
+// better diagnostic if so. AT is assumed to be valid.
 // Returns true when a c_str() conversion method is found.
 bool CheckPrintfHandler::checkForCStrMembers(
-    const analyze_printf::ArgTypeResult &ATR, const Expr *E,
+    const analyze_printf::ArgType &AT, const Expr *E,
     const CharSourceRange &CSR) {
   typedef llvm::SmallPtrSet<CXXMethodDecl*, 1> MethodSet;
 
@@ -2438,7 +2445,7 @@
        MI != ME; ++MI) {
     const CXXMethodDecl *Method = *MI;
     if (Method->getNumParams() == 0 &&
-          ATR.matchesType(S.Context, Method->getResultType())) {
+          AT.matchesType(S.Context, Method->getResultType())) {
       // FIXME: Suggest parens if the expression needs them.
       SourceLocation EndLoc =
           S.getPreprocessor().getLocForEndOfToken(E->getLocEnd());
@@ -2561,17 +2568,6 @@
     HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
                                              specifierLen);
 
-  // Are we using '%n'?
-  if (CS.getKind() == ConversionSpecifier::nArg) {
-    // Issue a warning about this being a possible security issue.
-    EmitFormatDiagnostic(S.PDiag(diag::warn_printf_write_back),
-                         getLocationOfByte(CS.getStart()),
-                         /*IsStringLocation*/true,
-                         getSpecifierRange(startSpecifier, specifierLen));
-    // Continue checking the other format specifiers.
-    return true;
-  }
-
   // The remaining checks depend on the data arguments.
   if (HasVAListArg)
     return true;
@@ -2595,9 +2591,9 @@
   using namespace analyze_printf;
   // Now type check the data expression that matches the
   // format specifier.
-  const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context,
-                                                           ObjCContext);
-  if (ATR.isValid() && !ATR.matchesType(S.Context, E->getType())) {
+  const analyze_printf::ArgType &AT = FS.getArgType(S.Context,
+                                                    ObjCContext);
+  if (AT.isValid() && !AT.matchesType(S.Context, E->getType())) {
     // Look through argument promotions for our error message's reported type.
     // This includes the integral and floating promotions, but excludes array
     // and function pointer decay; seeing that an argument intended to be a
@@ -2613,7 +2609,7 @@
         if (ICE->getType() == S.Context.IntTy ||
             ICE->getType() == S.Context.UnsignedIntTy) {
           // All further checking is done on the subexpression.
-          if (ATR.matchesType(S.Context, E->getType()))
+          if (AT.matchesType(S.Context, E->getType()))
             return true;
         }
       }
@@ -2632,7 +2628,7 @@
 
       EmitFormatDiagnostic(
         S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << ATR.getRepresentativeTypeName(S.Context) << E->getType()
+          << AT.getRepresentativeTypeName(S.Context) << E->getType()
           << E->getSourceRange(),
         E->getLocStart(),
         /*IsStringLocation*/false,
@@ -2658,16 +2654,16 @@
             << S.getLangOpts().CPlusPlus0x
             << E->getType()
             << CallType
-            << ATR.getRepresentativeTypeName(S.Context)
+            << AT.getRepresentativeTypeName(S.Context)
             << CSR
             << E->getSourceRange(),
           E->getLocStart(), /*IsStringLocation*/false, CSR);
 
-        checkForCStrMembers(ATR, E, CSR);
+        checkForCStrMembers(AT, E, CSR);
       } else
         EmitFormatDiagnostic(
           S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-            << ATR.getRepresentativeTypeName(S.Context) << E->getType()
+            << AT.getRepresentativeTypeName(S.Context) << E->getType()
             << CSR
             << E->getSourceRange(),
           E->getLocStart(), /*IsStringLocation*/false, CSR);
@@ -2811,8 +2807,8 @@
   if (!Ex)
     return true;
 
-  const analyze_scanf::ScanfArgTypeResult &ATR = FS.getArgType(S.Context);
-  if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
+  const analyze_format_string::ArgType &AT = FS.getArgType(S.Context);
+  if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) {
     ScanfSpecifier fixedFS = FS;
     bool success = fixedFS.fixType(Ex->getType(), S.getLangOpts(),
                                    S.Context);
@@ -2825,7 +2821,7 @@
 
       EmitFormatDiagnostic(
         S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << ATR.getRepresentativeTypeName(S.Context) << Ex->getType()
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
           << Ex->getSourceRange(),
         Ex->getLocStart(),
         /*IsStringLocation*/false,
@@ -2836,7 +2832,7 @@
     } else {
       EmitFormatDiagnostic(
         S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
-          << ATR.getRepresentativeTypeName(S.Context) << Ex->getType()
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
           << Ex->getSourceRange(),
         Ex->getLocStart(),
         /*IsStringLocation*/false,
@@ -3112,6 +3108,19 @@
   return Ex;
 }
 
+static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty,
+                                                      ASTContext &Context) {
+  // Only handle constant-sized or VLAs, but not flexible members.
+  if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(Ty)) {
+    // Only issue the FIXIT for arrays of size > 1.
+    if (CAT->getSize().getSExtValue() <= 1)
+      return false;
+  } else if (!Ty->isVariableArrayType()) {
+    return false;
+  }
+  return true;
+}
+
 // Warn if the user has made the 'size' argument to strlcpy or strlcat
 // be the size of the source, instead of the destination.
 void Sema::CheckStrlcpycatArguments(const CallExpr *Call,
@@ -3162,21 +3171,13 @@
   // pointers if we know the actual size, like if DstArg is 'array+2'
   // we could say 'sizeof(array)-2'.
   const Expr *DstArg = Call->getArg(0)->IgnoreParenImpCasts();
-  QualType DstArgTy = DstArg->getType();
-  
-  // Only handle constant-sized or VLAs, but not flexible members.
-  if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(DstArgTy)) {
-    // Only issue the FIXIT for arrays of size > 1.
-    if (CAT->getSize().getSExtValue() <= 1)
-      return;
-  } else if (!DstArgTy->isVariableArrayType()) {
+  if (!isConstantSizeArrayWithMoreThanOneElement(DstArg->getType(), Context))
     return;
-  }
 
   SmallString<128> sizeString;
   llvm::raw_svector_ostream OS(sizeString);
   OS << "sizeof(";
-  DstArg->printPretty(OS, Context, 0, getPrintingPolicy());
+  DstArg->printPretty(OS, 0, getPrintingPolicy());
   OS << ")";
   
   Diag(OriginalSizeArg->getLocStart(), diag::note_strlcpycat_wrong_size)
@@ -3253,33 +3254,30 @@
                      SM.getSpellingLoc(SR.getEnd()));
   }
 
+  // Check if the destination is an array (rather than a pointer to an array).
+  QualType DstTy = DstArg->getType();
+  bool isKnownSizeArray = isConstantSizeArrayWithMoreThanOneElement(DstTy,
+                                                                    Context);
+  if (!isKnownSizeArray) {
+    if (PatternType == 1)
+      Diag(SL, diag::warn_strncat_wrong_size) << SR;
+    else
+      Diag(SL, diag::warn_strncat_src_size) << SR;
+    return;
+  }
+
   if (PatternType == 1)
     Diag(SL, diag::warn_strncat_large_size) << SR;
   else
     Diag(SL, diag::warn_strncat_src_size) << SR;
 
-  // Output a FIXIT hint if the destination is an array (rather than a
-  // pointer to an array).  This could be enhanced to handle some
-  // pointers if we know the actual size, like if DstArg is 'array+2'
-  // we could say 'sizeof(array)-2'.
-  QualType DstArgTy = DstArg->getType();
-
-  // Only handle constant-sized or VLAs, but not flexible members.
-  if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(DstArgTy)) {
-    // Only issue the FIXIT for arrays of size > 1.
-    if (CAT->getSize().getSExtValue() <= 1)
-      return;
-  } else if (!DstArgTy->isVariableArrayType()) {
-    return;
-  }
-
   SmallString<128> sizeString;
   llvm::raw_svector_ostream OS(sizeString);
   OS << "sizeof(";
-  DstArg->printPretty(OS, Context, 0, getPrintingPolicy());
+  DstArg->printPretty(OS, 0, getPrintingPolicy());
   OS << ") - ";
   OS << "strlen(";
-  DstArg->printPretty(OS, Context, 0, getPrintingPolicy());
+  DstArg->printPretty(OS, 0, getPrintingPolicy());
   OS << ") - 1";
 
   Diag(SL, diag::note_strncat_wrong_size)
@@ -4721,7 +4719,7 @@
 ///   conversion
 void Sema::CheckImplicitConversions(Expr *E, SourceLocation CC) {
   // Don't diagnose in unevaluated contexts.
-  if (ExprEvalContexts.back().Context == Sema::Unevaluated)
+  if (isUnevaluatedContext())
     return;
 
   // Don't diagnose for value- or type-dependent expressions.
@@ -5477,3 +5475,410 @@
     Diag(NBody->getSemiLoc(), diag::note_empty_body_on_separate_line);
   }
 }
+
+//===--- Layout compatibility ----------------------------------------------//
+
+namespace {
+
+bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2);
+
+/// \brief Check if two enumeration types are layout-compatible.
+bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) {
+  // C++11 [dcl.enum] p8:
+  // Two enumeration types are layout-compatible if they have the same
+  // underlying type.
+  return ED1->isComplete() && ED2->isComplete() &&
+         C.hasSameType(ED1->getIntegerType(), ED2->getIntegerType());
+}
+
+/// \brief Check if two fields are layout-compatible.
+bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1, FieldDecl *Field2) {
+  if (!isLayoutCompatible(C, Field1->getType(), Field2->getType()))
+    return false;
+
+  if (Field1->isBitField() != Field2->isBitField())
+    return false;
+
+  if (Field1->isBitField()) {
+    // Make sure that the bit-fields are the same length.
+    unsigned Bits1 = Field1->getBitWidthValue(C);
+    unsigned Bits2 = Field2->getBitWidthValue(C);
+
+    if (Bits1 != Bits2)
+      return false;
+  }
+
+  return true;
+}
+
+/// \brief Check if two standard-layout structs are layout-compatible.
+/// (C++11 [class.mem] p17)
+bool isLayoutCompatibleStruct(ASTContext &C,
+                              RecordDecl *RD1,
+                              RecordDecl *RD2) {
+  // If both records are C++ classes, check that base classes match.
+  if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) {
+    // If one of records is a CXXRecordDecl we are in C++ mode,
+    // thus the other one is a CXXRecordDecl, too.
+    const CXXRecordDecl *D2CXX = cast<CXXRecordDecl>(RD2);
+    // Check number of base classes.
+    if (D1CXX->getNumBases() != D2CXX->getNumBases())
+      return false;
+
+    // Check the base classes.
+    for (CXXRecordDecl::base_class_const_iterator
+               Base1 = D1CXX->bases_begin(),
+           BaseEnd1 = D1CXX->bases_end(),
+              Base2 = D2CXX->bases_begin();
+         Base1 != BaseEnd1;
+         ++Base1, ++Base2) {
+      if (!isLayoutCompatible(C, Base1->getType(), Base2->getType()))
+        return false;
+    }
+  } else if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) {
+    // If only RD2 is a C++ class, it should have zero base classes.
+    if (D2CXX->getNumBases() > 0)
+      return false;
+  }
+
+  // Check the fields.
+  RecordDecl::field_iterator Field2 = RD2->field_begin(),
+                             Field2End = RD2->field_end(),
+                             Field1 = RD1->field_begin(),
+                             Field1End = RD1->field_end();
+  for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) {
+    if (!isLayoutCompatible(C, *Field1, *Field2))
+      return false;
+  }
+  if (Field1 != Field1End || Field2 != Field2End)
+    return false;
+
+  return true;
+}
+
+/// \brief Check if two standard-layout unions are layout-compatible.
+/// (C++11 [class.mem] p18)
+bool isLayoutCompatibleUnion(ASTContext &C,
+                             RecordDecl *RD1,
+                             RecordDecl *RD2) {
+  llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields;
+  for (RecordDecl::field_iterator Field2 = RD2->field_begin(),
+                                  Field2End = RD2->field_end();
+       Field2 != Field2End; ++Field2) {
+    UnmatchedFields.insert(*Field2);
+  }
+
+  for (RecordDecl::field_iterator Field1 = RD1->field_begin(),
+                                  Field1End = RD1->field_end();
+       Field1 != Field1End; ++Field1) {
+    llvm::SmallPtrSet<FieldDecl *, 8>::iterator
+        I = UnmatchedFields.begin(),
+        E = UnmatchedFields.end();
+
+    for ( ; I != E; ++I) {
+      if (isLayoutCompatible(C, *Field1, *I)) {
+        bool Result = UnmatchedFields.erase(*I);
+        (void) Result;
+        assert(Result);
+        break;
+      }
+    }
+    if (I == E)
+      return false;
+  }
+
+  return UnmatchedFields.empty();
+}
+
+bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1, RecordDecl *RD2) {
+  if (RD1->isUnion() != RD2->isUnion())
+    return false;
+
+  if (RD1->isUnion())
+    return isLayoutCompatibleUnion(C, RD1, RD2);
+  else
+    return isLayoutCompatibleStruct(C, RD1, RD2);
+}
+
+/// \brief Check if two types are layout-compatible in C++11 sense.
+bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) {
+  if (T1.isNull() || T2.isNull())
+    return false;
+
+  // C++11 [basic.types] p11:
+  // If two types T1 and T2 are the same type, then T1 and T2 are
+  // layout-compatible types.
+  if (C.hasSameType(T1, T2))
+    return true;
+
+  T1 = T1.getCanonicalType().getUnqualifiedType();
+  T2 = T2.getCanonicalType().getUnqualifiedType();
+
+  const Type::TypeClass TC1 = T1->getTypeClass();
+  const Type::TypeClass TC2 = T2->getTypeClass();
+
+  if (TC1 != TC2)
+    return false;
+
+  if (TC1 == Type::Enum) {
+    return isLayoutCompatible(C,
+                              cast<EnumType>(T1)->getDecl(),
+                              cast<EnumType>(T2)->getDecl());
+  } else if (TC1 == Type::Record) {
+    if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType())
+      return false;
+
+    return isLayoutCompatible(C,
+                              cast<RecordType>(T1)->getDecl(),
+                              cast<RecordType>(T2)->getDecl());
+  }
+
+  return false;
+}
+}
+
+//===--- CHECK: pointer_with_type_tag attribute: datatypes should match ----//
+
+namespace {
+/// \brief Given a type tag expression find the type tag itself.
+///
+/// \param TypeExpr Type tag expression, as it appears in user's code.
+///
+/// \param VD Declaration of an identifier that appears in a type tag.
+///
+/// \param MagicValue Type tag magic value.
+bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx,
+                     const ValueDecl **VD, uint64_t *MagicValue) {
+  while(true) {
+    if (!TypeExpr)
+      return false;
+
+    TypeExpr = TypeExpr->IgnoreParenImpCasts()->IgnoreParenCasts();
+
+    switch (TypeExpr->getStmtClass()) {
+    case Stmt::UnaryOperatorClass: {
+      const UnaryOperator *UO = cast<UnaryOperator>(TypeExpr);
+      if (UO->getOpcode() == UO_AddrOf || UO->getOpcode() == UO_Deref) {
+        TypeExpr = UO->getSubExpr();
+        continue;
+      }
+      return false;
+    }
+
+    case Stmt::DeclRefExprClass: {
+      const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
+      *VD = DRE->getDecl();
+      return true;
+    }
+
+    case Stmt::IntegerLiteralClass: {
+      const IntegerLiteral *IL = cast<IntegerLiteral>(TypeExpr);
+      llvm::APInt MagicValueAPInt = IL->getValue();
+      if (MagicValueAPInt.getActiveBits() <= 64) {
+        *MagicValue = MagicValueAPInt.getZExtValue();
+        return true;
+      } else
+        return false;
+    }
+
+    case Stmt::BinaryConditionalOperatorClass:
+    case Stmt::ConditionalOperatorClass: {
+      const AbstractConditionalOperator *ACO =
+          cast<AbstractConditionalOperator>(TypeExpr);
+      bool Result;
+      if (ACO->getCond()->EvaluateAsBooleanCondition(Result, Ctx)) {
+        if (Result)
+          TypeExpr = ACO->getTrueExpr();
+        else
+          TypeExpr = ACO->getFalseExpr();
+        continue;
+      }
+      return false;
+    }
+
+    case Stmt::BinaryOperatorClass: {
+      const BinaryOperator *BO = cast<BinaryOperator>(TypeExpr);
+      if (BO->getOpcode() == BO_Comma) {
+        TypeExpr = BO->getRHS();
+        continue;
+      }
+      return false;
+    }
+
+    default:
+      return false;
+    }
+  }
+}
+
+/// \brief Retrieve the C type corresponding to type tag TypeExpr.
+///
+/// \param TypeExpr Expression that specifies a type tag.
+///
+/// \param MagicValues Registered magic values.
+///
+/// \param FoundWrongKind Set to true if a type tag was found, but of a wrong
+///        kind.
+///
+/// \param TypeInfo Information about the corresponding C type.
+///
+/// \returns true if the corresponding C type was found.
+bool GetMatchingCType(
+        const IdentifierInfo *ArgumentKind,
+        const Expr *TypeExpr, const ASTContext &Ctx,
+        const llvm::DenseMap<Sema::TypeTagMagicValue,
+                             Sema::TypeTagData> *MagicValues,
+        bool &FoundWrongKind,
+        Sema::TypeTagData &TypeInfo) {
+  FoundWrongKind = false;
+
+  // Variable declaration that has type_tag_for_datatype attribute.
+  const ValueDecl *VD = NULL;
+
+  uint64_t MagicValue;
+
+  if (!FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue))
+    return false;
+
+  if (VD) {
+    for (specific_attr_iterator<TypeTagForDatatypeAttr>
+             I = VD->specific_attr_begin<TypeTagForDatatypeAttr>(),
+             E = VD->specific_attr_end<TypeTagForDatatypeAttr>();
+         I != E; ++I) {
+      if (I->getArgumentKind() != ArgumentKind) {
+        FoundWrongKind = true;
+        return false;
+      }
+      TypeInfo.Type = I->getMatchingCType();
+      TypeInfo.LayoutCompatible = I->getLayoutCompatible();
+      TypeInfo.MustBeNull = I->getMustBeNull();
+      return true;
+    }
+    return false;
+  }
+
+  if (!MagicValues)
+    return false;
+
+  llvm::DenseMap<Sema::TypeTagMagicValue,
+                 Sema::TypeTagData>::const_iterator I =
+      MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
+  if (I == MagicValues->end())
+    return false;
+
+  TypeInfo = I->second;
+  return true;
+}
+} // unnamed namespace
+
+void Sema::RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind,
+                                      uint64_t MagicValue, QualType Type,
+                                      bool LayoutCompatible,
+                                      bool MustBeNull) {
+  if (!TypeTagForDatatypeMagicValues)
+    TypeTagForDatatypeMagicValues.reset(
+        new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
+
+  TypeTagMagicValue Magic(ArgumentKind, MagicValue);
+  (*TypeTagForDatatypeMagicValues)[Magic] =
+      TypeTagData(Type, LayoutCompatible, MustBeNull);
+}
+
+namespace {
+bool IsSameCharType(QualType T1, QualType T2) {
+  const BuiltinType *BT1 = T1->getAs<BuiltinType>();
+  if (!BT1)
+    return false;
+
+  const BuiltinType *BT2 = T2->getAs<BuiltinType>();
+  if (!BT2)
+    return false;
+
+  BuiltinType::Kind T1Kind = BT1->getKind();
+  BuiltinType::Kind T2Kind = BT2->getKind();
+
+  return (T1Kind == BuiltinType::SChar  && T2Kind == BuiltinType::Char_S) ||
+         (T1Kind == BuiltinType::UChar  && T2Kind == BuiltinType::Char_U) ||
+         (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
+         (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
+}
+} // unnamed namespace
+
+void Sema::CheckArgumentWithTypeTag(const ArgumentWithTypeTagAttr *Attr,
+                                    const Expr * const *ExprArgs) {
+  const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
+  bool IsPointerAttr = Attr->getIsPointer();
+
+  const Expr *TypeTagExpr = ExprArgs[Attr->getTypeTagIdx()];
+  bool FoundWrongKind;
+  TypeTagData TypeInfo;
+  if (!GetMatchingCType(ArgumentKind, TypeTagExpr, Context,
+                        TypeTagForDatatypeMagicValues.get(),
+                        FoundWrongKind, TypeInfo)) {
+    if (FoundWrongKind)
+      Diag(TypeTagExpr->getExprLoc(),
+           diag::warn_type_tag_for_datatype_wrong_kind)
+        << TypeTagExpr->getSourceRange();
+    return;
+  }
+
+  const Expr *ArgumentExpr = ExprArgs[Attr->getArgumentIdx()];
+  if (IsPointerAttr) {
+    // Skip implicit cast of pointer to `void *' (as a function argument).
+    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
+      if (ICE->getType()->isVoidPointerType())
+        ArgumentExpr = ICE->getSubExpr();
+  }
+  QualType ArgumentType = ArgumentExpr->getType();
+
+  // Passing a `void*' pointer shouldn't trigger a warning.
+  if (IsPointerAttr && ArgumentType->isVoidPointerType())
+    return;
+
+  if (TypeInfo.MustBeNull) {
+    // Type tag with matching void type requires a null pointer.
+    if (!ArgumentExpr->isNullPointerConstant(Context,
+                                             Expr::NPC_ValueDependentIsNotNull)) {
+      Diag(ArgumentExpr->getExprLoc(),
+           diag::warn_type_safety_null_pointer_required)
+          << ArgumentKind->getName()
+          << ArgumentExpr->getSourceRange()
+          << TypeTagExpr->getSourceRange();
+    }
+    return;
+  }
+
+  QualType RequiredType = TypeInfo.Type;
+  if (IsPointerAttr)
+    RequiredType = Context.getPointerType(RequiredType);
+
+  bool mismatch = false;
+  if (!TypeInfo.LayoutCompatible) {
+    mismatch = !Context.hasSameType(ArgumentType, RequiredType);
+
+    // C++11 [basic.fundamental] p1:
+    // Plain char, signed char, and unsigned char are three distinct types.
+    //
+    // But we treat plain `char' as equivalent to `signed char' or `unsigned
+    // char' depending on the current char signedness mode.
+    if (mismatch)
+      if ((IsPointerAttr && IsSameCharType(ArgumentType->getPointeeType(),
+                                           RequiredType->getPointeeType())) ||
+          (!IsPointerAttr && IsSameCharType(ArgumentType, RequiredType)))
+        mismatch = false;
+  } else
+    if (IsPointerAttr)
+      mismatch = !isLayoutCompatible(Context,
+                                     ArgumentType->getPointeeType(),
+                                     RequiredType->getPointeeType());
+    else
+      mismatch = !isLayoutCompatible(Context, ArgumentType, RequiredType);
+
+  if (mismatch)
+    Diag(ArgumentExpr->getExprLoc(), diag::warn_type_safety_type_mismatch)
+        << ArgumentType << ArgumentKind->getName()
+        << TypeInfo.LayoutCompatible << RequiredType
+        << ArgumentExpr->getSourceRange()
+        << TypeTagExpr->getSourceRange();
+}
+
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index bb08405..6c140ac 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2369,11 +2369,11 @@
 
   // Handle multiple qualifiers.
   std::string QualsStr;
-  if (Proto->getTypeQuals() & Qualifiers::Const)
+  if (Proto->isConst())
     QualsStr += " const";
-  if (Proto->getTypeQuals() & Qualifiers::Volatile)
+  if (Proto->isVolatile())
     QualsStr += " volatile";
-  if (Proto->getTypeQuals() & Qualifiers::Restrict)
+  if (Proto->isRestrict())
     QualsStr += " restrict";
   Result.AddInformativeChunk(Result.getAllocator().CopyString(QualsStr));
 }
@@ -2543,7 +2543,7 @@
 
   if (IncludeBriefComments) {
     // Add documentation comment, if it exists.
-    if (const RawComment *RC = Ctx.getRawCommentForDecl(ND)) {
+    if (const RawComment *RC = Ctx.getRawCommentForAnyRedecl(ND)) {
       Result.addBriefComment(RC->getBriefText(Ctx));
     }
   }
@@ -4476,7 +4476,6 @@
   Builder.AddResultTypeChunk("NSDictionary *");
   Builder.AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,"{"));
   Builder.AddPlaceholderChunk("key");
-  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddChunk(CodeCompletionString::CK_Colon);
   Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Builder.AddPlaceholderChunk("object, ...");
@@ -4596,26 +4595,23 @@
   
   // Check for collisions with "readonly".
   if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
-      (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
-                     ObjCDeclSpec::DQ_PR_assign |
-                     ObjCDeclSpec::DQ_PR_unsafe_unretained |
-                     ObjCDeclSpec::DQ_PR_copy |
-                     ObjCDeclSpec::DQ_PR_retain |
-                     ObjCDeclSpec::DQ_PR_strong)))
+      (Attributes & ObjCDeclSpec::DQ_PR_readwrite))
     return true;
   
-  // Check for more than one of { assign, copy, retain, strong }.
+  // Check for more than one of { assign, copy, retain, strong, weak }.
   unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
                                          ObjCDeclSpec::DQ_PR_unsafe_unretained |
                                              ObjCDeclSpec::DQ_PR_copy |
-                                             ObjCDeclSpec::DQ_PR_retain|
-                                             ObjCDeclSpec::DQ_PR_strong);
+                                             ObjCDeclSpec::DQ_PR_retain |
+                                             ObjCDeclSpec::DQ_PR_strong |
+                                             ObjCDeclSpec::DQ_PR_weak);
   if (AssignCopyRetMask &&
       AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
       AssignCopyRetMask != ObjCDeclSpec::DQ_PR_unsafe_unretained &&
       AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
       AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain &&
-      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong)
+      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_strong &&
+      AssignCopyRetMask != ObjCDeclSpec::DQ_PR_weak)
     return true;
   
   return false;
@@ -4651,6 +4647,12 @@
     Results.AddResult(CodeCompletionResult("nonatomic"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_atomic))
     Results.AddResult(CodeCompletionResult("atomic"));
+
+  // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC.
+  if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC)
+    if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak))
+      Results.AddResult(CodeCompletionResult("weak"));
+
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
     CodeCompletionBuilder Setter(Results.getAllocator(),
                                  Results.getCodeCompletionTUInfo());
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 52aa5b7..cd6a60b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -562,11 +562,28 @@
   return false;
 }
 
+/// Build a ParsedType for a simple-type-specifier with a nested-name-specifier.
+static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS,
+                                  QualType T, SourceLocation NameLoc) {
+  ASTContext &Context = S.Context;
+
+  TypeLocBuilder Builder;
+  Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+
+  T = S.getElaboratedType(ETK_None, SS, T);
+  ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+  ElabTL.setElaboratedKeywordLoc(SourceLocation());
+  ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
+  return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+}
+
 Sema::NameClassification Sema::ClassifyName(Scope *S,
                                             CXXScopeSpec &SS,
                                             IdentifierInfo *&Name,
                                             SourceLocation NameLoc,
-                                            const Token &NextToken) {
+                                            const Token &NextToken,
+                                            bool IsAddressOfOperand,
+                                            CorrectionCandidateCallback *CCC) {
   DeclarationNameInfo NameInfo(Name, NameLoc);
   ObjCMethodDecl *CurMethod = getCurMethodDecl();
   
@@ -632,25 +649,11 @@
 
     // Perform typo correction to determine if there is another name that is
     // close to this name.
-    if (!SecondTry) {
+    if (!SecondTry && CCC) {
       SecondTry = true;
-      CorrectionCandidateCallback DefaultValidator;
-      // Try to limit which sets of keywords should be included in typo
-      // correction based on what the next token is.
-      DefaultValidator.WantTypeSpecifiers =
-          NextToken.is(tok::l_paren) || NextToken.is(tok::less) ||
-          NextToken.is(tok::identifier) || NextToken.is(tok::star) ||
-          NextToken.is(tok::amp) || NextToken.is(tok::l_square);
-      DefaultValidator.WantExpressionKeywords =
-          NextToken.is(tok::l_paren) || NextToken.is(tok::identifier) ||
-          NextToken.is(tok::arrow) || NextToken.is(tok::period);
-      DefaultValidator.WantRemainingKeywords =
-          NextToken.is(tok::l_paren) || NextToken.is(tok::semi) ||
-          NextToken.is(tok::identifier) || NextToken.is(tok::l_brace);
-      DefaultValidator.WantCXXNamedCasts = false;
       if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
                                                  Result.getLookupKind(), S, 
-                                                 &SS, DefaultValidator)) {
+                                                 &SS, *CCC)) {
         unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
         unsigned QualifiedDiag = diag::err_no_member_suggest;
         std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
@@ -731,8 +734,9 @@
     // perform some heroics to see if we actually have a 
     // template-argument-list, which would indicate a missing 'template'
     // keyword here.
-    return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(),
-                                     NameInfo, /*TemplateArgs=*/0);
+    return ActOnDependentIdExpression(SS, /*TemplateKWLoc=*/SourceLocation(),
+                                      NameInfo, IsAddressOfOperand,
+                                      /*TemplateArgs=*/0);
   }
 
   case LookupResult::Found:
@@ -808,14 +812,16 @@
       return NameClassification::TypeTemplate(Template);
     }
   }
-  
+
   NamedDecl *FirstDecl = (*Result.begin())->getUnderlyingDecl();
   if (TypeDecl *Type = dyn_cast<TypeDecl>(FirstDecl)) {
     DiagnoseUseOfDecl(Type, NameLoc);
     QualType T = Context.getTypeDeclType(Type);
+    if (SS.isNotEmpty())
+      return buildNestedType(*this, SS, T, NameLoc);
     return ParsedType::make(T);
   }
-  
+
   ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(FirstDecl);
   if (!Class) {
     // FIXME: It's unfortunate that we don't have a Type node for handling this.
@@ -838,10 +844,14 @@
     return ParsedType::make(T);
   }
 
+  // We can have a type template here if we're classifying a template argument.
+  if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl))
+    return NameClassification::TypeTemplate(
+        TemplateName(cast<TemplateDecl>(FirstDecl)));
+
   // Check for a tag type hidden by a non-type decl in a few cases where it
   // seems likely a type is wanted instead of the non-type that was found.
-  if (!getLangOpts().ObjC1 && FirstDecl && !isa<ClassTemplateDecl>(FirstDecl) &&
-      !isa<TypeAliasTemplateDecl>(FirstDecl)) {
+  if (!getLangOpts().ObjC1) {
     bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star);
     if ((NextToken.is(tok::identifier) ||
          (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) &&
@@ -850,12 +860,14 @@
       if (TypeDecl *Type = dyn_cast<TypeDecl>(FirstDecl)) {
         DiagnoseUseOfDecl(Type, NameLoc);
         QualType T = Context.getTypeDeclType(Type);
+        if (SS.isNotEmpty())
+          return buildNestedType(*this, SS, T, NameLoc);
         return ParsedType::make(T);
       }
     }
   }
   
-  if (!Result.empty() && (*Result.begin())->isCXXClassMember())
+  if (FirstDecl->isCXXClassMember())
     return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0);
 
   bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren));
@@ -4655,11 +4667,6 @@
   return false;
 }
 
-static bool hasDelayedExceptionSpec(CXXMethodDecl *Method) {
-  const FunctionProtoType *Proto =Method->getType()->getAs<FunctionProtoType>();
-  return Proto && Proto->getExceptionSpecType() == EST_Delayed;
-}
-
 /// AddOverriddenMethods - See if a method overrides any in the base classes,
 /// and if so, check that it's a valid override and remember it.
 bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
@@ -4675,8 +4682,7 @@
       if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
         MD->addOverriddenMethod(OldMD->getCanonicalDecl());
         if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
-            (hasDelayedExceptionSpec(MD) ||
-             !CheckOverridingFunctionExceptionSpec(MD, OldMD)) &&
+            !CheckOverridingFunctionExceptionSpec(MD, OldMD) &&
             !CheckIfOverriddenFunctionIsMarkedFinal(MD, OldMD)) {
           AddedAny = true;
         }
@@ -4858,7 +4864,7 @@
 
   bool NewFDisConst = false;
   if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD))
-    NewFDisConst = NewMD->getTypeQualifiers() & Qualifiers::Const;
+    NewFDisConst = NewMD->isConst();
 
   for (llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1>::iterator
        NearMatch = NearMatches.begin(), NearMatchEnd = NearMatches.end();
@@ -4866,7 +4872,7 @@
     FunctionDecl *FD = NearMatch->first;
     bool FDisConst = false;
     if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
-      FDisConst = MD->getTypeQualifiers() & Qualifiers::Const;
+      FDisConst = MD->isConst();
 
     if (unsigned Idx = NearMatch->second) {
       ParmVarDecl *FDParam = FD->getParamDecl(Idx-1);
@@ -5251,58 +5257,6 @@
         FunctionTemplate->setInvalidDecl();
     }
 
-    // If we see "T var();" at block scope, where T is a class type, it is
-    // probably an attempt to initialize a variable, not a function declaration.
-    // We don't catch this case earlier, since there is no ambiguity here.
-    if (!FunctionTemplate && D.getFunctionDefinitionKind() == FDK_Declaration &&
-        CurContext->isFunctionOrMethod() &&
-        D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() &&
-        D.getDeclSpec().getStorageClassSpecAsWritten()
-          == DeclSpec::SCS_unspecified) {
-      QualType T = R->getAs<FunctionType>()->getResultType();
-      DeclaratorChunk &C = D.getTypeObject(0);
-      if (!T->isVoidType() && C.Fun.NumArgs == 0 && !C.Fun.isVariadic &&
-          !C.Fun.hasTrailingReturnType() &&
-          C.Fun.getExceptionSpecType() == EST_None) {
-        SourceRange ParenRange(C.Loc, C.EndLoc);
-        Diag(C.Loc, diag::warn_empty_parens_are_function_decl) << ParenRange;
-
-        // If the declaration looks like:
-        //   T var1,
-        //   f();
-        // and name lookup finds a function named 'f', then the ',' was
-        // probably intended to be a ';'.
-        if (!D.isFirstDeclarator() && D.getIdentifier()) {
-          FullSourceLoc Comma(D.getCommaLoc(), SourceMgr);
-          FullSourceLoc Name(D.getIdentifierLoc(), SourceMgr);
-          if (Comma.getFileID() != Name.getFileID() ||
-              Comma.getSpellingLineNumber() != Name.getSpellingLineNumber()) {
-            LookupResult Result(*this, D.getIdentifier(), SourceLocation(),
-                                LookupOrdinaryName);
-            if (LookupName(Result, S))
-              Diag(D.getCommaLoc(), diag::note_empty_parens_function_call)
-                << FixItHint::CreateReplacement(D.getCommaLoc(), ";") << NewFD;
-          }
-        }
-        const CXXRecordDecl *RD = T->getAsCXXRecordDecl();
-        // Empty parens mean value-initialization, and no parens mean default
-        // initialization. These are equivalent if the default constructor is
-        // user-provided, or if zero-initialization is a no-op.
-        if (RD && RD->hasDefinition() &&
-            (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor()))
-          Diag(C.Loc, diag::note_empty_parens_default_ctor)
-            << FixItHint::CreateRemoval(ParenRange);
-        else {
-          std::string Init = getFixItZeroInitializerForType(T);
-          if (Init.empty() && LangOpts.CPlusPlus0x)
-            Init = "{}";
-          if (!Init.empty())
-            Diag(C.Loc, diag::note_empty_parens_zero_initialize)
-              << FixItHint::CreateReplacement(ParenRange, Init);
-        }
-      }
-    }
-
     // C++ [dcl.fct.spec]p5:
     //   The virtual specifier shall only be used in declarations of
     //   nonstatic class member functions that appear within a
@@ -6086,10 +6040,12 @@
     // compatible, and if it does, warn the user.
     if (NewFD->isExternC()) {
       QualType R = NewFD->getResultType();
-      if (!R.isPODType(Context) && 
-          !R->isVoidType())
-        Diag( NewFD->getLocation(), diag::warn_return_value_udt ) 
-          << NewFD << R;
+      if (R->isIncompleteType() && !R->isVoidType())
+        Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete)
+            << NewFD << R;
+      else if (!R.isPODType(Context) && !R->isVoidType() &&
+               !R->isObjCObjectPointerType())
+        Diag(NewFD->getLocation(), diag::warn_return_value_udt) << NewFD << R;
     }
   }
   return Redeclaration;
@@ -6230,6 +6186,7 @@
     Decl *OrigDecl;
     bool isRecordType;
     bool isPODType;
+    bool isReferenceType;
 
   public:
     typedef EvaluatedExprVisitor<SelfReferenceChecker> Inherited;
@@ -6238,9 +6195,11 @@
                                                     S(S), OrigDecl(OrigDecl) {
       isPODType = false;
       isRecordType = false;
+      isReferenceType = false;
       if (ValueDecl *VD = dyn_cast<ValueDecl>(OrigDecl)) {
         isPODType = VD->getType().isPODType(S.Context);
         isRecordType = VD->getType()->isRecordType();
+        isReferenceType = VD->getType()->isReferenceType();
       }
     }
 
@@ -6248,9 +6207,9 @@
     // to determine which DeclRefExpr's to check.  Assume that the casts
     // are present and continue visiting the expression.
     void HandleExpr(Expr *E) {
-      // Skip checking T a = a where T is not a record type.  Doing so is a
-      // way to silence uninitialized warnings.
-      if (isRecordType)
+      // Skip checking T a = a where T is not a record or reference type.
+      // Doing so is a way to silence uninitialized warnings.
+      if (isRecordType || isReferenceType)
         if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
           HandleDeclRefExpr(DRE);
 
@@ -6316,8 +6275,11 @@
       if (OrigDecl != ReferenceDecl) return;
       LookupResult Result(S, DRE->getNameInfo(), Sema::LookupOrdinaryName,
                           Sema::NotForRedeclaration);
+      unsigned diag = isReferenceType
+          ? diag::warn_uninit_self_reference_in_reference_init
+          : diag::warn_uninit_self_reference_in_init;
       S.DiagRuntimeBehavior(DRE->getLocStart(), DRE,
-                            S.PDiag(diag::warn_uninit_self_reference_in_init)
+                            S.PDiag(diag)
                               << Result.getLookupName()
                               << OrigDecl->getLocation()
                               << DRE->getSourceRange());
@@ -6365,9 +6327,12 @@
   }
 
   // Check for self-references within variable initializers.
-  // Variables declared within a function/method body are handled
-  // by a dataflow analysis.
-  if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal())
+  // Variables declared within a function/method body (except for references)
+  // are handled by a dataflow analysis.
+  // Record types initialized by initializer list are handled here.
+  // Initialization by constructors are handled in TryConstructorInitialization.
+  if ((!VDecl->hasLocalStorage() || VDecl->getType()->isReferenceType()) &&
+      (isa<InitListExpr>(Init) || !VDecl->getType()->isRecordType()))
     CheckSelfReference(RealDecl, Init);
 
   ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
@@ -6807,6 +6772,12 @@
                                  diag::err_abstract_type_in_decl,
                                  AbstractVariableType))
         Var->setInvalidDecl();
+      if (!Type->isDependentType() && !Var->isInvalidDecl() &&
+          Var->getStorageClass() == SC_PrivateExtern) {
+        Diag(Var->getLocation(), diag::warn_private_extern);
+        Diag(Var->getLocation(), diag::note_private_extern);
+      }
+        
       return;
 
     case VarDecl::TentativeDefinition:
@@ -7080,6 +7051,42 @@
 Sema::FinalizeDeclaration(Decl *ThisDecl) {
   // Note that we are no longer parsing the initializer for this declaration.
   ParsingInitForAutoVars.erase(ThisDecl);
+
+  // Now we have parsed the initializer and can update the table of magic
+  // tag values.
+  if (ThisDecl && ThisDecl->hasAttr<TypeTagForDatatypeAttr>()) {
+    const VarDecl *VD = dyn_cast<VarDecl>(ThisDecl);
+    if (VD && VD->getType()->isIntegralOrEnumerationType()) {
+      for (specific_attr_iterator<TypeTagForDatatypeAttr>
+               I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(),
+               E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>();
+           I != E; ++I) {
+        const Expr *MagicValueExpr = VD->getInit();
+        if (!MagicValueExpr) {
+          continue;
+        }
+        llvm::APSInt MagicValueInt;
+        if (!MagicValueExpr->isIntegerConstantExpr(MagicValueInt, Context)) {
+          Diag(I->getRange().getBegin(),
+               diag::err_type_tag_for_datatype_not_ice)
+            << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange();
+          continue;
+        }
+        if (MagicValueInt.getActiveBits() > 64) {
+          Diag(I->getRange().getBegin(),
+               diag::err_type_tag_for_datatype_too_large)
+            << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange();
+          continue;
+        }
+        uint64_t MagicValue = MagicValueInt.getZExtValue();
+        RegisterTypeTagForDatatype(I->getArgumentKind(),
+                                   MagicValue,
+                                   I->getMatchingCType(),
+                                   I->getLayoutCompatible(),
+                                   I->getMustBeNull());
+      }
+    }
+  }
 }
 
 Sema::DeclGroupPtrTy
@@ -7508,6 +7515,10 @@
   if (FD->isFunctionTemplateSpecialization())
     return false;
 
+  // Don't warn for OpenCL kernels.
+  if (FD->hasAttr<OpenCLKernelAttr>())
+    return false;
+  
   bool MissingPrototype = true;
   for (const FunctionDecl *Prev = FD->getPreviousDecl();
        Prev; Prev = Prev->getPreviousDecl()) {
@@ -7536,6 +7547,7 @@
     else
       Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
     Diag(Definition->getLocation(), diag::note_previous_definition);
+    FD->setInvalidDecl();
   }
 }
 
@@ -7671,6 +7683,9 @@
         << FD->getName() << "dllimport";
     }
   }
+  // We want to attach documentation to original Decl (which might be
+  // a function template).
+  ActOnDocumentableDecl(D);
   return FD;
 }
 
@@ -7767,22 +7782,24 @@
       if (Body)
         computeNRVO(Body, getCurFunction());
     }
-    if (ObjCShouldCallSuperDealloc) {
+    if (getCurFunction()->ObjCShouldCallSuperDealloc) {
       Diag(MD->getLocEnd(), diag::warn_objc_missing_super_dealloc);
-      ObjCShouldCallSuperDealloc = false;
+      getCurFunction()->ObjCShouldCallSuperDealloc = false;
     }
-    if (ObjCShouldCallSuperFinalize) {
+    if (getCurFunction()->ObjCShouldCallSuperFinalize) {
       Diag(MD->getLocEnd(), diag::warn_objc_missing_super_finalize);
-      ObjCShouldCallSuperFinalize = false;
+      getCurFunction()->ObjCShouldCallSuperFinalize = false;
     }
   } else {
     return 0;
   }
 
-  assert(!ObjCShouldCallSuperDealloc && "This should only be set for "
-         "ObjC methods, which should have been handled in the block above.");
-  assert(!ObjCShouldCallSuperFinalize && "This should only be set for "
-         "ObjC methods, which should have been handled in the block above.");
+  assert(!getCurFunction()->ObjCShouldCallSuperDealloc &&
+         "This should only be set for ObjC methods, which should have been "
+         "handled in the block above.");
+  assert(!getCurFunction()->ObjCShouldCallSuperFinalize &&
+         "This should only be set for ObjC methods, which should have been "
+         "handled in the block above.");
 
   // Verify and clean out per-function state.
   if (Body) {
@@ -7795,7 +7812,8 @@
     // Verify that gotos and switch cases don't jump into scopes illegally.
     if (getCurFunction()->NeedsScopeChecking() &&
         !dcl->isInvalidDecl() &&
-        !hasAnyUnrecoverableErrorsInThisFunction())
+        !hasAnyUnrecoverableErrorsInThisFunction() &&
+        !PP.isCodeCompletionEnabled())
       DiagnoseInvalidJumps(Body);
 
     if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl)) {
@@ -7916,10 +7934,10 @@
   (void)Error; // Silence warning.
   assert(!Error && "Error setting up implicit decl!");
   Declarator D(DS, Declarator::BlockContext);
-  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
-                                             0, 0, true, SourceLocation(),
+  D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, false,
+                                             SourceLocation(), 0, 0, 0, true, 
                                              SourceLocation(), SourceLocation(),
-                                             SourceLocation(),
+                                             SourceLocation(), SourceLocation(),
                                              EST_None, SourceLocation(),
                                              0, 0, 0, 0, Loc, Loc, D),
                 DS.getAttributes(),
@@ -8019,6 +8037,13 @@
                                              "printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
   }
+
+  if (Name->isStr("__CFStringMakeConstantString")) {
+    // We already have a __builtin___CFStringMakeConstantString,
+    // but builds that use -fno-constant-cfstrings don't go through that.
+    if (!FD->getAttr<FormatArgAttr>())
+      FD->addAttr(::new (Context) FormatArgAttr(FD->getLocation(), Context, 1));
+  }
 }
 
 TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
@@ -8852,9 +8877,10 @@
     // many points during the parsing of a struct declaration (because
     // the #pragma tokens are effectively skipped over during the
     // parsing of the struct).
-    AddAlignmentAttributesForRecord(RD);
-    
-    AddMsStructLayoutForRecord(RD);
+    if (TUK == TUK_Definition) {
+      AddAlignmentAttributesForRecord(RD);
+      AddMsStructLayoutForRecord(RD);
+    }
   }
 
   if (ModulePrivateLoc.isValid()) {
@@ -9514,10 +9540,9 @@
 
   case CXXCopyAssignment:
     if (RD->hasUserDeclaredCopyAssignment()) {
-      // FIXME: this should use the location of the copy
-      // assignment, not the type.
-      SourceLocation TyLoc = RD->getLocStart();
-      Diag(TyLoc, diag::note_nontrivial_user_defined) << QT << member;
+      SourceLocation AssignLoc =
+        RD->getCopyAssignmentOperator(0)->getLocation();
+      Diag(AssignLoc, diag::note_nontrivial_user_defined) << QT << member;
       return;
     }
     break;
@@ -9797,11 +9822,6 @@
                        AttributeList *Attr) {
   assert(EnclosingDecl && "missing record or interface decl");
 
-  // If the decl this is being inserted into is invalid, then it may be a
-  // redeclaration or some other bogus case.  Don't try to add fields to it.
-  if (EnclosingDecl->isInvalidDecl())
-    return;
-
   // If this is an Objective-C @implementation or category and we have
   // new fields here we should reset the layout of the interface since
   // it will now change.
@@ -9950,6 +9970,13 @@
           }
         }
       }
+      if (isa<ObjCContainerDecl>(EnclosingDecl) &&
+          RequireNonAbstractType(FD->getLocation(), FD->getType(),
+                                 diag::err_abstract_type_in_decl,
+                                 AbstractIvarType)) {
+        // Ivars can not have abstract class types
+        FD->setInvalidDecl();
+      }
       if (Record && FDTTy->getDecl()->hasObjectMember())
         Record->setHasObjectMember(true);
     } else if (FDTy->isObjCObjectType()) {
@@ -9958,8 +9985,7 @@
         << FixItHint::CreateInsertion(FD->getLocation(), "*");
       QualType T = Context.getObjCObjectPointerType(FD->getType());
       FD->setType(T);
-    } 
-    else if (!getLangOpts().CPlusPlus) {
+    } else if (!getLangOpts().CPlusPlus) {
       if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported) {
         // It's an error in ARC if a field has lifetime.
         // We don't want to report this in a system header, though,
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index a8783d6..dfac771 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -221,6 +221,53 @@
   return true;
 }
 
+/// \brief Check if IdxExpr is a valid argument index for a function or
+/// instance method D.  May output an error.
+///
+/// \returns true if IdxExpr is a valid index.
+static bool checkFunctionOrMethodArgumentIndex(Sema &S, const Decl *D,
+                                               StringRef AttrName,
+                                               SourceLocation AttrLoc,
+                                               unsigned AttrArgNum,
+                                               const Expr *IdxExpr,
+                                               uint64_t &Idx)
+{
+  assert(isFunctionOrMethod(D) && hasFunctionProto(D));
+
+  // In C++ the implicit 'this' function parameter also counts.
+  // Parameters are counted from one.
+  const bool HasImplicitThisParam = isInstanceMethod(D);
+  const unsigned NumArgs = getFunctionOrMethodNumArgs(D) + HasImplicitThisParam;
+  const unsigned FirstIdx = 1;
+
+  llvm::APSInt IdxInt;
+  if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
+      !IdxExpr->isIntegerConstantExpr(IdxInt, S.Context)) {
+    S.Diag(AttrLoc, diag::err_attribute_argument_n_not_int)
+      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
+    return false;
+  }
+
+  Idx = IdxInt.getLimitedValue();
+  if (Idx < FirstIdx || (!isFunctionOrMethodVariadic(D) && Idx > NumArgs)) {
+    S.Diag(AttrLoc, diag::err_attribute_argument_out_of_bounds)
+      << AttrName << AttrArgNum << IdxExpr->getSourceRange();
+    return false;
+  }
+  Idx--; // Convert to zero-based.
+  if (HasImplicitThisParam) {
+    if (Idx == 0) {
+      S.Diag(AttrLoc,
+             diag::err_attribute_invalid_implicit_this_argument)
+        << AttrName << IdxExpr->getSourceRange();
+      return false;
+    }
+    --Idx;
+  }
+
+  return true;
+}
+
 ///
 /// \brief Check if passed in Decl is a field or potentially shared global var
 /// \return true if the Decl is a field or potentially shared global variable
@@ -3531,25 +3578,16 @@
     D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
     return;
   case AttributeList::AT_Pcs: {
-    Expr *Arg = Attr.getArg(0);
-    StringLiteral *Str = dyn_cast<StringLiteral>(Arg);
-    if (!Str || !Str->isAscii()) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
-        << "pcs" << 1;
-      Attr.setInvalid();
-      return;
-    }
-
-    StringRef StrRef = Str->getString();
     PcsAttr::PCSType PCS;
-    if (StrRef == "aapcs")
+    switch (CC) {
+    case CC_AAPCS:
       PCS = PcsAttr::AAPCS;
-    else if (StrRef == "aapcs-vfp")
+      break;
+    case CC_AAPCS_VFP:
       PCS = PcsAttr::AAPCS_VFP;
-    else {
-      S.Diag(Attr.getLoc(), diag::err_invalid_pcs);
-      Attr.setInvalid();
-      return;
+      break;
+    default:
+      llvm_unreachable("unexpected calling convention in pcs attribute");
     }
 
     D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
@@ -3568,10 +3606,9 @@
   if (attr.isInvalid())
     return true;
 
-  if ((attr.getNumArgs() != 0 &&
-      !(attr.getKind() == AttributeList::AT_Pcs && attr.getNumArgs() == 1)) ||
-      attr.getParameterName()) {
-    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
+  unsigned ReqArgs = attr.getKind() == AttributeList::AT_Pcs ? 1 : 0;
+  if (attr.getNumArgs() != ReqArgs || attr.getParameterName()) {
+    Diag(attr.getLoc(), diag::err_attribute_wrong_number_arguments) << ReqArgs;
     attr.setInvalid();
     return true;
   }
@@ -3602,7 +3639,10 @@
       CC = CC_AAPCS_VFP;
       break;
     }
-    // FALLS THROUGH
+
+    attr.setInvalid();
+    Diag(attr.getLoc(), diag::err_invalid_pcs);
+    return true;
   }
   default: llvm_unreachable("unexpected attribute kind");
   }
@@ -3711,6 +3751,79 @@
   }
 }
 
+static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
+                                          const AttributeList &Attr) {
+  StringRef AttrName = Attr.getName()->getName();
+  if (!Attr.getParameterName()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
+      << Attr.getName() << /* arg num = */ 1;
+    return;
+  }
+
+  if (Attr.getNumArgs() != 2) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << /* required args = */ 3;
+    return;
+  }
+
+  IdentifierInfo *ArgumentKind = Attr.getParameterName();
+
+  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << ExpectedFunctionOrMethod;
+    return;
+  }
+
+  uint64_t ArgumentIdx;
+  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
+                                          Attr.getLoc(), 2,
+                                          Attr.getArg(0), ArgumentIdx))
+    return;
+
+  uint64_t TypeTagIdx;
+  if (!checkFunctionOrMethodArgumentIndex(S, D, AttrName,
+                                          Attr.getLoc(), 3,
+                                          Attr.getArg(1), TypeTagIdx))
+    return;
+
+  bool IsPointer = (AttrName == "pointer_with_type_tag");
+  if (IsPointer) {
+    // Ensure that buffer has a pointer type.
+    QualType BufferTy = getFunctionOrMethodArgType(D, ArgumentIdx);
+    if (!BufferTy->isPointerType()) {
+      S.Diag(Attr.getLoc(), diag::err_attribute_pointers_only)
+        << AttrName;
+    }
+  }
+
+  D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(Attr.getRange(),
+                                                       S.Context,
+                                                       ArgumentKind,
+                                                       ArgumentIdx,
+                                                       TypeTagIdx,
+                                                       IsPointer));
+}
+
+static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
+                                         const AttributeList &Attr) {
+  IdentifierInfo *PointerKind = Attr.getParameterName();
+  if (!PointerKind) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_identifier)
+      << "type_tag_for_datatype" << 1;
+    return;
+  }
+
+  QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
+
+  D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
+                                  Attr.getRange(),
+                                  S.Context,
+                                  PointerKind,
+                                  MatchingCType,
+                                  Attr.getLayoutCompatible(),
+                                  Attr.getMustBeNull()));
+}
+
 //===----------------------------------------------------------------------===//
 // Checker-specific attribute handlers.
 //===----------------------------------------------------------------------===//
@@ -4343,6 +4456,14 @@
     handleAcquiredAfterAttr(S, D, Attr);
     break;
 
+  // Type safety attributes.
+  case AttributeList::AT_ArgumentWithTypeTag:
+    handleArgumentWithTypeTagAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_TypeTagForDatatype:
+    handleTypeTagForDatatypeAttr(S, D, Attr);
+    break;
+
   default:
     // Ask target about the attribute.
     const TargetAttributesSema &TargetAttrs = S.getTargetAttributesSema();
@@ -4660,24 +4781,36 @@
   return false;
 }
 
+static void
+DoEmitDeprecationWarning(Sema &S, const NamedDecl *D, StringRef Message,
+                         SourceLocation Loc,
+                         const ObjCInterfaceDecl *UnknownObjCClass) {
+  DeclarationName Name = D->getDeclName();
+  if (!Message.empty()) {
+    S.Diag(Loc, diag::warn_deprecated_message) << Name << Message;
+    S.Diag(D->getLocation(),
+           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
+                                  : diag::note_previous_decl) << Name;
+  } else if (!UnknownObjCClass) {
+    S.Diag(Loc, diag::warn_deprecated) << D->getDeclName();
+    S.Diag(D->getLocation(),
+           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
+                                  : diag::note_previous_decl) << Name;
+  } else {
+    S.Diag(Loc, diag::warn_deprecated_fwdclass_message) << Name;
+    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
+  }
+}
+
 void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
                                          Decl *Ctx) {
   if (isDeclDeprecated(Ctx))
     return;
 
   DD.Triggered = true;
-  if (!DD.getDeprecationMessage().empty())
-    Diag(DD.Loc, diag::warn_deprecated_message)
-      << DD.getDeprecationDecl()->getDeclName()
-      << DD.getDeprecationMessage();
-  else if (DD.getUnknownObjCClass()) {
-    Diag(DD.Loc, diag::warn_deprecated_fwdclass_message)
-      << DD.getDeprecationDecl()->getDeclName();
-    Diag(DD.getUnknownObjCClass()->getLocation(), diag::note_forward_class);
-  }
-  else
-    Diag(DD.Loc, diag::warn_deprecated)
-      << DD.getDeprecationDecl()->getDeclName();
+  DoEmitDeprecationWarning(*this, DD.getDeprecationDecl(),
+                           DD.getDeprecationMessage(), DD.Loc,
+                           DD.getUnknownObjCClass());
 }
 
 void Sema::EmitDeprecationWarning(NamedDecl *D, StringRef Message,
@@ -4694,23 +4827,5 @@
   // Otherwise, don't warn if our current context is deprecated.
   if (isDeclDeprecated(cast<Decl>(getCurLexicalContext())))
     return;
-  if (!Message.empty()) {
-    Diag(Loc, diag::warn_deprecated_message) << D->getDeclName()
-                                             << Message;
-    Diag(D->getLocation(),
-         isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
-                                : diag::note_previous_decl) << D->getDeclName();
-  }
-  else {
-    if (!UnknownObjCClass) {
-      Diag(Loc, diag::warn_deprecated) << D->getDeclName();
-      Diag(D->getLocation(),
-           isa<ObjCMethodDecl>(D) ? diag::note_method_declared_at
-                                  : diag::note_previous_decl) << D->getDeclName();
-    }
-    else {
-      Diag(Loc, diag::warn_deprecated_fwdclass_message) << D->getDeclName();
-      Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);
-    }
-  }
+  DoEmitDeprecationWarning(*this, D, Message, Loc, UnknownObjCClass);
 }
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 1480c2e..2d3f2c0 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -128,8 +128,8 @@
 
 void Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc,
                                                       CXXMethodDecl *Method) {
-  // If we have an MSAny or unknown spec already, don't bother.
-  if (!Method || ComputedEST == EST_MSAny || ComputedEST == EST_Delayed)
+  // If we have an MSAny spec already, don't bother.
+  if (!Method || ComputedEST == EST_MSAny)
     return;
 
   const FunctionProtoType *Proto
@@ -141,7 +141,7 @@
   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
 
   // If this function can throw any exceptions, make a note of that.
-  if (EST == EST_Delayed || EST == EST_MSAny || EST == EST_None) {
+  if (EST == EST_MSAny || EST == EST_None) {
     ClearExceptions();
     ComputedEST = EST;
     return;
@@ -198,7 +198,7 @@
 }
 
 void Sema::ImplicitExceptionSpecification::CalledExpr(Expr *E) {
-  if (!E || ComputedEST == EST_MSAny || ComputedEST == EST_Delayed)
+  if (!E || ComputedEST == EST_MSAny)
     return;
 
   // FIXME:
@@ -1405,32 +1405,50 @@
   return ProcessAccessDeclAttributeList(ASDecl, Attrs);
 }
 
-/// CheckOverrideControl - Check C++0x override control semantics.
-void Sema::CheckOverrideControl(const Decl *D) {
+/// CheckOverrideControl - Check C++11 override control semantics.
+void Sema::CheckOverrideControl(Decl *D) {
   const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D);
-  if (!MD || !MD->isVirtual())
-    return;
 
-  if (MD->isDependentContext())
-    return;
+  // Do we know which functions this declaration might be overriding?
+  bool OverridesAreKnown = !MD ||
+      (!MD->getParent()->hasAnyDependentBases() &&
+       !MD->getType()->isDependentType());
 
-  // C++0x [class.virtual]p3:
-  //   If a virtual function is marked with the virt-specifier override and does
-  //   not override a member function of a base class, 
-  //   the program is ill-formed.
-  bool HasOverriddenMethods = 
-    MD->begin_overridden_methods() != MD->end_overridden_methods();
-  if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods) {
-    Diag(MD->getLocation(), 
-                 diag::err_function_marked_override_not_overriding)
-      << MD->getDeclName();
+  if (!MD || !MD->isVirtual()) {
+    if (OverridesAreKnown) {
+      if (OverrideAttr *OA = D->getAttr<OverrideAttr>()) {
+        Diag(OA->getLocation(),
+             diag::override_keyword_only_allowed_on_virtual_member_functions)
+          << "override" << FixItHint::CreateRemoval(OA->getLocation());
+        D->dropAttr<OverrideAttr>();
+      }
+      if (FinalAttr *FA = D->getAttr<FinalAttr>()) {
+        Diag(FA->getLocation(),
+             diag::override_keyword_only_allowed_on_virtual_member_functions)
+          << "final" << FixItHint::CreateRemoval(FA->getLocation());
+        D->dropAttr<FinalAttr>();
+      }
+    }
     return;
   }
+
+  if (!OverridesAreKnown)
+    return;
+
+  // C++11 [class.virtual]p5:
+  //   If a virtual function is marked with the virt-specifier override and
+  //   does not override a member function of a base class, the program is
+  //   ill-formed.
+  bool HasOverriddenMethods =
+    MD->begin_overridden_methods() != MD->end_overridden_methods();
+  if (MD->hasAttr<OverrideAttr>() && !HasOverriddenMethods)
+    Diag(MD->getLocation(), diag::err_function_marked_override_not_overriding)
+      << MD->getDeclName();
 }
 
-/// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member 
+/// CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member
 /// function overrides a virtual member function marked 'final', according to
-/// C++0x [class.virtual]p3.
+/// C++11 [class.virtual]p4.
 bool Sema::CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New,
                                                   const CXXMethodDecl *Old) {
   if (!Old->hasAttr<FinalAttr>())
@@ -1443,13 +1461,12 @@
 }
 
 static bool InitializationHasSideEffects(const FieldDecl &FD) {
-  if (!FD.getType().isNull()) {
-    if (const CXXRecordDecl *RD = FD.getType()->getAsCXXRecordDecl()) {
-      return !RD->isCompleteDefinition() ||
-             !RD->hasTrivialDefaultConstructor() ||
-             !RD->hasTrivialDestructor();
-    }
-  }
+  const Type *T = FD.getType()->getBaseElementTypeUnsafe();
+  // FIXME: Destruction of ObjC lifetime types has side-effects.
+  if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
+    return !RD->isCompleteDefinition() ||
+           !RD->hasTrivialDefaultConstructor() ||
+           !RD->hasTrivialDestructor();
   return false;
 }
 
@@ -1609,31 +1626,17 @@
       FunTmpl->getTemplatedDecl()->setAccess(AS);
   }
 
-  if (VS.isOverrideSpecified()) {
-    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
-    if (!MD || !MD->isVirtual()) {
-      Diag(Member->getLocStart(), 
-           diag::override_keyword_only_allowed_on_virtual_member_functions)
-        << "override" << FixItHint::CreateRemoval(VS.getOverrideLoc());
-    } else
-      MD->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context));
-  }
-  if (VS.isFinalSpecified()) {
-    CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member);
-    if (!MD || !MD->isVirtual()) {
-      Diag(Member->getLocStart(), 
-           diag::override_keyword_only_allowed_on_virtual_member_functions)
-      << "final" << FixItHint::CreateRemoval(VS.getFinalLoc());
-    } else
-      MD->addAttr(new (Context) FinalAttr(VS.getFinalLoc(), Context));
-  }
+  if (VS.isOverrideSpecified())
+    Member->addAttr(new (Context) OverrideAttr(VS.getOverrideLoc(), Context));
+  if (VS.isFinalSpecified())
+    Member->addAttr(new (Context) FinalAttr(VS.getFinalLoc(), Context));
 
   if (VS.getLastLocation().isValid()) {
     // Update the end location of a method that has a virt-specifiers.
     if (CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Member))
       MD->setRangeEnd(VS.getLastLocation());
   }
-      
+
   CheckOverrideControl(Member);
 
   assert((Name || isInstField) && "No identifier for non-field ?");
@@ -1650,7 +1653,7 @@
       if (!FD->isImplicit() && FD->getDeclName() &&
           FD->getAccess() == AS_private &&
           !FD->hasAttr<UnusedAttr>() &&
-          !FD->getParent()->getTypeForDecl()->isDependentType() &&
+          !FD->getParent()->isDependentContext() &&
           !InitializationHasSideEffects(*FD))
         UnusedPrivateFields.insert(FD);
     }
@@ -2077,7 +2080,10 @@
         }
 
         if (VD == ME->getMemberDecl() && isa<CXXThisExpr>(Base)) {
-          S.Diag(ME->getExprLoc(), diag::warn_field_is_uninit);
+          unsigned diag = VD->getType()->isReferenceType()
+              ? diag::warn_reference_field_is_uninit
+              : diag::warn_field_is_uninit;
+          S.Diag(ME->getExprLoc(), diag);
           return;
         }
       }
@@ -2160,24 +2166,6 @@
     NumArgs = InitList->getNumInits();
   }
 
-  // Mark FieldDecl as being used if it is a non-primitive type and the
-  // initializer does not call the default constructor (which is trivial
-  // for all entries in UnusedPrivateFields).
-  // FIXME: Make this smarter once more side effect-free types can be
-  // determined.
-  if (NumArgs > 0) {
-    if (Member->getType()->isRecordType()) {
-      UnusedPrivateFields.remove(Member);
-    } else {
-      for (unsigned i = 0; i < NumArgs; ++i) {
-        if (Args[i]->HasSideEffects(Context)) {
-          UnusedPrivateFields.remove(Member);
-          break;
-        }
-      }
-    }
-  }
-
   if (getDiagnostics().getDiagnosticLevel(diag::warn_field_is_uninit, IdLoc)
         != DiagnosticsEngine::Ignored)
     for (unsigned i = 0; i < NumArgs; ++i)
@@ -2821,6 +2809,16 @@
 
     llvm_unreachable("Invalid ImplicitInitializerKind!");
   }
+
+  bool addFieldInitializer(CXXCtorInitializer *Init) {
+    AllToInit.push_back(Init);
+
+    // Check whether this initializer makes the field "used".
+    if (Init->getInit() && Init->getInit()->HasSideEffects(S.Context))
+      S.UnusedPrivateFields.remove(Init->getAnyMember());
+
+    return false;
+  }
 };
 }
 
@@ -2858,12 +2856,10 @@
                                     IndirectFieldDecl *Indirect = 0) {
 
   // Overwhelmingly common case: we have a direct initializer for this field.
-  if (CXXCtorInitializer *Init = Info.AllBaseFields.lookup(Field)) {
-    Info.AllToInit.push_back(Init);
-    return false;
-  }
+  if (CXXCtorInitializer *Init = Info.AllBaseFields.lookup(Field))
+    return Info.addFieldInitializer(Init);
 
-  // C++0x [class.base.init]p8: if the entity is a non-static data member that
+  // C++11 [class.base.init]p8: if the entity is a non-static data member that
   // has a brace-or-equal-initializer, the entity is initialized as specified
   // in [dcl.init].
   if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) {
@@ -2878,15 +2874,7 @@
                                                       SourceLocation(),
                                                       SourceLocation(), 0,
                                                       SourceLocation());
-    Info.AllToInit.push_back(Init);
-
-    // Check whether this initializer makes the field "used".
-    Expr *InitExpr = Field->getInClassInitializer();
-    if (Field->getType()->isRecordType() ||
-        (InitExpr && InitExpr->HasSideEffects(SemaRef.Context)))
-      SemaRef.UnusedPrivateFields.remove(Field);
-
-    return false;
+    return Info.addFieldInitializer(Init);
   }
 
   // Don't build an implicit initializer for union members if none was
@@ -2910,10 +2898,10 @@
                                      Indirect, Init))
     return true;
 
-  if (Init)
-    Info.AllToInit.push_back(Init);
+  if (!Init)
+    return false;
 
-  return false;
+  return Info.addFieldInitializer(Init);
 }
 
 bool
@@ -3493,6 +3481,7 @@
       : TypeDiagnoser(DiagID == 0), DiagID(DiagID), SelID(SelID) { }
     
     virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) {
+      if (Suppressed) return;
       if (SelID == -1)
         S.Diag(Loc, DiagID) << T;
       else
@@ -3881,9 +3870,6 @@
   //   instantiated (e.g. meta-functions). This doesn't apply to classes that
   //   have inherited constructors.
   DeclareInheritedConstructors(Record);
-
-  if (!Record->isDependentType())
-    CheckExplicitlyDefaultedMethods(Record);
 }
 
 void Sema::CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record) {
@@ -3989,6 +3975,63 @@
   return true;
 }
 
+static Sema::ImplicitExceptionSpecification
+computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, CXXMethodDecl *MD) {
+  switch (S.getSpecialMember(MD)) {
+  case Sema::CXXDefaultConstructor:
+    return S.ComputeDefaultedDefaultCtorExceptionSpec(Loc, MD);
+  case Sema::CXXCopyConstructor:
+    return S.ComputeDefaultedCopyCtorExceptionSpec(MD);
+  case Sema::CXXCopyAssignment:
+    return S.ComputeDefaultedCopyAssignmentExceptionSpec(MD);
+  case Sema::CXXMoveConstructor:
+    return S.ComputeDefaultedMoveCtorExceptionSpec(MD);
+  case Sema::CXXMoveAssignment:
+    return S.ComputeDefaultedMoveAssignmentExceptionSpec(MD);
+  case Sema::CXXDestructor:
+    return S.ComputeDefaultedDtorExceptionSpec(MD);
+  case Sema::CXXInvalid:
+    break;
+  }
+  llvm_unreachable("only special members have implicit exception specs");
+}
+
+static void
+updateExceptionSpec(Sema &S, FunctionDecl *FD, const FunctionProtoType *FPT,
+                    const Sema::ImplicitExceptionSpecification &ExceptSpec) {
+  FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+  ExceptSpec.getEPI(EPI);
+  const FunctionProtoType *NewFPT = cast<FunctionProtoType>(
+    S.Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
+                              FPT->getNumArgs(), EPI));
+  FD->setType(QualType(NewFPT, 0));
+}
+
+void Sema::EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD) {
+  const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>();
+  if (FPT->getExceptionSpecType() != EST_Unevaluated)
+    return;
+
+  // Evaluate the exception specification.
+  ImplicitExceptionSpecification ExceptSpec =
+      computeImplicitExceptionSpec(*this, Loc, MD);
+
+  // Update the type of the special member to use it.
+  updateExceptionSpec(*this, MD, FPT, ExceptSpec);
+
+  // A user-provided destructor can be defined outside the class. When that
+  // happens, be sure to update the exception specification on both
+  // declarations.
+  const FunctionProtoType *CanonicalFPT =
+    MD->getCanonicalDecl()->getType()->castAs<FunctionProtoType>();
+  if (CanonicalFPT->getExceptionSpecType() == EST_Unevaluated)
+    updateExceptionSpec(*this, MD->getCanonicalDecl(),
+                        CanonicalFPT, ExceptSpec);
+}
+
+static bool isImplicitCopyCtorArgConst(Sema &S, CXXRecordDecl *ClassDecl);
+static bool isImplicitCopyAssignmentArgConst(Sema &S, CXXRecordDecl *ClassDecl);
+
 void Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD) {
   CXXRecordDecl *RD = MD->getParent();
   CXXSpecialMember CSM = getSpecialMember(MD);
@@ -4023,40 +4066,28 @@
 
   const FunctionProtoType *Type = MD->getType()->getAs<FunctionProtoType>();
 
-  // Compute implicit exception specification, argument constness, constexpr
-  // and triviality.
-  ImplicitExceptionSpecification Spec(*this);
+  // Compute argument constness, constexpr, and triviality.
   bool CanHaveConstParam = false;
   bool Trivial;
   switch (CSM) {
   case CXXDefaultConstructor:
-    Spec = ComputeDefaultedDefaultCtorExceptionSpec(RD);
-    if (Spec.isDelayed())
-      // Exception specification depends on some deferred part of the class.
-      // We'll try again when the class's definition has been fully processed.
-      return;
     Trivial = RD->hasTrivialDefaultConstructor();
     break;
   case CXXCopyConstructor:
-    llvm::tie(Spec, CanHaveConstParam) =
-      ComputeDefaultedCopyCtorExceptionSpecAndConst(RD);
+    CanHaveConstParam = isImplicitCopyCtorArgConst(*this, RD);
     Trivial = RD->hasTrivialCopyConstructor();
     break;
   case CXXCopyAssignment:
-    llvm::tie(Spec, CanHaveConstParam) =
-      ComputeDefaultedCopyAssignmentExceptionSpecAndConst(RD);
+    CanHaveConstParam = isImplicitCopyAssignmentArgConst(*this, RD);
     Trivial = RD->hasTrivialCopyAssignment();
     break;
   case CXXMoveConstructor:
-    Spec = ComputeDefaultedMoveCtorExceptionSpec(RD);
     Trivial = RD->hasTrivialMoveConstructor();
     break;
   case CXXMoveAssignment:
-    Spec = ComputeDefaultedMoveAssignmentExceptionSpec(RD);
     Trivial = RD->hasTrivialMoveAssignment();
     break;
   case CXXDestructor:
-    Spec = ComputeDefaultedDtorExceptionSpec(RD);
     Trivial = RD->hasTrivialDestructor();
     break;
   case CXXInvalid:
@@ -4126,11 +4157,15 @@
     HadError = true;
   }
 
-  // Rebuild the type with the implicit exception specification added.
-  FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo();
-  Spec.getEPI(EPI);
-  const FunctionProtoType *ImplicitType = cast<FunctionProtoType>(
-    Context.getFunctionType(ReturnType, &ArgType, ExpectedParams, EPI));
+  // Rebuild the type with the implicit exception specification added, if we
+  // are going to need it.
+  const FunctionProtoType *ImplicitType = 0;
+  if (First || Type->hasExceptionSpec()) {
+    FunctionProtoType::ExtProtoInfo EPI = Type->getExtProtoInfo();
+    computeImplicitExceptionSpec(*this, MD->getLocation(), MD).getEPI(EPI);
+    ImplicitType = cast<FunctionProtoType>(
+      Context.getFunctionType(ReturnType, &ArgType, ExpectedParams, EPI));
+  }
 
   // C++11 [dcl.fct.def.default]p2:
   //   An explicitly-defaulted function may be declared constexpr only if it
@@ -4506,7 +4541,8 @@
 /// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
 bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
                                      bool Diagnose) {
-  assert(!MD->isInvalidDecl());
+  if (MD->isInvalidDecl())
+    return false;
   CXXRecordDecl *RD = MD->getParent();
   assert(!RD->isDependentType() && "do deletion after instantiation");
   if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
@@ -6603,6 +6639,7 @@
   if (!Redeclaration)
     PushOnScopeChains(NewND, S);
 
+  ActOnDocumentableDecl(NewND);
   return NewND;
 }
 
@@ -6685,7 +6722,10 @@
 }
 
 Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl) {
+Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
+                                               CXXMethodDecl *MD) {
+  CXXRecordDecl *ClassDecl = MD->getParent();
+
   // C++ [except.spec]p14:
   //   An implicitly declared special member function (Clause 12) shall have an 
   //   exception-specification. [...]
@@ -6732,7 +6772,21 @@
       if (Expr *E = F->getInClassInitializer())
         ExceptSpec.CalledExpr(E);
       else if (!F->isInvalidDecl())
-        ExceptSpec.SetDelayed();
+        // DR1351:
+        //   If the brace-or-equal-initializer of a non-static data member
+        //   invokes a defaulted default constructor of its class or of an
+        //   enclosing class in a potentially evaluated subexpression, the
+        //   program is ill-formed.
+        //
+        // This resolution is unworkable: the exception specification of the
+        // default constructor can be needed in an unevaluated context, in
+        // particular, in the operand of a noexcept-expression, and we can be
+        // unable to compute an exception specification for an enclosed class.
+        //
+        // We do not allow an in-class initializer to require the evaluation
+        // of the exception specification for any in-class initializer whose
+        // definition is not lexically complete.
+        Diag(Loc, diag::err_in_class_initializer_references_def_ctor) << MD;
     } else if (const RecordType *RecordTy
               = Context.getBaseElementType(F->getType())->getAs<RecordType>()) {
       CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
@@ -6761,10 +6815,6 @@
   assert(!ClassDecl->hasUserDeclaredConstructor() && 
          "Should not build implicit default constructor!");
 
-  ImplicitExceptionSpecification Spec = 
-    ComputeDefaultedDefaultCtorExceptionSpec(ClassDecl);
-  FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
-
   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
                                                      CXXDefaultConstructor,
                                                      false);
@@ -6777,15 +6827,20 @@
     = Context.DeclarationNames.getCXXConstructorName(ClassType);
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXConstructorDecl *DefaultCon = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo,
-      Context.getFunctionType(Context.VoidTy, 0, 0, EPI), /*TInfo=*/0,
+      Context, ClassDecl, ClassLoc, NameInfo, /*Type*/QualType(), /*TInfo=*/0,
       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
       Constexpr);
   DefaultCon->setAccess(AS_public);
   DefaultCon->setDefaulted();
   DefaultCon->setImplicit();
   DefaultCon->setTrivial(ClassDecl->hasTrivialDefaultConstructor());
-  
+
+  // Build an exception specification pointing back at this constructor.
+  FunctionProtoType::ExtProtoInfo EPI;
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = DefaultCon;
+  DefaultCon->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
+
   // Note that we have declared this constructor.
   ++ASTContext::NumImplicitDefaultConstructorsDeclared;
   
@@ -6830,58 +6885,14 @@
   }
 }
 
-/// Get any existing defaulted default constructor for the given class. Do not
-/// implicitly define one if it does not exist.
-static CXXConstructorDecl *getDefaultedDefaultConstructorUnsafe(Sema &Self,
-                                                             CXXRecordDecl *D) {
-  ASTContext &Context = Self.Context;
-  QualType ClassType = Context.getTypeDeclType(D);
-  DeclarationName ConstructorName
-    = Context.DeclarationNames.getCXXConstructorName(
-                      Context.getCanonicalType(ClassType.getUnqualifiedType()));
-
-  DeclContext::lookup_const_iterator Con, ConEnd;
-  for (llvm::tie(Con, ConEnd) = D->lookup(ConstructorName);
-       Con != ConEnd; ++Con) {
-    // A function template cannot be defaulted.
-    if (isa<FunctionTemplateDecl>(*Con))
-      continue;
-
-    CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
-    if (Constructor->isDefaultConstructor())
-      return Constructor->isDefaulted() ? Constructor : 0;
-  }
-  return 0;
-}
-
 void Sema::ActOnFinishDelayedMemberInitializers(Decl *D) {
   if (!D) return;
   AdjustDeclIfTemplate(D);
 
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(D);
-  CXXConstructorDecl *CtorDecl
-    = getDefaultedDefaultConstructorUnsafe(*this, ClassDecl);
 
-  if (!CtorDecl) return;
-
-  // Compute the exception specification for the default constructor.
-  const FunctionProtoType *CtorTy =
-    CtorDecl->getType()->castAs<FunctionProtoType>();
-  if (CtorTy->getExceptionSpecType() == EST_Delayed) {
-    // FIXME: Don't do this unless the exception spec is needed.
-    ImplicitExceptionSpecification Spec = 
-      ComputeDefaultedDefaultCtorExceptionSpec(ClassDecl);
-    FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
-    assert(EPI.ExceptionSpecType != EST_Delayed);
-
-    CtorDecl->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
-  }
-
-  // If the default constructor is explicitly defaulted, checking the exception
-  // specification is deferred until now.
-  if (!CtorDecl->isInvalidDecl() && CtorDecl->isExplicitlyDefaulted() &&
-      !ClassDecl->isDependentType())
-    CheckExplicitlyDefaultedSpecialMember(CtorDecl);
+  if (!ClassDecl->isDependentType())
+    CheckExplicitlyDefaultedMethods(ClassDecl);
 }
 
 void Sema::DeclareInheritedConstructors(CXXRecordDecl *ClassDecl) {
@@ -7065,7 +7076,9 @@
 }
 
 Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl) {
+Sema::ComputeDefaultedDtorExceptionSpec(CXXMethodDecl *MD) {
+  CXXRecordDecl *ClassDecl = MD->getParent();
+
   // C++ [except.spec]p14: 
   //   An implicitly declared special member function (Clause 12) shall have 
   //   an exception-specification.
@@ -7112,14 +7125,8 @@
   //   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.
-  
-  ImplicitExceptionSpecification Spec =
-      ComputeDefaultedDtorExceptionSpec(ClassDecl); 
-  FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
 
   // Create the actual destructor declaration.
-  QualType Ty = Context.getFunctionType(Context.VoidTy, 0, 0, EPI);
-
   CanQualType ClassType
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   SourceLocation ClassLoc = ClassDecl->getLocation();
@@ -7127,24 +7134,27 @@
     = Context.DeclarationNames.getCXXDestructorName(ClassType);
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXDestructorDecl *Destructor
-      = CXXDestructorDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, Ty, 0,
-                                  /*isInline=*/true,
+      = CXXDestructorDecl::Create(Context, ClassDecl, ClassLoc, NameInfo,
+                                  QualType(), 0, /*isInline=*/true,
                                   /*isImplicitlyDeclared=*/true);
   Destructor->setAccess(AS_public);
   Destructor->setDefaulted();
   Destructor->setImplicit();
   Destructor->setTrivial(ClassDecl->hasTrivialDestructor());
-  
+
+  // Build an exception specification pointing back at this destructor.
+  FunctionProtoType::ExtProtoInfo EPI;
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = Destructor;
+  Destructor->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
+
   // Note that we have declared this destructor.
   ++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);
 
@@ -7194,15 +7204,6 @@
 /// \brief Perform any semantic analysis which needs to be delayed until all
 /// pending class member declarations have been parsed.
 void Sema::ActOnFinishCXXMemberDecls() {
-  // Now we have parsed all exception specifications, determine the implicit
-  // exception specifications for destructors.
-  for (unsigned i = 0, e = DelayedDestructorExceptionSpecs.size();
-       i != e; ++i) {
-    CXXDestructorDecl *Dtor = DelayedDestructorExceptionSpecs[i];
-    AdjustDestructorExceptionSpec(Dtor->getParent(), Dtor, true);
-  }
-  DelayedDestructorExceptionSpecs.clear();
-
   // Perform any deferred checking of exception specifications for virtual
   // destructors.
   for (unsigned i = 0, e = DelayedDestructorExceptionSpecChecks.size();
@@ -7217,44 +7218,33 @@
   DelayedDestructorExceptionSpecChecks.clear();
 }
 
-void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *classDecl,
-                                         CXXDestructorDecl *destructor,
-                                         bool WasDelayed) {
+void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl,
+                                         CXXDestructorDecl *Destructor) {
+  assert(getLangOpts().CPlusPlus0x &&
+         "adjusting dtor exception specs was introduced in c++11");
+
   // C++11 [class.dtor]p3:
   //   A declaration of a destructor that does not have an exception-
   //   specification is implicitly considered to have the same exception-
   //   specification as an implicit declaration.
-  const FunctionProtoType *dtorType = destructor->getType()->
+  const FunctionProtoType *DtorType = Destructor->getType()->
                                         getAs<FunctionProtoType>();
-  if (!WasDelayed && dtorType->hasExceptionSpec())
+  if (DtorType->hasExceptionSpec())
     return;
 
-  ImplicitExceptionSpecification exceptSpec =
-      ComputeDefaultedDtorExceptionSpec(classDecl);
-
   // Replace the destructor's type, building off the existing one. Fortunately,
   // the only thing of interest in the destructor type is its extended info.
   // The return and arguments are fixed.
-  FunctionProtoType::ExtProtoInfo epi = dtorType->getExtProtoInfo();
-  epi.ExceptionSpecType = exceptSpec.getExceptionSpecType();
-  epi.NumExceptions = exceptSpec.size();
-  epi.Exceptions = exceptSpec.data();
-  QualType ty = Context.getFunctionType(Context.VoidTy, 0, 0, epi);
-
-  destructor->setType(ty);
-
-  // If we can't compute the exception specification for this destructor yet
-  // (because it depends on an exception specification which we have not parsed
-  // yet), make a note that we need to try again when the class is complete.
-  if (epi.ExceptionSpecType == EST_Delayed) {
-    assert(!WasDelayed && "couldn't compute destructor exception spec");
-    DelayedDestructorExceptionSpecs.push_back(destructor);
-  }
+  FunctionProtoType::ExtProtoInfo EPI = DtorType->getExtProtoInfo();
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = Destructor;
+  Destructor->setType(Context.getFunctionType(Context.VoidTy, 0, 0, EPI));
 
   // FIXME: If the destructor has a body that could throw, and the newly created
   // spec doesn't allow exceptions, we should emit a warning, because this
   // change in behavior can break conforming C++03 programs at runtime.
-  // However, we don't have a body yet, so it needs to be done somewhere else.
+  // However, we don't have a body or an exception specification yet, so it
+  // needs to be done somewhere else.
 }
 
 /// \brief Builds a statement that copies/moves the given entity from \p From to
@@ -7456,11 +7446,13 @@
                         Loc, Copy.take());
 }
 
-std::pair<Sema::ImplicitExceptionSpecification, bool>
-Sema::ComputeDefaultedCopyAssignmentExceptionSpecAndConst(
-                                                   CXXRecordDecl *ClassDecl) {
+/// Determine whether an implicit copy assignment operator for ClassDecl has a
+/// const argument.
+/// FIXME: It ought to be possible to store this on the record.
+static bool isImplicitCopyAssignmentArgConst(Sema &S,
+                                             CXXRecordDecl *ClassDecl) {
   if (ClassDecl->isInvalidDecl())
-    return std::make_pair(ImplicitExceptionSpecification(*this), true);
+    return true;
 
   // C++ [class.copy]p10:
   //   If the class definition does not explicitly declare a copy
@@ -7471,37 +7463,34 @@
   //       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(),
                                        BaseEnd = ClassDecl->bases_end();
-       HasConstCopyAssignment && Base != BaseEnd; ++Base) {
+       Base != BaseEnd; ++Base) {
     // We'll handle this below
-    if (LangOpts.CPlusPlus0x && Base->isVirtual())
+    if (S.getLangOpts().CPlusPlus0x && Base->isVirtual())
       continue;
 
     assert(!Base->getType()->isDependentType() &&
            "Cannot generate implicit members for class with dependent bases.");
     CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
-    HasConstCopyAssignment &=
-      (bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
-                                    false, 0);
+    if (!S.LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const, false, 0))
+      return false;
   }
 
   // In C++11, the above citation has "or virtual" added
-  if (LangOpts.CPlusPlus0x) {
+  if (S.getLangOpts().CPlusPlus0x) {
     for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
                                          BaseEnd = ClassDecl->vbases_end();
-         HasConstCopyAssignment && Base != BaseEnd; ++Base) {
+         Base != BaseEnd; ++Base) {
       assert(!Base->getType()->isDependentType() &&
              "Cannot generate implicit members for class with dependent bases.");
       CXXRecordDecl *BaseClassDecl = Base->getType()->getAsCXXRecordDecl();
-      HasConstCopyAssignment &=
-        (bool)LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
-                                      false, 0);
+      if (!S.LookupCopyingAssignment(BaseClassDecl, Qualifiers::Const,
+                                     false, 0))
+        return false;
     }
   }
   
@@ -7511,23 +7500,36 @@
   //          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 (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
-      HasConstCopyAssignment &=
-        (bool)LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const,
-                                      false, 0);
-    }
+       Field != FieldEnd; ++Field) {
+    QualType FieldType = S.Context.getBaseElementType(Field->getType());
+    if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl())
+      if (!S.LookupCopyingAssignment(FieldClassDecl, Qualifiers::Const,
+                                     false, 0))
+        return false;
   }
   
   //   Otherwise, the implicitly declared copy assignment operator will
   //   have the form
   //
   //       X& X::operator=(X&)
-  
+
+  return true;
+}
+
+Sema::ImplicitExceptionSpecification
+Sema::ComputeDefaultedCopyAssignmentExceptionSpec(CXXMethodDecl *MD) {
+  CXXRecordDecl *ClassDecl = MD->getParent();
+
+  ImplicitExceptionSpecification ExceptSpec(*this);
+  if (ClassDecl->isInvalidDecl())
+    return ExceptSpec;
+
+  const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>();
+  assert(T->getNumArgs() == 1 && "not a copy assignment op");
+  unsigned ArgQuals = T->getArgType(0).getNonReferenceType().getCVRQualifiers();
+
   // C++ [except.spec]p14:
-  //   An implicitly declared special member function (Clause 12) shall have an 
+  //   An implicitly declared special member function (Clause 12) shall have an
   //   exception-specification. [...]
 
   // It is unspecified whether or not an implicit copy assignment operator
@@ -7536,8 +7538,6 @@
   // Based on a similar decision made for constness in C++0x, we're erring on
   // the side of assuming such calls to be made regardless of whether they
   // actually happen.
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  unsigned ArgQuals = HasConstCopyAssignment ? Qualifiers::Const : 0;
   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
                                        BaseEnd = ClassDecl->bases_end();
        Base != BaseEnd; ++Base) {
@@ -7575,7 +7575,7 @@
     }
   }
 
-  return std::make_pair(ExceptSpec, HasConstCopyAssignment);
+  return ExceptSpec;
 }
 
 CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
@@ -7584,26 +7584,19 @@
   // for determining the argument type of the operator. Note also that
   // operators taking an object instead of a reference are allowed.
 
-  ImplicitExceptionSpecification Spec(*this);
-  bool Const;
-  llvm::tie(Spec, Const) =
-    ComputeDefaultedCopyAssignmentExceptionSpecAndConst(ClassDecl);
-
   QualType ArgType = Context.getTypeDeclType(ClassDecl);
   QualType RetType = Context.getLValueReferenceType(ArgType);
-  if (Const)
+  if (isImplicitCopyAssignmentArgConst(*this, ClassDecl))
     ArgType = ArgType.withConst();
   ArgType = Context.getLValueReferenceType(ArgType);
 
   //   An implicitly-declared copy assignment operator is an inline public
   //   member of its class.
-  FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
   SourceLocation ClassLoc = ClassDecl->getLocation();
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXMethodDecl *CopyAssignment
-    = CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo,
-                            Context.getFunctionType(RetType, &ArgType, 1, EPI),
+    = CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(),
                             /*TInfo=*/0, /*isStatic=*/false,
                             /*StorageClassAsWritten=*/SC_None,
                             /*isInline=*/true, /*isConstexpr=*/false,
@@ -7612,7 +7605,13 @@
   CopyAssignment->setDefaulted();
   CopyAssignment->setImplicit();
   CopyAssignment->setTrivial(ClassDecl->hasTrivialCopyAssignment());
-  
+
+  // Build an exception specification pointing back at this member.
+  FunctionProtoType::ExtProtoInfo EPI;
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = CopyAssignment;
+  CopyAssignment->setType(Context.getFunctionType(RetType, &ArgType, 1, EPI));
+
   // Add the parameter to the operator.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, CopyAssignment,
                                                ClassLoc, ClassLoc, /*Id=*/0,
@@ -7950,9 +7949,10 @@
 }
 
 Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXRecordDecl *ClassDecl) {
-  ImplicitExceptionSpecification ExceptSpec(*this);
+Sema::ComputeDefaultedMoveAssignmentExceptionSpec(CXXMethodDecl *MD) {
+  CXXRecordDecl *ClassDecl = MD->getParent();
 
+  ImplicitExceptionSpecification ExceptSpec(*this);
   if (ClassDecl->isInvalidDecl())
     return ExceptSpec;
 
@@ -8120,22 +8120,17 @@
   // Note: The following rules are largely analoguous to the move
   // constructor rules.
 
-  ImplicitExceptionSpecification Spec(
-      ComputeDefaultedMoveAssignmentExceptionSpec(ClassDecl));
-
   QualType ArgType = Context.getTypeDeclType(ClassDecl);
   QualType RetType = Context.getLValueReferenceType(ArgType);
   ArgType = Context.getRValueReferenceType(ArgType);
 
   //   An implicitly-declared move assignment operator is an inline public
   //   member of its class.
-  FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
   SourceLocation ClassLoc = ClassDecl->getLocation();
   DeclarationNameInfo NameInfo(Name, ClassLoc);
   CXXMethodDecl *MoveAssignment
-    = CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo,
-                            Context.getFunctionType(RetType, &ArgType, 1, EPI),
+    = CXXMethodDecl::Create(Context, ClassDecl, ClassLoc, NameInfo, QualType(),
                             /*TInfo=*/0, /*isStatic=*/false,
                             /*StorageClassAsWritten=*/SC_None,
                             /*isInline=*/true,
@@ -8146,6 +8141,12 @@
   MoveAssignment->setImplicit();
   MoveAssignment->setTrivial(ClassDecl->hasTrivialMoveAssignment());
 
+  // Build an exception specification pointing back at this member.
+  FunctionProtoType::ExtProtoInfo EPI;
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = MoveAssignment;
+  MoveAssignment->setType(Context.getFunctionType(RetType, &ArgType, 1, EPI));
+
   // Add the parameter to the operator.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveAssignment,
                                                ClassLoc, ClassLoc, /*Id=*/0,
@@ -8496,10 +8497,12 @@
   }
 }
 
-std::pair<Sema::ImplicitExceptionSpecification, bool>
-Sema::ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl) {
+/// Determine whether an implicit copy constructor for ClassDecl has a const
+/// argument.
+/// FIXME: It ought to be possible to store this on the record.
+static bool isImplicitCopyCtorArgConst(Sema &S, CXXRecordDecl *ClassDecl) {
   if (ClassDecl->isInvalidDecl())
-    return std::make_pair(ImplicitExceptionSpecification(*this), true);
+    return true;
 
   // C++ [class.copy]p5:
   //   The implicitly-declared copy constructor for a class X will
@@ -8508,60 +8511,71 @@
   //       X::X(const X&)
   //
   //   if
-  // FIXME: It ought to be possible to store this on the record.
-  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) {
+       Base != BaseEnd; ++Base) {
     // Virtual bases are handled below.
     if (Base->isVirtual())
       continue;
-    
+
     CXXRecordDecl *BaseClassDecl
       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-    HasConstCopyConstructor &=
-      (bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const);
+    // FIXME: This lookup is wrong. If the copy ctor for a member or base is
+    // ambiguous, we should still produce a constructor with a const-qualified
+    // parameter.
+    if (!S.LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const))
+      return false;
   }
 
   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
                                        BaseEnd = ClassDecl->vbases_end();
-       HasConstCopyConstructor && Base != BaseEnd; 
-       ++Base) {
+       Base != BaseEnd; ++Base) {
     CXXRecordDecl *BaseClassDecl
       = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-    HasConstCopyConstructor &=
-      (bool)LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const);
+    if (!S.LookupCopyingConstructor(BaseClassDecl, Qualifiers::Const))
+      return false;
   }
-  
+
   //     -- 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());
+       Field != FieldEnd; ++Field) {
+    QualType FieldType = S.Context.getBaseElementType(Field->getType());
     if (CXXRecordDecl *FieldClassDecl = FieldType->getAsCXXRecordDecl()) {
-      HasConstCopyConstructor &=
-        (bool)LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const);
+      if (!S.LookupCopyingConstructor(FieldClassDecl, Qualifiers::Const))
+        return false;
     }
   }
+
   //   Otherwise, the implicitly declared copy constructor will have
   //   the form
   //
   //       X::X(X&)
- 
+
+  return true;
+}
+
+Sema::ImplicitExceptionSpecification
+Sema::ComputeDefaultedCopyCtorExceptionSpec(CXXMethodDecl *MD) {
+  CXXRecordDecl *ClassDecl = MD->getParent();
+
+  ImplicitExceptionSpecification ExceptSpec(*this);
+  if (ClassDecl->isInvalidDecl())
+    return ExceptSpec;
+
+  const FunctionProtoType *T = MD->getType()->castAs<FunctionProtoType>();
+  assert(T->getNumArgs() >= 1 && "not a copy ctor");
+  unsigned Quals = T->getArgType(0).getNonReferenceType().getCVRQualifiers();
+
   // C++ [except.spec]p14:
   //   An implicitly declared special member function (Clause 12) shall have an 
   //   exception-specification. [...]
-  ImplicitExceptionSpecification ExceptSpec(*this);
-  unsigned Quals = HasConstCopyConstructor? Qualifiers::Const : 0;
   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
                                        BaseEnd = ClassDecl->bases_end();
        Base != BaseEnd; 
@@ -8599,7 +8613,7 @@
     }
   }
 
-  return std::make_pair(ExceptSpec, HasConstCopyConstructor);
+  return ExceptSpec;
 }
 
 CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
@@ -8608,18 +8622,12 @@
   //   If the class definition does not explicitly declare a copy
   //   constructor, one is declared implicitly.
 
-  ImplicitExceptionSpecification Spec(*this);
-  bool Const;
-  llvm::tie(Spec, Const) =
-    ComputeDefaultedCopyCtorExceptionSpecAndConst(ClassDecl);
-
   QualType ClassType = Context.getTypeDeclType(ClassDecl);
   QualType ArgType = ClassType;
+  bool Const = isImplicitCopyCtorArgConst(*this, ClassDecl);
   if (Const)
     ArgType = ArgType.withConst();
   ArgType = Context.getLValueReferenceType(ArgType);
- 
-  FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
 
   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
                                                      CXXCopyConstructor,
@@ -8634,14 +8642,20 @@
   //   An implicitly-declared copy constructor is an inline public
   //   member of its class.
   CXXConstructorDecl *CopyConstructor = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo,
-      Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI), /*TInfo=*/0,
+      Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/0,
       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
       Constexpr);
   CopyConstructor->setAccess(AS_public);
   CopyConstructor->setDefaulted();
   CopyConstructor->setTrivial(ClassDecl->hasTrivialCopyConstructor());
 
+  // Build an exception specification pointing back at this member.
+  FunctionProtoType::ExtProtoInfo EPI;
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = CopyConstructor;
+  CopyConstructor->setType(
+      Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI));
+
   // Note that we have declared this constructor.
   ++ASTContext::NumImplicitCopyConstructorsDeclared;
   
@@ -8705,7 +8719,9 @@
 }
 
 Sema::ImplicitExceptionSpecification
-Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXRecordDecl *ClassDecl) {
+Sema::ComputeDefaultedMoveCtorExceptionSpec(CXXMethodDecl *MD) {
+  CXXRecordDecl *ClassDecl = MD->getParent();
+
   // C++ [except.spec]p14:
   //   An implicitly declared special member function (Clause 12) shall have an 
   //   exception-specification. [...]
@@ -8788,13 +8804,8 @@
     return 0;
   }
 
-  ImplicitExceptionSpecification Spec(
-      ComputeDefaultedMoveCtorExceptionSpec(ClassDecl));
-
   QualType ClassType = Context.getTypeDeclType(ClassDecl);
   QualType ArgType = Context.getRValueReferenceType(ClassType);
- 
-  FunctionProtoType::ExtProtoInfo EPI = Spec.getEPI();
 
   bool Constexpr = defaultedSpecialMemberIsConstexpr(*this, ClassDecl,
                                                      CXXMoveConstructor,
@@ -8810,14 +8821,20 @@
   //   An implicitly-declared copy/move constructor is an inline public
   //   member of its class.
   CXXConstructorDecl *MoveConstructor = CXXConstructorDecl::Create(
-      Context, ClassDecl, ClassLoc, NameInfo,
-      Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI), /*TInfo=*/0,
+      Context, ClassDecl, ClassLoc, NameInfo, QualType(), /*TInfo=*/0,
       /*isExplicit=*/false, /*isInline=*/true, /*isImplicitlyDeclared=*/true,
       Constexpr);
   MoveConstructor->setAccess(AS_public);
   MoveConstructor->setDefaulted();
   MoveConstructor->setTrivial(ClassDecl->hasTrivialMoveConstructor());
 
+  // Build an exception specification pointing back at this member.
+  FunctionProtoType::ExtProtoInfo EPI;
+  EPI.ExceptionSpecType = EST_Unevaluated;
+  EPI.ExceptionSpecDecl = MoveConstructor;
+  MoveConstructor->setType(
+      Context.getFunctionType(Context.VoidTy, &ArgType, 1, EPI));
+
   // Add the parameter to the constructor.
   ParmVarDecl *FromParam = ParmVarDecl::Create(Context, MoveConstructor,
                                                ClassLoc, ClassLoc,
@@ -9446,7 +9463,7 @@
       TemplateParameterList *Params = TpDecl->getTemplateParameters();
       if (Params->size() == 1) {
         NonTypeTemplateParmDecl *PmDecl =
-          cast<NonTypeTemplateParmDecl>(Params->getParam(0));
+          dyn_cast<NonTypeTemplateParmDecl>(Params->getParam(0));
 
         // The template parameter must be a char parameter pack.
         if (PmDecl && PmDecl->isTemplateParameterPack() &&
@@ -9793,7 +9810,7 @@
     if (!Failed && !Cond) {
       llvm::SmallString<256> MsgBuffer;
       llvm::raw_svector_ostream Msg(MsgBuffer);
-      AssertMessage->printPretty(Msg, Context, 0, getPrintingPolicy());
+      AssertMessage->printPretty(Msg, 0, getPrintingPolicy());
       Diag(StaticAssertLoc, diag::err_static_assert_failed)
         << Msg.str() << AssertExpr->getSourceRange();
       Failed = true;
@@ -10329,9 +10346,11 @@
   FrD->setAccess(AS_public);
   CurContext->addDecl(FrD);
 
-  if (ND->isInvalidDecl())
+  if (ND->isInvalidDecl()) {
     FrD->setInvalidDecl();
-  else {
+  } else {
+    if (DC->isRecord()) CheckFriendAccess(ND);
+
     FunctionDecl *FD;
     if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
       FD = FTD->getTemplatedDecl();
@@ -10427,10 +10446,11 @@
     if (Primary == Primary->getCanonicalDecl())
       return;
 
+    CheckExplicitlyDefaultedSpecialMember(MD);
+
     switch (Member) {
     case CXXDefaultConstructor: {
       CXXConstructorDecl *CD = cast<CXXConstructorDecl>(MD);
-      CheckExplicitlyDefaultedSpecialMember(CD);
       if (!CD->isInvalidDecl())
         DefineImplicitDefaultConstructor(DefaultLoc, CD);
       break;
@@ -10438,14 +10458,12 @@
 
     case CXXCopyConstructor: {
       CXXConstructorDecl *CD = cast<CXXConstructorDecl>(MD);
-      CheckExplicitlyDefaultedSpecialMember(CD);
       if (!CD->isInvalidDecl())
         DefineImplicitCopyConstructor(DefaultLoc, CD);
       break;
     }
 
     case CXXCopyAssignment: {
-      CheckExplicitlyDefaultedSpecialMember(MD);
       if (!MD->isInvalidDecl())
         DefineImplicitCopyAssignment(DefaultLoc, MD);
       break;
@@ -10453,7 +10471,6 @@
 
     case CXXDestructor: {
       CXXDestructorDecl *DD = cast<CXXDestructorDecl>(MD);
-      CheckExplicitlyDefaultedSpecialMember(DD);
       if (!DD->isInvalidDecl())
         DefineImplicitDestructor(DefaultLoc, DD);
       break;
@@ -10461,14 +10478,12 @@
 
     case CXXMoveConstructor: {
       CXXConstructorDecl *CD = cast<CXXConstructorDecl>(MD);
-      CheckExplicitlyDefaultedSpecialMember(CD);
       if (!CD->isInvalidDecl())
         DefineImplicitMoveConstructor(DefaultLoc, CD);
       break;
     }
 
     case CXXMoveAssignment: {
-      CheckExplicitlyDefaultedSpecialMember(MD);
       if (!MD->isInvalidDecl())
         DefineImplicitMoveAssignment(DefaultLoc, MD);
       break;
@@ -10753,7 +10768,7 @@
 
   // 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
+  // time through the loop and prefer indices (which are stable) to
   // iterators (which are not).
   bool DefinedAnything = false;
   for (unsigned I = 0; I != VTableUses.size(); ++I) {
@@ -10763,6 +10778,8 @@
 
     SourceLocation Loc = VTableUses[I].second;
 
+    bool DefineVTable = true;
+
     // 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.
@@ -10773,7 +10790,8 @@
       case TSK_ExplicitSpecialization:
       case TSK_ExplicitInstantiationDeclaration:
         // The key function is in another translation unit.
-        continue;
+        DefineVTable = false;
+        break;
 
       case TSK_ExplicitInstantiationDefinition:
       case TSK_ImplicitInstantiation:
@@ -10802,7 +10820,15 @@
       }
 
       if (IsExplicitInstantiationDeclaration)
-        continue;
+        DefineVTable = false;
+    }
+
+    // The exception specifications for all virtual members may be needed even
+    // if we are not providing an authoritative form of the vtable in this TU.
+    // We may choose to emit it available_externally anyway.
+    if (!DefineVTable) {
+      MarkVirtualMemberExceptionSpecsNeeded(Loc, Class);
+      continue;
     }
 
     // Mark all of the virtual members of this class as referenced, so
@@ -10831,6 +10857,14 @@
   return DefinedAnything;
 }
 
+void Sema::MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc,
+                                                 const CXXRecordDecl *RD) {
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
+                                      E = RD->method_end(); I != E; ++I)
+    if ((*I)->isVirtual() && !(*I)->isPure())
+      ResolveExceptionSpec(Loc, (*I)->getType()->castAs<FunctionProtoType>());
+}
+
 void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
                                         const CXXRecordDecl *RD) {
   // Mark all functions which will appear in RD's vtable as used.
@@ -11067,8 +11101,8 @@
 
   switch (Proto->getExceptionSpecType()) {
   case EST_Uninstantiated:
+  case EST_Unevaluated:
   case EST_BasicNoexcept:
-  case EST_Delayed:
   case EST_DynamicNone:
   case EST_MSAny:
   case EST_None:
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 17c34a2..9da4d69 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -197,7 +197,6 @@
   ObjCMethodFamily family = method->getMethodFamily();
   switch (family) {
   case OMF_None:
-  case OMF_dealloc:
   case OMF_finalize:
   case OMF_retain:
   case OMF_release:
@@ -207,6 +206,24 @@
   case OMF_performSelector:
     return false;
 
+  case OMF_dealloc:
+    if (!S.Context.hasSameType(method->getResultType(), S.Context.VoidTy)) {
+      SourceRange ResultTypeRange;
+      if (const TypeSourceInfo *ResultTypeInfo
+          = method->getResultTypeSourceInfo())
+        ResultTypeRange = ResultTypeInfo->getTypeLoc().getSourceRange();
+      if (ResultTypeRange.isInvalid())
+        S.Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
+          << method->getResultType() 
+          << FixItHint::CreateInsertion(method->getSelectorLoc(0), "(void)");
+      else
+        S.Diag(method->getLocation(), diag::error_dealloc_bad_result_type) 
+          << method->getResultType() 
+          << FixItHint::CreateReplacement(ResultTypeRange, "void");
+      return true;
+    }
+    return false;
+      
   case OMF_init:
     // If the method doesn't obey the init rules, don't bother annotating it.
     if (S.checkInitMethod(method, QualType()))
@@ -265,34 +282,10 @@
     AddFactoryMethodToGlobalPool(MDecl, true);
 }
 
-/// ActOnStartOfObjCMethodOrCFunctionDef - This routine sets up parameters; invisible
-/// and user declared, in the method definition's AST. This routine is also  called
-/// for C-functions defined in an Objective-c class implementation.
-void Sema::ActOnStartOfObjCMethodOrCFunctionDef(Scope *FnBodyScope, Decl *D,
-                                                bool parseMethod) {
-  assert((getCurMethodDecl() == 0 && getCurFunctionDecl() == 0) &&
-         "Method/c-function parsing confused");
-  if (!parseMethod) {
-    FunctionDecl *FDecl = dyn_cast_or_null<FunctionDecl>(D);
-    // If we don't have a valid c-function decl, simply return.
-    if (!FDecl)
-      return;
-    PushDeclContext(FnBodyScope, FDecl);
-    PushFunctionScope();
-    
-    for (FunctionDecl::param_const_iterator PI = FDecl->param_begin(),
-         E = FDecl->param_end(); PI != E; ++PI) {
-      ParmVarDecl *Param = (*PI);
-      if (!Param->isInvalidDecl() &&
-          RequireCompleteType(Param->getLocation(), Param->getType(),
-                              diag::err_typecheck_decl_incomplete_type))
-        Param->setInvalidDecl();
-      if ((*PI)->getIdentifier())
-        PushOnScopeChains(*PI, FnBodyScope);
-    }
-    return;
-  }
-  
+/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
+/// and user declared, in the method definition's AST.
+void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
+  assert((getCurMethodDecl() == 0) && "Methodparsing confused");
   ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
   
   // If we don't have a valid method decl, simply return.
@@ -363,11 +356,11 @@
     // Finally, in ActOnFinishFunctionBody() (SemaDecl), warn if flag is set.
     // Only do this if the current class actually has a superclass.
     if (IC->getSuperClass()) {
-      ObjCShouldCallSuperDealloc = 
+      getCurFunction()->ObjCShouldCallSuperDealloc = 
         !(Context.getLangOpts().ObjCAutoRefCount ||
           Context.getLangOpts().getGC() == LangOptions::GCOnly) &&
         MDecl->getMethodFamily() == OMF_dealloc;
-      ObjCShouldCallSuperFinalize =
+      getCurFunction()->ObjCShouldCallSuperFinalize =
         Context.getLangOpts().getGC() != LangOptions::NonGC &&
         MDecl->getMethodFamily() == OMF_finalize;
     }
@@ -526,13 +519,13 @@
   return ActOnObjCContainerStartDefinition(IDecl);
 }
 
-/// ActOnCompatiblityAlias - this action is called after complete parsing of
+/// ActOnCompatibilityAlias - this action is called after complete parsing of
 /// a \@compatibility_alias declaration. It sets up the alias relationships.
-Decl *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
-                                        IdentifierInfo *AliasName,
-                                        SourceLocation AliasLocation,
-                                        IdentifierInfo *ClassName,
-                                        SourceLocation ClassLocation) {
+Decl *Sema::ActOnCompatibilityAlias(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);
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index f88ead5..e6266fb 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -100,20 +100,22 @@
 
 const FunctionProtoType *
 Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {
-  // FIXME: If FD is a special member, we should delay computing its exception
-  // specification until this point.
-  if (FPT->getExceptionSpecType() != EST_Uninstantiated)
+  if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
     return FPT;
 
   FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl();
   const FunctionProtoType *SourceFPT =
       SourceDecl->getType()->castAs<FunctionProtoType>();
 
-  if (SourceFPT->getExceptionSpecType() != EST_Uninstantiated)
+  // If the exception specification has already been resolved, just return it.
+  if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType()))
     return SourceFPT;
 
-  // Instantiate the exception specification now.
-  InstantiateExceptionSpec(Loc, SourceDecl);
+  // Compute or instantiate the exception specification now.
+  if (FPT->getExceptionSpecType() == EST_Unevaluated)
+    EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl));
+  else
+    InstantiateExceptionSpec(Loc, SourceDecl);
 
   return SourceDecl->getType()->castAs<FunctionProtoType>();
 }
@@ -240,8 +242,7 @@
 
     case EST_ComputedNoexcept:
       OS << "noexcept(";
-      OldProto->getNoexceptExpr()->printPretty(OS, Context, 0, 
-                                               getPrintingPolicy());
+      OldProto->getNoexceptExpr()->printPretty(OS, 0, getPrintingPolicy());
       OS << ")";
       break;
 
@@ -346,8 +347,8 @@
   ExceptionSpecificationType OldEST = Old->getExceptionSpecType();
   ExceptionSpecificationType NewEST = New->getExceptionSpecType();
 
-  assert(OldEST != EST_Delayed && NewEST != EST_Delayed &&
-         OldEST != EST_Uninstantiated && NewEST != EST_Uninstantiated &&
+  assert(!isUnresolvedExceptionSpec(OldEST) &&
+         !isUnresolvedExceptionSpec(NewEST) &&
          "Shouldn't see unknown exception specifications here");
 
   // Shortcut the case where both have no spec.
@@ -544,8 +545,8 @@
 
   ExceptionSpecificationType SubEST = Subset->getExceptionSpecType();
 
-  assert(SuperEST != EST_Delayed && SubEST != EST_Delayed &&
-         SuperEST != EST_Uninstantiated && SubEST != EST_Uninstantiated &&
+  assert(!isUnresolvedExceptionSpec(SuperEST) &&
+         !isUnresolvedExceptionSpec(SubEST) &&
          "Shouldn't see unknown exception specifications here");
 
   // It does not. If the subset contains everything, we've failed.
@@ -808,15 +809,6 @@
   if (!FT)
     return CT_Can;
 
-  if (FT->getExceptionSpecType() == EST_Delayed) {
-    // FIXME: Try to resolve a delayed exception spec in ResolveExceptionSpec.
-    assert(isa<CXXConstructorDecl>(D) &&
-           "only constructor exception specs can be unknown");
-    S.Diag(E->getLocStart(), diag::err_exception_spec_unknown)
-      << E->getSourceRange();
-    return CT_Can;
-  }
-
   return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
 }
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 9b5f003..3875ba1 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -584,8 +584,7 @@
   //     is a prvalue for the temporary.
   // FIXME: add some way to gate this entire thing for correctness in
   // potentially potentially evaluated contexts.
-  if (getLangOpts().CPlusPlus && E->isGLValue() && 
-      ExprEvalContexts.back().Context != Unevaluated) {
+  if (getLangOpts().CPlusPlus && E->isGLValue() && !isUnevaluatedContext()) {
     ExprResult Temp = PerformCopyInitialization(
                        InitializedEntity::InitializeTemporary(E->getType()),
                                                 E->getExprLoc(),
@@ -1962,6 +1961,10 @@
         return ExprError();
 
       MarkAnyDeclReferenced(Loc, IV);
+      
+      ObjCMethodFamily MF = CurMethod->getMethodFamily();
+      if (MF != OMF_init && MF != OMF_dealloc && MF != OMF_finalize)
+        Diag(Loc, diag::warn_direct_ivar_access) << IV->getDeclName();
       return Owned(new (Context)
                    ObjCIvarRefExpr(IV, IV->getType(), Loc,
                                    SelfExpr.take(), true, true));
@@ -2403,7 +2406,7 @@
       // FIXME: Does the addition of const really only apply in
       // potentially-evaluated contexts? Since the variable isn't actually
       // captured in an unevaluated context, it seems that the answer is no.
-      if (ExprEvalContexts.back().Context != Sema::Unevaluated) {
+      if (!isUnevaluatedContext()) {
         QualType CapturedType = getCapturedDeclRefType(cast<VarDecl>(VD), Loc);
         if (!CapturedType.isNull())
           type = CapturedType;
@@ -2902,8 +2905,9 @@
                                              SourceLocation Loc,
                                              SourceRange ArgRange,
                                              UnaryExprOrTypeTrait TraitKind) {
-  // Reject sizeof(interface) and sizeof(interface<proto>) in 64-bit mode.
-  if (S.LangOpts.ObjCRuntime.isNonFragile() && T->isObjCObjectType()) {
+  // Reject sizeof(interface) and sizeof(interface<proto>) if the
+  // runtime doesn't allow it.
+  if (!S.LangOpts.ObjCRuntime.allowsSizeofAlignof() && T->isObjCObjectType()) {
     S.Diag(Loc, diag::err_sizeof_nonfragile_interface)
       << T << (TraitKind == UETT_SizeOf)
       << ArgRange;
@@ -3193,6 +3197,22 @@
   return BuildUnaryOp(S, OpLoc, Opc, Input);
 }
 
+/// \brief Diagnose if arithmetic on the given ObjC pointer is illegal.
+///
+/// \return true on error
+static bool checkArithmeticOnObjCPointer(Sema &S,
+                                         SourceLocation opLoc,
+                                         Expr *op) {
+  assert(op->getType()->isObjCObjectPointerType());
+  if (S.LangOpts.ObjCRuntime.allowsPointerArithmetic())
+    return false;
+
+  S.Diag(opLoc, diag::err_arithmetic_nonfragile_interface)
+    << op->getType()->castAs<ObjCObjectPointerType>()->getPointeeType()
+    << op->getSourceRange();
+  return true;
+}
+
 ExprResult
 Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
                               Expr *Idx, SourceLocation RLoc) {
@@ -3223,7 +3243,6 @@
   return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc);
 }
 
-
 ExprResult
 Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
                                       Expr *Idx, SourceLocation RLoc) {
@@ -3261,13 +3280,21 @@
     IndexExpr = RHSExp;
     ResultType = PTy->getPointeeType();
   } else if (const ObjCObjectPointerType *PTy =
-             LHSTy->getAs<ObjCObjectPointerType>()) {
+               LHSTy->getAs<ObjCObjectPointerType>()) {
     BaseExpr = LHSExp;
     IndexExpr = RHSExp;
-    Result = BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0);
-    if (!Result.isInvalid())
-      return Owned(Result.take());
+
+    // Use custom logic if this should be the pseudo-object subscript
+    // expression.
+    if (!LangOpts.ObjCRuntime.isSubscriptPointerArithmetic())
+      return BuildObjCSubscriptExpression(RLoc, BaseExpr, IndexExpr, 0, 0);
+
     ResultType = PTy->getPointeeType();
+    if (!LangOpts.ObjCRuntime.allowsPointerArithmetic()) {
+      Diag(LLoc, diag::err_subscript_nonfragile_interface)
+        << ResultType << BaseExpr->getSourceRange();
+      return ExprError();
+    }
   } else if (const PointerType *PTy = RHSTy->getAs<PointerType>()) {
      // Handle the uncommon case of "123[Ptr]".
     BaseExpr = RHSExp;
@@ -3279,6 +3306,11 @@
     BaseExpr = RHSExp;
     IndexExpr = LHSExp;
     ResultType = PTy->getPointeeType();
+    if (!LangOpts.ObjCRuntime.allowsPointerArithmetic()) {
+      Diag(LLoc, diag::err_subscript_nonfragile_interface)
+        << ResultType << BaseExpr->getSourceRange();
+      return ExprError();
+    }
   } else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) {
     BaseExpr = LHSExp;    // vectors: V[123]
     IndexExpr = RHSExp;
@@ -3351,13 +3383,6 @@
                           diag::err_subscript_incomplete_type, BaseExpr))
     return ExprError();
 
-  // Diagnose bad cases where we step over interface counts.
-  if (ResultType->isObjCObjectType() && LangOpts.ObjCRuntime.isNonFragile()) {
-    Diag(LLoc, diag::err_subscript_nonfragile_interface)
-      << ResultType << BaseExpr->getSourceRange();
-    return ExprError();
-  }
-
   assert(VK == VK_RValue || LangOpts.CPlusPlus ||
          !ResultType.isCForbiddenLValueType());
 
@@ -4607,7 +4632,10 @@
   if (NullKind == Expr::NPCK_NotNull)
     return false;
 
-  if (NullKind == Expr::NPCK_ZeroInteger) {
+  if (NullKind == Expr::NPCK_ZeroExpression)
+    return false;
+
+  if (NullKind == Expr::NPCK_ZeroLiteral) {
     // In this case, check to make sure that we got here from a "NULL"
     // string in the source code.
     NullExpr = NullExpr->IgnoreParenImpCasts();
@@ -6173,17 +6201,12 @@
 /// \returns True if pointer has incomplete type
 static bool checkArithmeticIncompletePointerType(Sema &S, SourceLocation Loc,
                                                  Expr *Operand) {
-  if ((Operand->getType()->isPointerType() &&
-       !Operand->getType()->isDependentType()) ||
-      Operand->getType()->isObjCObjectPointerType()) {
-    QualType PointeeTy = Operand->getType()->getPointeeType();
-    if (S.RequireCompleteType(
-          Loc, PointeeTy,
-          diag::err_typecheck_arithmetic_incomplete_type,
-          PointeeTy, Operand->getSourceRange()))
-      return true;
-  }
-  return false;
+  assert(Operand->getType()->isAnyPointerType() &&
+         !Operand->getType()->isDependentType());
+  QualType PointeeTy = Operand->getType()->getPointeeType();
+  return S.RequireCompleteType(Loc, PointeeTy,
+                               diag::err_typecheck_arithmetic_incomplete_type,
+                               PointeeTy, Operand->getSourceRange());
 }
 
 /// \brief Check the validity of an arithmetic pointer operand.
@@ -6254,26 +6277,14 @@
     return !S.getLangOpts().CPlusPlus;
   }
 
-  if (checkArithmeticIncompletePointerType(S, Loc, LHSExpr)) return false;
-  if (checkArithmeticIncompletePointerType(S, Loc, RHSExpr)) return false;
+  if (isLHSPointer && checkArithmeticIncompletePointerType(S, Loc, LHSExpr))
+    return false;
+  if (isRHSPointer && checkArithmeticIncompletePointerType(S, Loc, RHSExpr))
+    return false;
 
   return true;
 }
 
-/// \brief Check bad cases where we step over interface counts.
-static bool checkArithmethicPointerOnNonFragileABI(Sema &S,
-                                                   SourceLocation OpLoc,
-                                                   Expr *Op) {
-  assert(Op->getType()->isAnyPointerType());
-  QualType PointeeTy = Op->getType()->getPointeeType();
-  if (!PointeeTy->isObjCObjectType() || S.LangOpts.ObjCRuntime.isFragile())
-    return true;
-
-  S.Diag(OpLoc, diag::err_arithmetic_nonfragile_interface)
-    << PointeeTy << Op->getSourceRange();
-  return false;
-}
-
 /// diagnoseStringPlusInt - Emit a warning when adding an integer to a string
 /// literal.
 static void diagnoseStringPlusInt(Sema &Self, SourceLocation OpLoc,
@@ -6350,13 +6361,26 @@
     return compType;
   }
 
-  // Put any potential pointer into PExp
-  Expr* PExp = LHS.get(), *IExp = RHS.get();
-  if (IExp->getType()->isAnyPointerType())
-    std::swap(PExp, IExp);
+  // Type-checking.  Ultimately the pointer's going to be in PExp;
+  // note that we bias towards the LHS being the pointer.
+  Expr *PExp = LHS.get(), *IExp = RHS.get();
 
-  if (!PExp->getType()->isAnyPointerType())
-    return InvalidOperands(Loc, LHS, RHS);
+  bool isObjCPointer;
+  if (PExp->getType()->isPointerType()) {
+    isObjCPointer = false;
+  } else if (PExp->getType()->isObjCObjectPointerType()) {
+    isObjCPointer = true;
+  } else {
+    std::swap(PExp, IExp);
+    if (PExp->getType()->isPointerType()) {
+      isObjCPointer = false;
+    } else if (PExp->getType()->isObjCObjectPointerType()) {
+      isObjCPointer = true;
+    } else {
+      return InvalidOperands(Loc, LHS, RHS);
+    }
+  }
+  assert(PExp->getType()->isAnyPointerType());
 
   if (!IExp->getType()->isIntegerType())
     return InvalidOperands(Loc, LHS, RHS);
@@ -6364,8 +6388,7 @@
   if (!checkArithmeticOpPointerOperand(*this, Loc, PExp))
     return QualType();
 
-  // Diagnose bad cases where we step over interface counts.
-  if (!checkArithmethicPointerOnNonFragileABI(*this, Loc, PExp))
+  if (isObjCPointer && checkArithmeticOnObjCPointer(*this, Loc, PExp))
     return QualType();
 
   // Check array bounds for pointer arithemtic
@@ -6414,7 +6437,8 @@
     QualType lpointee = LHS.get()->getType()->getPointeeType();
 
     // Diagnose bad cases where we step over interface counts.
-    if (!checkArithmethicPointerOnNonFragileABI(*this, Loc, LHS.get()))
+    if (LHS.get()->getType()->isObjCObjectPointerType() &&
+        checkArithmeticOnObjCPointer(*this, Loc, LHS.get()))
       return QualType();
 
     // The result type of a pointer-int computation is the pointer type.
@@ -7746,14 +7770,16 @@
     S.Diag(OpLoc, diag::warn_increment_bool) << Op->getSourceRange();
   } else if (ResType->isRealType()) {
     // OK!
-  } else if (ResType->isAnyPointerType()) {
+  } else if (ResType->isPointerType()) {
     // C99 6.5.2.4p2, 6.5.6p2
     if (!checkArithmeticOpPointerOperand(S, OpLoc, Op))
       return QualType();
-
-    // Diagnose bad cases where we step over interface counts.
-    else if (!checkArithmethicPointerOnNonFragileABI(S, OpLoc, Op))
-      return QualType();
+  } else if (ResType->isObjCObjectPointerType()) {
+    // On modern runtimes, ObjC pointer arithmetic is forbidden.
+    // Otherwise, we just need a complete type.
+    if (checkArithmeticIncompletePointerType(S, OpLoc, Op) ||
+        checkArithmeticOnObjCPointer(S, OpLoc, Op))
+      return QualType();    
   } else if (ResType->isAnyComplexType()) {
     // C99 does not support ++/-- on complex types, we allow as an extension.
     S.Diag(OpLoc, diag::ext_integer_increment_complex)
@@ -9435,7 +9461,8 @@
 
   // If needed, diagnose invalid gotos and switches in the block.
   if (getCurFunction()->NeedsScopeChecking() &&
-      !hasAnyUnrecoverableErrorsInThisFunction())
+      !hasAnyUnrecoverableErrorsInThisFunction() &&
+      !PP.isCodeCompletionEnabled())
     DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
 
   BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
@@ -10019,7 +10046,7 @@
     // Error on DeclRefExprs referring to FieldDecls.
     ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
       if (isa<FieldDecl>(E->getDecl()) &&
-          SemaRef.ExprEvalContexts.back().Context != Sema::Unevaluated)
+          !SemaRef.isUnevaluatedContext())
         return SemaRef.Diag(E->getLocation(),
                             diag::err_invalid_non_static_member_use)
             << E->getDecl() << E->getSourceRange();
@@ -10224,11 +10251,11 @@
   // FIXME: Is this really right?
   if (CurContext == Func) return;
 
-  // Instantiate the exception specification for any function which is
+  // Resolve the exception specification for any function which is
   // used: CodeGen will need it.
   const FunctionProtoType *FPT = Func->getType()->getAs<FunctionProtoType>();
-  if (FPT && FPT->getExceptionSpecType() == EST_Uninstantiated)
-    InstantiateExceptionSpec(Loc, Func);
+  if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
+    ResolveExceptionSpec(Loc, FPT);
 
   // Implicit instantiation of function templates and member functions of
   // class templates.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index ec4bf82..2740259 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -333,7 +333,7 @@
       //   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->Classify(Context).isGLValue()) {
+      if (RecordD->isPolymorphic() && E->isGLValue()) {
         // The subexpression is potentially evaluated; switch the context
         // and recheck the subexpression.
         ExprResult Result = TranformToPotentiallyEvaluated(E);
@@ -3190,8 +3190,6 @@
             CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
             if (!CPT)
               return false;
-            if (CPT->getExceptionSpecType() == EST_Delayed)
-              return false;
             if (!CPT->isNothrow(Self.Context))
               return false;
           }
@@ -3232,8 +3230,6 @@
           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
           if (!CPT)
             return false;
-          if (CPT->getExceptionSpecType() == EST_Delayed)
-            return false;
           // FIXME: check whether evaluating default arguments can throw.
           // For now, we'll be conservative and assume that they can throw.
           if (!CPT->isNothrow(Self.Context) || CPT->getNumArgs() > 1)
@@ -3270,8 +3266,6 @@
           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
           if (!CPT)
             return false;
-          if (CPT->getExceptionSpecType() == EST_Delayed)
-            return false;
           // TODO: check whether evaluating default arguments can throw.
           // For now, we'll be conservative and assume that they can throw.
           return CPT->isNothrow(Self.Context) && CPT->getNumArgs() == 0;
@@ -3548,9 +3542,25 @@
     // We model the initialization as a copy-initialization of a temporary
     // of the appropriate type, which for this expression is identical to the
     // return statement (since NRVO doesn't apply).
+
+    // Functions aren't allowed to return function or array types.
+    if (RhsT->isFunctionType() || RhsT->isArrayType())
+      return false;
+
+    // A return statement in a void function must have void type.
+    if (RhsT->isVoidType())
+      return LhsT->isVoidType();
+
+    // A function definition requires a complete, non-abstract return type.
+    if (Self.RequireCompleteType(KeyLoc, RhsT, 0) ||
+        Self.RequireNonAbstractType(KeyLoc, RhsT, 0))
+      return false;
+
+    // Compute the result of add_rvalue_reference.
     if (LhsT->isObjectType() || LhsT->isFunctionType())
       LhsT = Self.Context.getRValueReferenceType(LhsT);
-    
+
+    // Build a fake source and destination for initialization.
     InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT));
     OpaqueValueExpr From(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
                          Expr::getValueKindForType(LhsT));
@@ -4106,13 +4116,14 @@
 ///
 /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y
 /// extension. In this case, LHS == Cond. (But they're not aliases.)
-QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS,
-                                           ExprValueKind &VK, ExprObjectKind &OK,
+QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
+                                           ExprResult &RHS, ExprValueKind &VK,
+                                           ExprObjectKind &OK,
                                            SourceLocation QuestionLoc) {
   // FIXME: Handle C99's complex types, vector types, block pointers and Obj-C++
   // interface pointers.
 
-  // C++0x 5.16p1
+  // C++11 [expr.cond]p1
   //   The first expression is contextually converted to bool.
   if (!Cond.get()->isTypeDependent()) {
     ExprResult CondRes = CheckCXXBooleanCondition(Cond.take());
@@ -4129,7 +4140,7 @@
   if (LHS.get()->isTypeDependent() || RHS.get()->isTypeDependent())
     return Context.DependentTy;
 
-  // C++0x 5.16p2
+  // C++11 [expr.cond]p2
   //   If either the second or the third operand has type (cv) void, ...
   QualType LTy = LHS.get()->getType();
   QualType RTy = RHS.get()->getType();
@@ -4142,12 +4153,26 @@
     RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
     if (LHS.isInvalid() || RHS.isInvalid())
       return QualType();
+
+    // Finish off the lvalue-to-rvalue conversion by copy-initializing a
+    // temporary if necessary. DefaultFunctionArrayLvalueConversion doesn't
+    // do this part for us.
+    ExprResult &NonVoid = LVoid ? RHS : LHS;
+    if (NonVoid.get()->getType()->isRecordType() &&
+        NonVoid.get()->isGLValue()) {
+      InitializedEntity Entity =
+          InitializedEntity::InitializeTemporary(NonVoid.get()->getType());
+      NonVoid = PerformCopyInitialization(Entity, SourceLocation(), NonVoid);
+      if (NonVoid.isInvalid())
+        return QualType();
+    }
+
     LTy = LHS.get()->getType();
     RTy = RHS.get()->getType();
 
     //   ... and one of the following shall hold:
     //   -- The second or the third operand (but not both) is a throw-
-    //      expression; the result is of the type of the other and is an rvalue.
+    //      expression; the result is of the type of the other and is a prvalue.
     bool LThrow = isa<CXXThrowExpr>(LHS.get());
     bool RThrow = isa<CXXThrowExpr>(RHS.get());
     if (LThrow && !RThrow)
@@ -4156,7 +4181,7 @@
       return LTy;
 
     //   -- Both the second and third operands have type void; the result is of
-    //      type void and is an rvalue.
+    //      type void and is a prvalue.
     if (LVoid && RVoid)
       return Context.VoidTy;
 
@@ -4169,10 +4194,10 @@
 
   // Neither is void.
 
-  // C++0x 5.16p3
+  // C++11 [expr.cond]p3
   //   Otherwise, if the second and third operand have different types, and
-  //   either has (cv) class type, and attempt is made to convert each of those
-  //   operands to the other.
+  //   either has (cv) class type [...] an attempt is made to convert each of
+  //   those operands to the type of the other.
   if (!Context.hasSameType(LTy, RTy) &&
       (LTy->isRecordType() || RTy->isRecordType())) {
     ImplicitConversionSequence ICSLeftToRight, ICSRightToLeft;
@@ -4205,7 +4230,31 @@
     }
   }
 
-  // C++0x 5.16p4
+  // C++11 [expr.cond]p3
+  //   if both are glvalues of the same value category and the same type except
+  //   for cv-qualification, an attempt is made to convert each of those
+  //   operands to the type of the other.
+  ExprValueKind LVK = LHS.get()->getValueKind();
+  ExprValueKind RVK = RHS.get()->getValueKind();
+  if (!Context.hasSameType(LTy, RTy) &&
+      Context.hasSameUnqualifiedType(LTy, RTy) &&
+      LVK == RVK && LVK != VK_RValue) {
+    // Since the unqualified types are reference-related and we require the
+    // result to be as if a reference bound directly, the only conversion
+    // we can perform is to add cv-qualifiers.
+    Qualifiers LCVR = Qualifiers::fromCVRMask(LTy.getCVRQualifiers());
+    Qualifiers RCVR = Qualifiers::fromCVRMask(RTy.getCVRQualifiers());
+    if (RCVR.isStrictSupersetOf(LCVR)) {
+      LHS = ImpCastExprToType(LHS.take(), RTy, CK_NoOp, LVK);
+      LTy = LHS.get()->getType();
+    }
+    else if (LCVR.isStrictSupersetOf(RCVR)) {
+      RHS = ImpCastExprToType(RHS.take(), LTy, CK_NoOp, RVK);
+      RTy = RHS.get()->getType();
+    }
+  }
+
+  // C++11 [expr.cond]p4
   //   If the second and third operands are glvalues of the same value
   //   category and have the same type, the result is of that type and
   //   value category and it is a bit-field if the second or the third
@@ -4213,9 +4262,7 @@
   // We only extend this to bitfields, not to the crazy other kinds of
   // l-values.
   bool Same = Context.hasSameType(LTy, RTy);
-  if (Same &&
-      LHS.get()->isGLValue() &&
-      LHS.get()->getValueKind() == RHS.get()->getValueKind() &&
+  if (Same && LVK == RVK && LVK != VK_RValue &&
       LHS.get()->isOrdinaryOrBitFieldObject() &&
       RHS.get()->isOrdinaryOrBitFieldObject()) {
     VK = LHS.get()->getValueKind();
@@ -4225,8 +4272,8 @@
     return LTy;
   }
 
-  // C++0x 5.16p5
-  //   Otherwise, the result is an rvalue. If the second and third operands
+  // C++11 [expr.cond]p5
+  //   Otherwise, the result is a prvalue. If the second and third operands
   //   do not have the same type, and either has (cv) class type, ...
   if (!Same && (LTy->isRecordType() || RTy->isRecordType())) {
     //   ... overload resolution is used to determine the conversions (if any)
@@ -4236,8 +4283,8 @@
       return QualType();
   }
 
-  // C++0x 5.16p6
-  //   LValue-to-rvalue, array-to-pointer, and function-to-pointer standard
+  // C++11 [expr.cond]p6
+  //   Lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
   //   conversions are performed on the second and third operands.
   LHS = DefaultFunctionArrayLvalueConversion(LHS.take());
   RHS = DefaultFunctionArrayLvalueConversion(RHS.take());
@@ -4290,9 +4337,11 @@
   }
 
   //   -- The second and third operands have pointer type, or one has pointer
-  //      type and the other is a null pointer constant; pointer conversions
-  //      and qualification conversions are performed to bring them to their
-  //      composite pointer type. The result is of the composite pointer type.
+  //      type and the other is a null pointer constant, or both are null
+  //      pointer constants, at least one of which is non-integral; pointer
+  //      conversions and qualification conversions are performed to bring them
+  //      to their composite pointer type. The result is of the composite
+  //      pointer type.
   //   -- The second and third operands have pointer to member type, or one has
   //      pointer to member type and the other is a null pointer constant;
   //      pointer to member conversions and qualification conversions are
@@ -4330,7 +4379,7 @@
 /// \brief Find a merged pointer type and convert the two expressions to it.
 ///
 /// This finds the composite pointer type (or member pointer type) for @p E1
-/// and @p E2 according to C++0x 5.9p2. It converts both expressions to this
+/// and @p E2 according to C++11 5.9p2. It converts both expressions to this
 /// type and returns it.
 /// It does not emit diagnostics.
 ///
@@ -4350,15 +4399,27 @@
   assert(getLangOpts().CPlusPlus && "This function assumes C++");
   QualType T1 = E1->getType(), T2 = E2->getType();
 
-  if (!T1->isAnyPointerType() && !T1->isMemberPointerType() &&
-      !T2->isAnyPointerType() && !T2->isMemberPointerType())
-   return QualType();
-
-  // C++0x 5.9p2
+  // C++11 5.9p2
   //   Pointer conversions and qualification conversions are performed on
   //   pointer operands to bring them to their composite pointer type. If
   //   one operand is a null pointer constant, the composite pointer type is
-  //   the type of the other operand.
+  //   std::nullptr_t if the other operand is also a null pointer constant or,
+  //   if the other operand is a pointer, the type of the other operand.
+  if (!T1->isAnyPointerType() && !T1->isMemberPointerType() &&
+      !T2->isAnyPointerType() && !T2->isMemberPointerType()) {
+    if (T1->isNullPtrType() &&
+        E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+      E2 = ImpCastExprToType(E2, T1, CK_NullToPointer).take();
+      return T1;
+    }
+    if (T2->isNullPtrType() &&
+        E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
+      E1 = ImpCastExprToType(E1, T2, CK_NullToPointer).take();
+      return T2;
+    }
+    return QualType();
+  }
+
   if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T2->isMemberPointerType())
       E1 = ImpCastExprToType(E1, T2, CK_NullToMemberPointer).take();
@@ -4789,6 +4850,11 @@
   // Disable the special decltype handling now.
   Rec.IsDecltype = false;
 
+  // In MS mode, don't perform any extra checking of call return types within a
+  // decltype expression.
+  if (getLangOpts().MicrosoftMode)
+    return Owned(E);
+
   // Perform the semantic checks we delayed until this point.
   CallExpr *TopCall = dyn_cast<CallExpr>(E);
   for (unsigned I = 0, N = Rec.DelayedDecltypeCalls.size(); I != N; ++I) {
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 3f74022..d50a979 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1156,7 +1156,7 @@
         goto fail;
       // There's an implicit 'isa' ivar on all objects.
       // But we only actually find it this way on objects of type 'id',
-      // apparently.ghjg
+      // apparently.
       if (OTy->isObjCId() && Member->isStr("isa")) {
         Diag(MemberLoc, diag::warn_objc_isa_use);
         return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc,
@@ -1269,6 +1269,7 @@
             << IV->getDeclName();
       }
     }
+    bool warn = true;
     if (getLangOpts().ObjCAutoRefCount) {
       Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
       if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
@@ -1276,10 +1277,20 @@
           BaseExp = UO->getSubExpr()->IgnoreParenCasts();
       
       if (DeclRefExpr *DE = dyn_cast<DeclRefExpr>(BaseExp))
-        if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
+        if (DE->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
           Diag(DE->getLocation(), diag::error_arc_weak_ivar_access);
+          warn = false;
+        }
     }
-
+    if (warn) {
+      if (ObjCMethodDecl *MD = getCurMethodDecl()) {
+        ObjCMethodFamily MF = MD->getMethodFamily();
+        warn = (MF != OMF_init && MF != OMF_dealloc && 
+                MF != OMF_finalize);
+      }
+      if (warn)
+        Diag(MemberLoc, diag::warn_direct_ivar_access) << IV->getDeclName();
+    }
     return Owned(new (Context) ObjCIvarRefExpr(IV, IV->getType(),
                                                MemberLoc, BaseExpr.take(),
                                                IsArrow));
@@ -1385,9 +1396,6 @@
         // methods.
         Setter = IFace->lookupPrivateMethod(SetterSel, false);
       }
-      // Look through local category implementations associated with the class.
-      if (!Setter)
-        Setter = IFace->getCategoryClassMethod(SetterSel);
 
       if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
         return ExprError();
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index a3fe7d3..0aabf8b 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -575,27 +575,33 @@
   return MaybeBindToTemporary(BoxedExpr);
 }
 
+/// Build an ObjC subscript pseudo-object expression, given that
+/// that's supported by the runtime.
 ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
                                         Expr *IndexExpr,
                                         ObjCMethodDecl *getterMethod,
                                         ObjCMethodDecl *setterMethod) {
-  // Subscripting is only supported in the non-fragile ABI.
-  if (LangOpts.ObjCRuntime.isFragile())
-    return ExprError();
+  assert(!LangOpts.ObjCRuntime.isSubscriptPointerArithmetic());
 
-  // If the expression is type-dependent, there's nothing for us to do.
-  assert ((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
-          "base or index cannot have dependent type here");
+  // We can't get dependent types here; our callers should have
+  // filtered them out.
+  assert((!BaseExpr->isTypeDependent() && !IndexExpr->isTypeDependent()) &&
+         "base or index cannot have dependent type here");
+
+  // Filter out placeholders in the index.  In theory, overloads could
+  // be preserved here, although that might not actually work correctly.
   ExprResult Result = CheckPlaceholderExpr(IndexExpr);
   if (Result.isInvalid())
     return ExprError();
   IndexExpr = Result.get();
   
-  // Perform lvalue-to-rvalue conversion.
+  // Perform lvalue-to-rvalue conversion on the base.
   Result = DefaultLvalueConversion(BaseExpr);
   if (Result.isInvalid())
     return ExprError();
   BaseExpr = Result.get();
+
+  // Build the pseudo-object expression.
   return Owned(ObjCSubscriptRefExpr::Create(Context, 
                                             BaseExpr,
                                             IndexExpr,
@@ -1247,57 +1253,6 @@
   return false;
 }
 
-// Helper method for ActOnClassMethod/ActOnInstanceMethod.
-// Will search "local" class/category implementations for a method decl.
-// If failed, then we search in class's root for an instance method.
-// Returns 0 if no method is found.
-ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
-                                          ObjCInterfaceDecl *ClassDecl) {
-  ObjCMethodDecl *Method = 0;
-  // lookup in class and all superclasses
-  while (ClassDecl && !Method) {
-    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
-      Method = ImpDecl->getClassMethod(Sel);
-
-    // Look through local category implementations associated with the class.
-    if (!Method)
-      Method = ClassDecl->getCategoryClassMethod(Sel);
-
-    // Before we give up, check if the selector is an instance method.
-    // But only in the root. This matches gcc's behaviour and what the
-    // runtime expects.
-    if (!Method && !ClassDecl->getSuperClass()) {
-      Method = ClassDecl->lookupInstanceMethod(Sel);
-      // Look through local category implementations associated
-      // with the root class.
-      if (!Method)
-        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
-    }
-
-    ClassDecl = ClassDecl->getSuperClass();
-  }
-  return Method;
-}
-
-ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
-                                              ObjCInterfaceDecl *ClassDecl) {
-  if (!ClassDecl->hasDefinition())
-    return 0;
-
-  ObjCMethodDecl *Method = 0;
-  while (ClassDecl && !Method) {
-    // If we have implementations in scope, check "private" methods.
-    if (ObjCImplementationDecl *ImpDecl = ClassDecl->getImplementation())
-      Method = ImpDecl->getInstanceMethod(Sel);
-
-    // Look through local category implementations associated with the class.
-    if (!Method)
-      Method = ClassDecl->getCategoryInstanceMethod(Sel);
-    ClassDecl = ClassDecl->getSuperClass();
-  }
-  return Method;
-}
-
 /// LookupMethodInType - Look up a method in an ObjCObjectType.
 ObjCMethodDecl *Sema::LookupMethodInObjectType(Selector sel, QualType type,
                                                bool isInstance) {
@@ -1309,13 +1264,8 @@
 
     // Okay, look for "private" methods declared in any
     // @implementations we've seen.
-    if (isInstance) {
-      if (ObjCMethodDecl *method = LookupPrivateInstanceMethod(sel, iface))
-        return method;
-    } else {
-      if (ObjCMethodDecl *method = LookupPrivateClassMethod(sel, iface))
-        return method;
-    }
+    if (ObjCMethodDecl *method = iface->lookupPrivateMethod(sel, isInstance))
+      return method;
   }
 
   // Check qualifiers.
@@ -1489,9 +1439,6 @@
   if (!Getter)
     Getter = IFace->lookupPrivateMethod(Sel);
 
-  // Look through local category implementations associated with the class.
-  if (!Getter)
-    Getter = IFace->getCategoryInstanceMethod(Sel);
   if (Getter) {
     // Check if we can reference this property.
     if (DiagnoseUseOfDecl(Getter, MemberLoc))
@@ -1513,9 +1460,6 @@
     // methods.
     Setter = IFace->lookupPrivateMethod(SetterSel);
   }
-  // Look through local category implementations associated with the class.
-  if (!Setter)
-    Setter = IFace->getCategoryInstanceMethod(SetterSel);
     
   if (Setter && DiagnoseUseOfDecl(Setter, MemberLoc))
     return ExprError();
@@ -1834,9 +1778,9 @@
   // is acting as a keyword.
   if (Method->isInstanceMethod()) {
     if (Sel.getMethodFamily() == OMF_dealloc)
-      ObjCShouldCallSuperDealloc = false;
+      getCurFunction()->ObjCShouldCallSuperDealloc = false;
     if (Sel.getMethodFamily() == OMF_finalize)
-      ObjCShouldCallSuperFinalize = false;
+      getCurFunction()->ObjCShouldCallSuperFinalize = false;
 
     // Since we are in an instance method, this is an instance
     // message to the superclass instance.
@@ -2010,7 +1954,7 @@
 
     // If we have an implementation in scope, check "private" methods.
     if (!Method)
-      Method = LookupPrivateClassMethod(Sel, Class);
+      Method = Class->lookupPrivateClassMethod(Sel);
 
     if (Method && DiagnoseUseOfDecl(Method, Loc))
       return ExprError();
@@ -2207,7 +2151,7 @@
             Method = ClassDecl->lookupClassMethod(Sel);
 
             if (!Method)
-              Method = LookupPrivateClassMethod(Sel, ClassDecl);
+              Method = ClassDecl->lookupPrivateClassMethod(Sel);
           }
           if (Method && DiagnoseUseOfDecl(Method, Loc))
             return ExprError();
@@ -2280,7 +2224,7 @@
         
         if (!Method) {
           // If we have implementations in scope, check "private" methods.
-          Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+          Method = ClassDecl->lookupPrivateMethod(Sel);
 
           if (!Method && getLangOpts().ObjCAutoRefCount) {
             Diag(Loc, diag::err_arc_may_not_respond)
@@ -2603,6 +2547,7 @@
     ASTContext &Context;
     ARCConversionTypeClass SourceClass;
     ARCConversionTypeClass TargetClass;
+    bool Diagnose;
 
     static bool isCFType(QualType type) {
       // Someday this can use ns_bridged.  For now, it has to do this.
@@ -2611,8 +2556,9 @@
 
   public:
     ARCCastChecker(ASTContext &Context, ARCConversionTypeClass source,
-                   ARCConversionTypeClass target)
-      : Context(Context), SourceClass(source), TargetClass(target) {}
+                   ARCConversionTypeClass target, bool diagnose)
+      : Context(Context), SourceClass(source), TargetClass(target),
+        Diagnose(diagnose) {}
 
     using super::Visit;
     ACCResult Visit(Expr *e) {
@@ -2730,7 +2676,8 @@
       // now we're not going to permit implicit handling of +1 results,
       // because it's a bit frightening.
       if (fn->hasAttr<CFReturnsRetainedAttr>())
-        return ACC_invalid; // ACC_plusOne if we start accepting this
+        return Diagnose ? ACC_plusOne
+                        : ACC_invalid; // ACC_plusOne if we start accepting this
 
       // Recognize this specific builtin function, which is used by CFSTR.
       unsigned builtinID = fn->getBuiltinID();
@@ -2740,10 +2687,11 @@
       // Otherwise, don't do anything implicit with an unaudited function.
       if (!fn->hasAttr<CFAuditedTransferAttr>())
         return ACC_invalid;
-
+      
       // Otherwise, it's +0 unless it follows the create convention.
       if (ento::coreFoundation::followsCreateRule(fn))
-        return ACC_invalid; // ACC_plusOne if we start accepting this
+        return Diagnose ? ACC_plusOne 
+                        : ACC_invalid; // ACC_plusOne if we start accepting this
 
       return ACC_plusZero;
     }
@@ -2918,11 +2866,16 @@
       << castRange
       << castExpr->getSourceRange();
     bool br = S.isKnownName("CFBridgingRelease");
+    ACCResult CreateRule = 
+      ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
+    assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
+    if (CreateRule != ACC_plusOne)
     {
       DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
                                    castType, castExpr, "__bridge ", 0);
     }
+    if (CreateRule != ACC_plusZero)
     {
       DiagnosticBuilder DiagB = S.Diag(br ? castExpr->getExprLoc() : noteLoc,
                                        diag::note_arc_bridge_transfer)
@@ -2946,12 +2899,16 @@
       << castType
       << castRange
       << castExpr->getSourceRange();
-
+    ACCResult CreateRule = 
+      ARCCastChecker(S.Context, exprACTC, castACTC, true).Visit(castExpr);
+    assert(CreateRule != ACC_bottom && "This cast should already be accepted.");
+    if (CreateRule != ACC_plusOne)
     {
       DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge);
       addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen,
                                    castType, castExpr, "__bridge ", 0);
     }
+    if (CreateRule != ACC_plusZero)
     {
       DiagnosticBuilder DiagB = S.Diag(br ? castExpr->getExprLoc() : noteLoc,
                                        diag::note_arc_bridge_retained)
@@ -3027,7 +2984,7 @@
       CCK != CCK_ImplicitConversion)
     return ACR_okay;
 
-  switch (ARCCastChecker(Context, exprACTC, castACTC).Visit(castExpr)) {
+  switch (ARCCastChecker(Context, exprACTC, castACTC, false).Visit(castExpr)) {
   // For invalid casts, fall through.
   case ACC_invalid:
     break;
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 0e5a02f..62ab1e6 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -92,8 +92,7 @@
   if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
     // C99 6.7.8p14. We have an array of character type with unknown size
     // being initialized to a string literal.
-    llvm::APSInt ConstVal(32);
-    ConstVal = StrLength;
+    llvm::APInt ConstVal(32, StrLength);
     // Return a new array type (C99 6.7.8p22).
     DeclT = S.Context.getConstantArrayType(IAT->getElementType(),
                                            ConstVal,
@@ -2906,7 +2905,7 @@
   //   user-provided default constructor.
   if (Kind.getKind() == InitializationKind::IK_Default &&
       Entity.getType().isConstQualified() &&
-      cast<CXXConstructorDecl>(Best->Function)->isImplicit()) {
+      !cast<CXXConstructorDecl>(Best->Function)->isUserProvided()) {
     Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);
     return;
   }
@@ -6179,8 +6178,8 @@
   Expr *InitE = Init.get();
   assert(InitE && "No initialization expression");
 
-  InitializationKind Kind = InitializationKind::CreateCopy(SourceLocation(),
-                                                           SourceLocation());
+  InitializationKind Kind
+    = InitializationKind::CreateCopy(InitE->getLocStart(), SourceLocation());
   InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
   return !Seq.Failed();
 }
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index 25d27f4..6414c6f 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -375,6 +375,7 @@
   TypeSourceInfo *MethodTyInfo;
   bool ExplicitParams = true;
   bool ExplicitResultType = true;
+  bool ContainsUnexpandedParameterPack = false;
   SourceLocation EndLoc;
   llvm::ArrayRef<ParmVarDecl *> Params;
   if (ParamInfo.getNumTypeObjects() == 0) {
@@ -416,21 +417,8 @@
                                            Proto.getNumArgs());
 
     // Check for unexpanded parameter packs in the method type.
-    // FIXME: We should allow unexpanded parameter packs here, but that would,
-    // in turn, make the lambda expression contain unexpanded parameter packs.
-    if (DiagnoseUnexpandedParameterPack(Intro.Range.getBegin(), MethodTyInfo,
-                                        UPPC_Lambda)) {
-      // Drop the parameters.
-      Params = llvm::ArrayRef<ParmVarDecl *>();
-      FunctionProtoType::ExtProtoInfo EPI;
-      EPI.HasTrailingReturn = false;
-      EPI.TypeQuals |= DeclSpec::TQ_const;
-      QualType MethodTy = Context.getFunctionType(Context.DependentTy,
-                                                  /*Args=*/0, /*NumArgs=*/0, EPI);
-      MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy);
-      ExplicitParams = false;
-      ExplicitResultType = false;
-    }
+    if (MethodTyInfo->getType()->containsUnexpandedParameterPack())
+      ContainsUnexpandedParameterPack = true;
   }
   
   CXXMethodDecl *Method = startLambdaDefinition(Class, Intro.Range,
@@ -449,7 +437,7 @@
   LambdaScopeInfo *LSI
     = enterLambdaScope(Method, Intro.Range, Intro.Default, ExplicitParams,
                        ExplicitResultType,
-                       (Method->getTypeQualifiers() & Qualifiers::Const) == 0);
+                       !Method->isConst());
  
   // Handle explicit captures.
   SourceLocation PrevCaptureLoc
@@ -571,8 +559,7 @@
         // Just ignore the ellipsis.
       }
     } else if (Var->isParameterPack()) {
-      Diag(C->Loc, diag::err_lambda_unexpanded_pack);
-      continue;
+      ContainsUnexpandedParameterPack = true;
     }
     
     TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
@@ -581,6 +568,8 @@
   }
   finishLambdaExplicitCaptures(LSI);
 
+  LSI->ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack;
+
   // Add lambda parameters into scope.
   addLambdaParameters(Method, CurScope);
 
@@ -743,6 +732,7 @@
   bool ExplicitParams;
   bool ExplicitResultType;
   bool LambdaExprNeedsCleanups;
+  bool ContainsUnexpandedParameterPack;
   llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
   llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
   {
@@ -753,6 +743,7 @@
     ExplicitParams = LSI->ExplicitParams;
     ExplicitResultType = !LSI->HasImplicitReturnType;
     LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
+    ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
     ArrayIndexVars.swap(LSI->ArrayIndexVars);
     ArrayIndexStarts.swap(LSI->ArrayIndexStarts);
     
@@ -867,7 +858,8 @@
                                           CaptureDefault, Captures, 
                                           ExplicitParams, ExplicitResultType,
                                           CaptureInits, ArrayIndexVars, 
-                                          ArrayIndexStarts, Body->getLocEnd());
+                                          ArrayIndexStarts, Body->getLocEnd(),
+                                          ContainsUnexpandedParameterPack);
 
   // C++11 [expr.prim.lambda]p2:
   //   A lambda-expression shall not appear in an unevaluated operand
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index e280705..dad196b 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3895,13 +3895,13 @@
       // If a validator callback object was given, drop the correction
       // unless it passes validation.
       bool Viable = false;
-      for (TypoResultList::iterator RI = I->second.begin(), RIEnd = I->second.end();
-           RI != RIEnd; /* Increment in loop. */) {
+      for (TypoResultList::iterator RI = I->second.begin();
+           RI != I->second.end(); /* Increment in loop. */) {
         TypoResultList::iterator Prev = RI;
         ++RI;
         if (Prev->isResolved()) {
           if (!isCandidateViable(CCC, *Prev))
-            I->second.erase(Prev);
+            RI = I->second.erase(Prev);
           else
             Viable = true;
         }
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 335dad1..e465cd6 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -43,7 +43,7 @@
   if (attrs & (ObjCPropertyDecl::OBJC_PR_retain |
                ObjCPropertyDecl::OBJC_PR_strong |
                ObjCPropertyDecl::OBJC_PR_copy)) {
-    return type->getObjCARCImplicitLifetime();
+    return Qualifiers::OCL_Strong;
   } else if (attrs & ObjCPropertyDecl::OBJC_PR_weak) {
     return Qualifiers::OCL_Weak;
   } else if (attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) {
@@ -102,6 +102,15 @@
     << propertyLifetime;
 }
 
+static unsigned deduceWeakPropertyFromType(Sema &S, QualType T) {
+  if ((S.getLangOpts().getGC() != LangOptions::NonGC && 
+       T.isObjCGCWeak()) ||
+      (S.getLangOpts().ObjCAutoRefCount &&
+       T.getObjCLifetime() == Qualifiers::OCL_Weak))
+    return ObjCDeclSpec::DQ_PR_weak;
+  return 0;
+}
+
 Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
                           SourceLocation LParenLoc,
                           FieldDeclarator &FD,
@@ -114,12 +123,8 @@
   unsigned Attributes = ODS.getPropertyAttributes();
   TypeSourceInfo *TSI = GetTypeForDeclarator(FD.D, S);
   QualType T = TSI->getType();
-  if ((getLangOpts().getGC() != LangOptions::NonGC && 
-       T.isObjCGCWeak()) ||
-      (getLangOpts().ObjCAutoRefCount &&
-       T.getObjCLifetime() == Qualifiers::OCL_Weak))
-    Attributes |= ObjCDeclSpec::DQ_PR_weak;
-
+  Attributes |= deduceWeakPropertyFromType(*this, T);
+  
   bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
                       // default is readwrite!
                       !(Attributes & ObjCDeclSpec::DQ_PR_readonly));
@@ -236,6 +241,15 @@
   
 }
 
+static unsigned getOwnershipRule(unsigned attr) {
+  return attr & (ObjCPropertyDecl::OBJC_PR_assign |
+                 ObjCPropertyDecl::OBJC_PR_retain |
+                 ObjCPropertyDecl::OBJC_PR_copy   |
+                 ObjCPropertyDecl::OBJC_PR_weak   |
+                 ObjCPropertyDecl::OBJC_PR_strong |
+                 ObjCPropertyDecl::OBJC_PR_unsafe_unretained);
+}
+
 Decl *
 Sema::HandlePropertyInClassExtension(Scope *S,
                                      SourceLocation AtLoc,
@@ -342,13 +356,11 @@
   // with continuation class's readwrite property attribute!
   unsigned PIkind = PIDecl->getPropertyAttributesAsWritten();
   if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
-    unsigned retainCopyNonatomic =
-    (ObjCPropertyDecl::OBJC_PR_retain |
-     ObjCPropertyDecl::OBJC_PR_strong |
-     ObjCPropertyDecl::OBJC_PR_copy |
-     ObjCPropertyDecl::OBJC_PR_nonatomic);
-    if ((Attributes & retainCopyNonatomic) !=
-        (PIkind & retainCopyNonatomic)) {
+    PIkind |= deduceWeakPropertyFromType(*this, PIDecl->getType());
+    unsigned ClassExtensionMemoryModel = getOwnershipRule(Attributes);
+    unsigned PrimaryClassMemoryModel = getOwnershipRule(PIkind);
+    if (PrimaryClassMemoryModel && ClassExtensionMemoryModel &&
+        (PrimaryClassMemoryModel != ClassExtensionMemoryModel)) {
       Diag(AtLoc, diag::warn_property_attr_mismatch);
       Diag(PIDecl->getLocation(), diag::note_property_declare);
     }
@@ -543,6 +555,23 @@
       ivarLifetime == Qualifiers::OCL_Autoreleasing)
     return;
 
+  // If the ivar is private, and it's implicitly __unsafe_unretained
+  // becaues of its type, then pretend it was actually implicitly
+  // __strong.  This is only sound because we're processing the
+  // property implementation before parsing any method bodies.
+  if (ivarLifetime == Qualifiers::OCL_ExplicitNone &&
+      propertyLifetime == Qualifiers::OCL_Strong &&
+      ivar->getAccessControl() == ObjCIvarDecl::Private) {
+    SplitQualType split = ivarType.split();
+    if (split.Quals.hasObjCLifetime()) {
+      assert(ivarType->isObjCARCImplicitlyUnretainedType());
+      split.Quals.setObjCLifetime(Qualifiers::OCL_Strong);
+      ivarType = S.Context.getQualifiedType(split);
+      ivar->setType(ivarType);
+      return;
+    }
+  }
+
   switch (propertyLifetime) {
   case Qualifiers::OCL_Strong:
     S.Diag(propertyImplLoc, diag::err_arc_strong_property_ownership)
@@ -730,8 +759,6 @@
         (PIkind & ObjCPropertyDecl::OBJC_PR_readonly) &&
         property->hasAttr<IBOutletAttr>() &&
         !AtLoc.isValid()) {
-      unsigned rwPIKind = (PIkind | ObjCPropertyDecl::OBJC_PR_readwrite);
-      rwPIKind &= (~ObjCPropertyDecl::OBJC_PR_readonly);
       Diag(IC->getLocation(), diag::warn_auto_readonly_iboutlet_property);
       Diag(property->getLocation(), diag::note_property_declare);
       SourceLocation readonlyLoc;
@@ -865,7 +892,7 @@
                 Diag(property->getLocation(), diag::note_property_declare);
                 err = true;
               }
-            if (!err && !getLangOpts().ObjCRuntimeHasWeak) {
+            if (!err && !getLangOpts().ObjCARCWeak) {
               Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime);
               Diag(property->getLocation(), diag::note_property_declare);
             }
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index bdf6f60..efc5b6e 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -57,7 +57,7 @@
                                  StandardConversionSequence &SCS,
                                  bool CStyle,
                                  bool AllowObjCWritebackConversion);
-  
+
 static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, 
                                                  QualType &ToType,
                                                  bool InOverloadResolution,
@@ -2562,13 +2562,17 @@
 
   Kind = CK_BitCast;
 
-  if (!IsCStyleOrFunctionalCast &&
-      Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy) &&
-      From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
-    DiagRuntimeBehavior(From->getExprLoc(), From,
-                        PDiag(diag::warn_impcast_bool_to_null_pointer)
-                          << ToType << From->getSourceRange());
-
+  if (!IsCStyleOrFunctionalCast && !FromType->isAnyPointerType() &&
+      From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) ==
+      Expr::NPCK_ZeroExpression) {
+    if (Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy))
+      DiagRuntimeBehavior(From->getExprLoc(), From,
+                          PDiag(diag::warn_impcast_bool_to_null_pointer)
+                            << ToType << From->getSourceRange());
+    else if (!isUnevaluatedContext())
+      Diag(From->getExprLoc(), diag::warn_non_literal_null_pointer)
+        << ToType << From->getSourceRange();
+  }
   if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) {
     if (const PointerType *FromPtrType = FromType->getAs<PointerType>()) {
       QualType FromPointeeType = FromPtrType->getPointeeType(),
@@ -9332,7 +9336,7 @@
       return true;
     }
 
-    // Fix the expresion to refer to 'fn'.
+    // Fix the expression to refer to 'fn'.
     SingleFunctionExpression =
       Owned(FixOverloadedFunctionReference(SrcExpr.take(), found, fn));
 
@@ -9691,20 +9695,15 @@
                                RParenLoc);
 }
 
-/// ResolveOverloadedCallFn - Given the call expression that calls Fn
-/// (which eventually refers to the declaration Func) and the call
-/// arguments Args/NumArgs, attempt to resolve the function call down
-/// to a specific function. If overload resolution succeeds, returns
-/// the function declaration produced by overload
-/// resolution. Otherwise, emits diagnostics, deletes all of the
-/// arguments and Fn, and returns NULL.
-ExprResult
-Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
-                              SourceLocation LParenLoc,
-                              Expr **Args, unsigned NumArgs,
-                              SourceLocation RParenLoc,
-                              Expr *ExecConfig,
-                              bool AllowTypoCorrection) {
+/// \brief Constructs and populates an OverloadedCandidateSet from
+/// the given function.
+/// \returns true when an the ExprResult output parameter has been set.
+bool Sema::buildOverloadedCallSet(Scope *S, Expr *Fn,
+                                  UnresolvedLookupExpr *ULE,
+                                  Expr **Args, unsigned NumArgs,
+                                  SourceLocation RParenLoc,
+                                  OverloadCandidateSet *CandidateSet,
+                                  ExprResult *Result) {
 #ifndef NDEBUG
   if (ULE->requiresADL()) {
     // To do ADL, we must have found an unqualified name.
@@ -9726,20 +9725,20 @@
 #endif
 
   UnbridgedCastsSet UnbridgedCasts;
-  if (checkArgPlaceholdersForOverload(*this, Args, NumArgs, UnbridgedCasts))
-    return ExprError();
-
-  OverloadCandidateSet CandidateSet(Fn->getExprLoc());
+  if (checkArgPlaceholdersForOverload(*this, Args, NumArgs, UnbridgedCasts)) {
+    *Result = ExprError();
+    return true;
+  }
 
   // Add the functions denoted by the callee to the set of candidate
   // functions, including those from argument-dependent lookup.
   AddOverloadedCallCandidates(ULE, llvm::makeArrayRef(Args, NumArgs),
-                              CandidateSet);
+                              *CandidateSet);
 
   // If we found nothing, try to recover.
   // BuildRecoveryCallExpr diagnoses the error itself, so we just bail
   // out if it fails.
-  if (CandidateSet.empty()) {
+  if (CandidateSet->empty()) {
     // In Microsoft mode, if we are inside a template class member function then
     // create a type dependent CallExpr. The goal is to postpone name lookup
     // to instantiation time to be able to search into type dependent base
@@ -9750,32 +9749,50 @@
                                           Context.DependentTy, VK_RValue,
                                           RParenLoc);
       CE->setTypeDependent(true);
-      return Owned(CE);
+      *Result = Owned(CE);
+      return true;
     }
-    return BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc,
-                                 llvm::MutableArrayRef<Expr *>(Args, NumArgs),
-                                 RParenLoc, /*EmptyLookup=*/true,
-                                 AllowTypoCorrection);
+    return false;
   }
 
   UnbridgedCasts.restore();
+  return false;
+}
 
-  OverloadCandidateSet::iterator Best;
-  switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
+/// FinishOverloadedCallExpr - given an OverloadCandidateSet, builds and returns
+/// the completed call expression. If overload resolution fails, emits
+/// diagnostics and returns ExprError()
+static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
+                                           UnresolvedLookupExpr *ULE,
+                                           SourceLocation LParenLoc,
+                                           Expr **Args, unsigned NumArgs,
+                                           SourceLocation RParenLoc,
+                                           Expr *ExecConfig,
+                                           OverloadCandidateSet *CandidateSet,
+                                           OverloadCandidateSet::iterator *Best,
+                                           OverloadingResult OverloadResult,
+                                           bool AllowTypoCorrection) {
+  if (CandidateSet->empty())
+    return BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc,
+                                 llvm::MutableArrayRef<Expr *>(Args, NumArgs),
+                                 RParenLoc, /*EmptyLookup=*/true,
+                                 AllowTypoCorrection);
+
+  switch (OverloadResult) {
   case OR_Success: {
-    FunctionDecl *FDecl = Best->Function;
-    MarkFunctionReferenced(Fn->getExprLoc(), FDecl);
-    CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
-    DiagnoseUseOfDecl(FDecl, ULE->getNameLoc());
-    Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
-    return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc,
-                                 ExecConfig);
+    FunctionDecl *FDecl = (*Best)->Function;
+    SemaRef.MarkFunctionReferenced(Fn->getExprLoc(), FDecl);
+    SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl);
+    SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc());
+    Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
+    return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs,
+                                         RParenLoc, ExecConfig);
   }
 
   case OR_No_Viable_Function: {
     // Try to recover by looking for viable functions which the user might
     // have meant to call.
-    ExprResult Recovery = BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc,
+    ExprResult Recovery = BuildRecoveryCallExpr(SemaRef, S, Fn, ULE, LParenLoc,
                                   llvm::MutableArrayRef<Expr *>(Args, NumArgs),
                                                 RParenLoc,
                                                 /*EmptyLookup=*/false,
@@ -9783,44 +9800,73 @@
     if (!Recovery.isInvalid())
       return Recovery;
 
-    Diag(Fn->getLocStart(),
+    SemaRef.Diag(Fn->getLocStart(),
          diag::err_ovl_no_viable_function_in_call)
       << ULE->getName() << Fn->getSourceRange();
-    CandidateSet.NoteCandidates(*this, OCD_AllCandidates,
-                                llvm::makeArrayRef(Args, NumArgs));
+    CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates,
+                                 llvm::makeArrayRef(Args, NumArgs));
     break;
   }
 
   case OR_Ambiguous:
-    Diag(Fn->getLocStart(), diag::err_ovl_ambiguous_call)
+    SemaRef.Diag(Fn->getLocStart(), diag::err_ovl_ambiguous_call)
       << ULE->getName() << Fn->getSourceRange();
-    CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
-                                llvm::makeArrayRef(Args, NumArgs));
+    CandidateSet->NoteCandidates(SemaRef, OCD_ViableCandidates,
+                                 llvm::makeArrayRef(Args, NumArgs));
     break;
 
-  case OR_Deleted:
-    {
-      Diag(Fn->getLocStart(), diag::err_ovl_deleted_call)
-        << Best->Function->isDeleted()
-        << ULE->getName()
-        << getDeletedOrUnavailableSuffix(Best->Function)
-        << Fn->getSourceRange();
-      CandidateSet.NoteCandidates(*this, OCD_AllCandidates,
-                                  llvm::makeArrayRef(Args, NumArgs));
+  case OR_Deleted: {
+    SemaRef.Diag(Fn->getLocStart(), diag::err_ovl_deleted_call)
+      << (*Best)->Function->isDeleted()
+      << ULE->getName()
+      << SemaRef.getDeletedOrUnavailableSuffix((*Best)->Function)
+      << Fn->getSourceRange();
+    CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates,
+                                 llvm::makeArrayRef(Args, NumArgs));
 
-      // We emitted an error for the unvailable/deleted function call but keep
-      // the call in the AST.
-      FunctionDecl *FDecl = Best->Function;
-      Fn = FixOverloadedFunctionReference(Fn, Best->FoundDecl, FDecl);
-      return BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs,
-                                   RParenLoc, ExecConfig);
-    }
+    // We emitted an error for the unvailable/deleted function call but keep
+    // the call in the AST.
+    FunctionDecl *FDecl = (*Best)->Function;
+    Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl);
+    return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs,
+                                 RParenLoc, ExecConfig);
+  }
   }
 
   // Overload resolution failed.
   return ExprError();
 }
 
+/// BuildOverloadedCallExpr - Given the call expression that calls Fn
+/// (which eventually refers to the declaration Func) and the call
+/// arguments Args/NumArgs, attempt to resolve the function call down
+/// to a specific function. If overload resolution succeeds, returns
+/// the call expression produced by overload resolution.
+/// Otherwise, emits diagnostics and returns ExprError.
+ExprResult Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn,
+                                         UnresolvedLookupExpr *ULE,
+                                         SourceLocation LParenLoc,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RParenLoc,
+                                         Expr *ExecConfig,
+                                         bool AllowTypoCorrection) {
+  OverloadCandidateSet CandidateSet(Fn->getExprLoc());
+  ExprResult result;
+
+  if (buildOverloadedCallSet(S, Fn, ULE, Args, NumArgs, LParenLoc,
+                             &CandidateSet, &result))
+    return result;
+
+  OverloadCandidateSet::iterator Best;
+  OverloadingResult OverloadResult =
+      CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best);
+
+  return FinishOverloadedCallExpr(*this, S, Fn, ULE, LParenLoc, Args, NumArgs,
+                                  RParenLoc, ExecConfig, &CandidateSet,
+                                  &Best, OverloadResult,
+                                  AllowTypoCorrection);
+}
+
 static bool IsOverloaded(const UnresolvedSetImpl &Functions) {
   return Functions.size() > 1 ||
     (Functions.size() == 1 && isa<FunctionTemplateDecl>(*Functions.begin()));
@@ -11195,6 +11241,83 @@
   return MaybeBindToTemporary(UDL);
 }
 
+/// Build a call to 'begin' or 'end' for a C++11 for-range statement. If the
+/// given LookupResult is non-empty, it is assumed to describe a member which
+/// will be invoked. Otherwise, the function will be found via argument
+/// dependent lookup.
+/// CallExpr is set to a valid expression and FRS_Success returned on success,
+/// otherwise CallExpr is set to ExprError() and some non-success value
+/// is returned.
+Sema::ForRangeStatus
+Sema::BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc,
+                                SourceLocation RangeLoc, VarDecl *Decl,
+                                BeginEndFunction BEF,
+                                const DeclarationNameInfo &NameInfo,
+                                LookupResult &MemberLookup,
+                                OverloadCandidateSet *CandidateSet,
+                                Expr *Range, ExprResult *CallExpr) {
+  CandidateSet->clear();
+  if (!MemberLookup.empty()) {
+    ExprResult MemberRef =
+        BuildMemberReferenceExpr(Range, Range->getType(), Loc,
+                                 /*IsPtr=*/false, CXXScopeSpec(),
+                                 /*TemplateKWLoc=*/SourceLocation(),
+                                 /*FirstQualifierInScope=*/0,
+                                 MemberLookup,
+                                 /*TemplateArgs=*/0);
+    if (MemberRef.isInvalid()) {
+      *CallExpr = ExprError();
+      Diag(Range->getLocStart(), diag::note_in_for_range)
+          << RangeLoc << BEF << Range->getType();
+      return FRS_DiagnosticIssued;
+    }
+    *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, MultiExprArg(), Loc, 0);
+    if (CallExpr->isInvalid()) {
+      *CallExpr = ExprError();
+      Diag(Range->getLocStart(), diag::note_in_for_range)
+          << RangeLoc << BEF << Range->getType();
+      return FRS_DiagnosticIssued;
+    }
+  } else {
+    UnresolvedSet<0> FoundNames;
+    // C++11 [stmt.ranged]p1: For the purposes of this name lookup, namespace
+    // std is an associated namespace.
+    UnresolvedLookupExpr *Fn =
+      UnresolvedLookupExpr::Create(Context, /*NamingClass=*/0,
+                                   NestedNameSpecifierLoc(), NameInfo,
+                                   /*NeedsADL=*/true, /*Overloaded=*/false,
+                                   FoundNames.begin(), FoundNames.end(),
+                                   /*LookInStdNamespace=*/true);
+
+    bool CandidateSetError = buildOverloadedCallSet(S, Fn, Fn, &Range, 1, Loc,
+                                                    CandidateSet, CallExpr);
+    if (CandidateSet->empty() || CandidateSetError) {
+      *CallExpr = ExprError();
+      return FRS_NoViableFunction;
+    }
+    OverloadCandidateSet::iterator Best;
+    OverloadingResult OverloadResult =
+        CandidateSet->BestViableFunction(*this, Fn->getLocStart(), Best);
+
+    if (OverloadResult == OR_No_Viable_Function) {
+      *CallExpr = ExprError();
+      return FRS_NoViableFunction;
+    }
+    *CallExpr = FinishOverloadedCallExpr(*this, S, Fn, Fn, Loc, &Range, 1,
+                                         Loc, 0, CandidateSet, &Best,
+                                         OverloadResult,
+                                         /*AllowTypoCorrection=*/false);
+    if (CallExpr->isInvalid() || OverloadResult != OR_Success) {
+      *CallExpr = ExprError();
+      Diag(Range->getLocStart(), diag::note_in_for_range)
+          << RangeLoc << BEF << Range->getType();
+      return FRS_DiagnosticIssued;
+    }
+  }
+  return FRS_Success;
+}
+
+
 /// FixOverloadedFunctionReference - E is an expression that refers to
 /// a C++ overloaded function (possibly with some parentheses and
 /// perhaps a '&' around it). We have resolved the overloaded function
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index 4921ec9..722ac19 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -955,6 +955,27 @@
   return OS_Error;
 }
 
+/// CheckKeyForObjCARCConversion - This routine suggests bridge casting of CF
+/// objects used as dictionary subscript key objects.
+static void CheckKeyForObjCARCConversion(Sema &S, QualType ContainerT, 
+                                         Expr *Key) {
+  if (ContainerT.isNull())
+    return;
+  // dictionary subscripting.
+  // - (id)objectForKeyedSubscript:(id)key;
+  IdentifierInfo *KeyIdents[] = {
+    &S.Context.Idents.get("objectForKeyedSubscript")  
+  };
+  Selector GetterSelector = S.Context.Selectors.getSelector(1, KeyIdents);
+  ObjCMethodDecl *Getter = S.LookupMethodInObjectType(GetterSelector, ContainerT, 
+                                                      true /*instance*/);
+  if (!Getter)
+    return;
+  QualType T = Getter->param_begin()[0]->getType();
+  S.CheckObjCARCConversion(Key->getSourceRange(), 
+                         T, Key, Sema::CCK_ImplicitConversion);
+}
+
 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
   if (AtIndexGetter)
     return true;
@@ -972,8 +993,12 @@
   }
   Sema::ObjCSubscriptKind Res = 
     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
-  if (Res == Sema::OS_Error)
+  if (Res == Sema::OS_Error) {
+    if (S.getLangOpts().ObjCAutoRefCount)
+      CheckKeyForObjCARCConversion(S, ResultType, 
+                                   RefExpr->getKeyExpr());
     return false;
+  }
   bool arrayRef = (Res == Sema::OS_Array);
   
   if (ResultType.isNull()) {
@@ -1080,8 +1105,12 @@
   
   Sema::ObjCSubscriptKind Res = 
     S.CheckSubscriptingKind(RefExpr->getKeyExpr());
-  if (Res == Sema::OS_Error)
+  if (Res == Sema::OS_Error) {
+    if (S.getLangOpts().ObjCAutoRefCount)
+      CheckKeyForObjCARCConversion(S, ResultType, 
+                                   RefExpr->getKeyExpr());
     return false;
+  }
   bool arrayRef = (Res == Sema::OS_Array);
   
   if (ResultType.isNull()) {
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9affe98..8367c1a2 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -656,7 +656,7 @@
     = CondExpr->isTypeDependent() || CondExpr->isValueDependent();
   unsigned CondWidth
     = HasDependentValue ? 0 : Context.getIntWidth(CondTypeBeforePromotion);
-  bool CondIsSigned 
+  bool CondIsSigned
     = CondTypeBeforePromotion->isSignedIntegerOrEnumerationType();
 
   // Accumulate all of the case values in a vector so that we can sort them
@@ -973,7 +973,7 @@
             << CondTypeBeforePromotion;
         }
 
-        llvm::APSInt Hi = 
+        llvm::APSInt Hi =
           RI->second->getRHS()->EvaluateKnownConstInt(Context);
         AdjustAPSInt(Hi, CondWidth, CondIsSigned);
         while (EI != EIend && EI->first < Hi)
@@ -1021,12 +1021,12 @@
       switch (UnhandledNames.size()) {
       case 0: break;
       case 1:
-        Diag(CondExpr->getExprLoc(), TheDefaultStmt 
+        Diag(CondExpr->getExprLoc(), TheDefaultStmt
           ? diag::warn_def_missing_case1 : diag::warn_missing_case1)
           << UnhandledNames[0];
         break;
       case 2:
-        Diag(CondExpr->getExprLoc(), TheDefaultStmt 
+        Diag(CondExpr->getExprLoc(), TheDefaultStmt
           ? diag::warn_def_missing_case2 : diag::warn_missing_case2)
           << UnhandledNames[0] << UnhandledNames[1];
         break;
@@ -1063,10 +1063,10 @@
 Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
                              Expr *SrcExpr) {
   unsigned DIAG = diag::warn_not_in_enum_assignement;
-  if (Diags.getDiagnosticLevel(DIAG, SrcExpr->getExprLoc()) 
+  if (Diags.getDiagnosticLevel(DIAG, SrcExpr->getExprLoc())
       == DiagnosticsEngine::Ignored)
     return;
-  
+
   if (const EnumType *ET = DstType->getAs<EnumType>())
     if (!Context.hasSameType(SrcType, DstType) &&
         SrcType->isIntegerType()) {
@@ -1081,7 +1081,7 @@
         typedef SmallVector<std::pair<llvm::APSInt, EnumConstantDecl*>, 64>
         EnumValsTy;
         EnumValsTy EnumVals;
-        
+
         // Gather all enum values, set their type and sort them,
         // allowing easier comparison with rhs constant.
         for (EnumDecl::enumerator_iterator EDI = ED->enumerator_begin();
@@ -1095,7 +1095,7 @@
         std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals);
         EnumValsTy::iterator EIend =
         std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
-        
+
         // See which case values aren't in enum.
         EnumValsTy::const_iterator EI = EnumVals.begin();
         while (EI != EIend && EI->first < RhsVal)
@@ -1236,7 +1236,7 @@
   }; // end class DeclExtractor
 
   // DeclMatcher checks to see if the decls are used in a non-evauluated
-  // context.  
+  // context.
   class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> {
     llvm::SmallPtrSet<VarDecl*, 8> &Decls;
     bool FoundDecl;
@@ -1435,7 +1435,7 @@
 Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) {
   if (!collection)
     return ExprError();
-  
+
   // Bail out early if we've got a type-dependent expression.
   if (collection->isTypeDependent()) return Owned(collection);
 
@@ -1460,7 +1460,7 @@
 
   // If we have a forward-declared type, we can't do this check.
   // Under ARC, it is an error not to have a forward-declared class.
-  if (iface && 
+  if (iface &&
       RequireCompleteType(forLoc, QualType(objectType, 0),
                           getLangOpts().ObjCAutoRefCount
                             ? diag::err_arc_collection_forward
@@ -1481,7 +1481,7 @@
     // If there's an interface, look in both the public and private APIs.
     if (iface) {
       method = iface->lookupInstanceMethod(selector);
-      if (!method) method = LookupPrivateInstanceMethod(selector, iface);
+      if (!method) method = iface->lookupPrivateMethod(selector);
     }
 
     // Also check protocol qualifiers.
@@ -1504,13 +1504,12 @@
 
 StmtResult
 Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
-                                 SourceLocation LParenLoc,
                                  Stmt *First, Expr *collection,
                                  SourceLocation RParenLoc) {
-  
-  ExprResult CollectionExprResult = 
+
+  ExprResult CollectionExprResult =
     CheckObjCForCollectionOperand(ForLoc, collection);
-  
+
   if (First) {
     QualType FirstType;
     if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
@@ -1541,34 +1540,15 @@
         return StmtError(Diag(ForLoc, diag::err_selector_element_type)
                            << FirstType << First->getSourceRange());
   }
-  
+
   if (CollectionExprResult.isInvalid())
     return StmtError();
-  
-  return Owned(new (Context) ObjCForCollectionStmt(First, 
-                                                   CollectionExprResult.take(), 0, 
+
+  return Owned(new (Context) ObjCForCollectionStmt(First,
+                                                   CollectionExprResult.take(), 0,
                                                    ForLoc, RParenLoc));
 }
 
-namespace {
-
-enum BeginEndFunction {
-  BEF_begin,
-  BEF_end
-};
-
-/// Build a variable declaration for a for-range statement.
-static VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,
-                                     QualType Type, const char *Name) {
-  DeclContext *DC = SemaRef.CurContext;
-  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
-  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
-  VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type,
-                                  TInfo, SC_Auto, SC_None);
-  Decl->setImplicit();
-  return Decl;
-}
-
 /// Finish building a variable declaration for a for-range statement.
 /// \return true if an error occurs.
 static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
@@ -1590,7 +1570,7 @@
   // In ARC, infer lifetime.
   // FIXME: ARC may want to turn this into 'const __unsafe_unretained' if
   // we're doing the equivalent of fast iteration.
-  if (SemaRef.getLangOpts().ObjCAutoRefCount && 
+  if (SemaRef.getLangOpts().ObjCAutoRefCount &&
       SemaRef.inferObjCARCLifetime(Decl))
     Decl->setInvalidDecl();
 
@@ -1601,12 +1581,14 @@
   return false;
 }
 
+namespace {
+
 /// Produce a note indicating which begin/end function was implicitly called
-/// by a C++0x for-range statement. This is often not obvious from the code,
+/// by a C++11 for-range statement. This is often not obvious from the code,
 /// nor from the diagnostics produced when analysing the implicit expressions
 /// required in a for-range statement.
 void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,
-                                  BeginEndFunction BEF) {
+                                  Sema::BeginEndFunction BEF) {
   CallExpr *CE = dyn_cast<CallExpr>(E);
   if (!CE)
     return;
@@ -1627,56 +1609,16 @@
     << BEF << IsTemplate << Description << E->getType();
 }
 
-/// Build a call to 'begin' or 'end' for a C++0x for-range statement. If the
-/// given LookupResult is non-empty, it is assumed to describe a member which
-/// will be invoked. Otherwise, the function will be found via argument
-/// dependent lookup.
-static ExprResult BuildForRangeBeginEndCall(Sema &SemaRef, Scope *S,
-                                            SourceLocation Loc,
-                                            VarDecl *Decl,
-                                            BeginEndFunction BEF,
-                                            const DeclarationNameInfo &NameInfo,
-                                            LookupResult &MemberLookup,
-                                            Expr *Range) {
-  ExprResult CallExpr;
-  if (!MemberLookup.empty()) {
-    ExprResult MemberRef =
-      SemaRef.BuildMemberReferenceExpr(Range, Range->getType(), Loc,
-                                       /*IsPtr=*/false, CXXScopeSpec(),
-                                       /*TemplateKWLoc=*/SourceLocation(),
-                                       /*FirstQualifierInScope=*/0,
-                                       MemberLookup,
-                                       /*TemplateArgs=*/0);
-    if (MemberRef.isInvalid())
-      return ExprError();
-    CallExpr = SemaRef.ActOnCallExpr(S, MemberRef.get(), Loc, MultiExprArg(),
-                                     Loc, 0);
-    if (CallExpr.isInvalid())
-      return ExprError();
-  } else {
-    UnresolvedSet<0> FoundNames;
-    // C++0x [stmt.ranged]p1: For the purposes of this name lookup, namespace
-    // std is an associated namespace.
-    UnresolvedLookupExpr *Fn =
-      UnresolvedLookupExpr::Create(SemaRef.Context, /*NamingClass=*/0,
-                                   NestedNameSpecifierLoc(), NameInfo,
-                                   /*NeedsADL=*/true, /*Overloaded=*/false,
-                                   FoundNames.begin(), FoundNames.end(),
-                                   /*LookInStdNamespace=*/true);
-    CallExpr = SemaRef.BuildOverloadedCallExpr(S, Fn, Fn, Loc, &Range, 1, Loc,
-                                               0, /*AllowTypoCorrection=*/false);
-    if (CallExpr.isInvalid()) {
-      SemaRef.Diag(Range->getLocStart(), diag::note_for_range_type)
-        << Range->getType();
-      return ExprError();
-    }
-  }
-  if (FinishForRangeVarDecl(SemaRef, Decl, CallExpr.get(), Loc,
-                            diag::err_for_range_iter_deduction_failure)) {
-    NoteForRangeBeginEndFunction(SemaRef, CallExpr.get(), BEF);
-    return ExprError();
-  }
-  return CallExpr;
+/// Build a variable declaration for a for-range statement.
+VarDecl *BuildForRangeVarDecl(Sema &SemaRef, SourceLocation Loc,
+                              QualType Type, const char *Name) {
+  DeclContext *DC = SemaRef.CurContext;
+  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
+  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
+  VarDecl *Decl = VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type,
+                                  TInfo, SC_Auto, SC_None);
+  Decl->setImplicit();
+  return Decl;
 }
 
 }
@@ -1686,9 +1628,9 @@
           && Collection->getType()->getAs<ObjCObjectPointerType>() != 0;
 }
 
-/// ActOnCXXForRangeStmt - Check and build a C++0x for-range statement.
+/// ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
 ///
-/// C++0x [stmt.ranged]:
+/// C++11 [stmt.ranged]:
 ///   A range-based for statement is equivalent to
 ///
 ///   {
@@ -1705,15 +1647,14 @@
 /// The body of the loop is not available yet, since it cannot be analysed until
 /// we have determined the type of the for-range-declaration.
 StmtResult
-Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
+Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc,
                            Stmt *First, SourceLocation ColonLoc, Expr *Range,
-                           SourceLocation RParenLoc) {
+                           SourceLocation RParenLoc, bool ShouldTryDeref) {
   if (!First || !Range)
     return StmtError();
-  
+
   if (ObjCEnumerationCollection(Range))
-    return ActOnObjCForCollectionStmt(ForLoc, LParenLoc, First, Range,
-                                      RParenLoc);
+    return ActOnObjCForCollectionStmt(ForLoc, First, Range, RParenLoc);
 
   DeclStmt *DS = dyn_cast<DeclStmt>(First);
   assert(DS && "first part of for range not a decl stmt");
@@ -1746,7 +1687,111 @@
 
   return BuildCXXForRangeStmt(ForLoc, ColonLoc, RangeDecl.get(),
                               /*BeginEndDecl=*/0, /*Cond=*/0, /*Inc=*/0, DS,
-                              RParenLoc);
+                              RParenLoc, ShouldTryDeref);
+}
+
+/// \brief Create the initialization, compare, and increment steps for
+/// the range-based for loop expression.
+/// This function does not handle array-based for loops,
+/// which are created in Sema::BuildCXXForRangeStmt.
+///
+/// \returns a ForRangeStatus indicating success or what kind of error occurred.
+/// BeginExpr and EndExpr are set and FRS_Success is returned on success;
+/// CandidateSet and BEF are set and some non-success value is returned on
+/// failure.
+static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S,
+                                            Expr *BeginRange, Expr *EndRange,
+                                            QualType RangeType,
+                                            VarDecl *BeginVar,
+                                            VarDecl *EndVar,
+                                            SourceLocation ColonLoc,
+                                            OverloadCandidateSet *CandidateSet,
+                                            ExprResult *BeginExpr,
+                                            ExprResult *EndExpr,
+                                            Sema::BeginEndFunction *BEF) {
+  DeclarationNameInfo BeginNameInfo(
+      &SemaRef.PP.getIdentifierTable().get("begin"), ColonLoc);
+  DeclarationNameInfo EndNameInfo(&SemaRef.PP.getIdentifierTable().get("end"),
+                                  ColonLoc);
+
+  LookupResult BeginMemberLookup(SemaRef, BeginNameInfo,
+                                 Sema::LookupMemberName);
+  LookupResult EndMemberLookup(SemaRef, EndNameInfo, Sema::LookupMemberName);
+
+  if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) {
+    // - if _RangeT is a class type, the unqualified-ids begin and end are
+    //   looked up in the scope of class _RangeT as if by class member access
+    //   lookup (3.4.5), and if either (or both) finds at least one
+    //   declaration, begin-expr and end-expr are __range.begin() and
+    //   __range.end(), respectively;
+    SemaRef.LookupQualifiedName(BeginMemberLookup, D);
+    SemaRef.LookupQualifiedName(EndMemberLookup, D);
+
+    if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {
+      SourceLocation RangeLoc = BeginVar->getLocation();
+      *BEF = BeginMemberLookup.empty() ? Sema::BEF_end : Sema::BEF_begin;
+
+      SemaRef.Diag(RangeLoc, diag::err_for_range_member_begin_end_mismatch)
+          << RangeLoc << BeginRange->getType() << *BEF;
+      return Sema::FRS_DiagnosticIssued;
+    }
+  } else {
+    // - otherwise, begin-expr and end-expr are begin(__range) and
+    //   end(__range), respectively, where begin and end are looked up with
+    //   argument-dependent lookup (3.4.2). For the purposes of this name
+    //   lookup, namespace std is an associated namespace.
+
+  }
+
+  *BEF = Sema::BEF_begin;
+  Sema::ForRangeStatus RangeStatus =
+      SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, BeginVar,
+                                        Sema::BEF_begin, BeginNameInfo,
+                                        BeginMemberLookup, CandidateSet,
+                                        BeginRange, BeginExpr);
+
+  if (RangeStatus != Sema::FRS_Success)
+    return RangeStatus;
+  if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc,
+                            diag::err_for_range_iter_deduction_failure)) {
+    NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF);
+    return Sema::FRS_DiagnosticIssued;
+  }
+
+  *BEF = Sema::BEF_end;
+  RangeStatus =
+      SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, EndVar,
+                                        Sema::BEF_end, EndNameInfo,
+                                        EndMemberLookup, CandidateSet,
+                                        EndRange, EndExpr);
+  if (RangeStatus != Sema::FRS_Success)
+    return RangeStatus;
+  if (FinishForRangeVarDecl(SemaRef, EndVar, EndExpr->get(), ColonLoc,
+                            diag::err_for_range_iter_deduction_failure)) {
+    NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF);
+    return Sema::FRS_DiagnosticIssued;
+  }
+  return Sema::FRS_Success;
+}
+
+/// Speculatively attempt to dereference an invalid range expression.
+/// This function will not emit diagnostics, but returns StmtError if
+/// an error occurs.
+static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S,
+                                                 SourceLocation ForLoc,
+                                                 Stmt *LoopVarDecl,
+                                                 SourceLocation ColonLoc,
+                                                 Expr *Range,
+                                                 SourceLocation RangeLoc,
+                                                 SourceLocation RParenLoc) {
+  Sema::SFINAETrap Trap(SemaRef);
+  ExprResult AdjustedRange = SemaRef.BuildUnaryOp(S, RangeLoc, UO_Deref, Range);
+  StmtResult SR =
+    SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc,
+                                 AdjustedRange.get(), RParenLoc, false);
+  if (Trap.hasErrorOccurred())
+    return StmtError();
+  return SR;
 }
 
 /// BuildCXXForRangeStmt - Build or instantiate a C++0x for-range statement.
@@ -1754,7 +1799,7 @@
 Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc,
                            Stmt *RangeDecl, Stmt *BeginEnd, Expr *Cond,
                            Expr *Inc, Stmt *LoopVarDecl,
-                           SourceLocation RParenLoc) {
+                           SourceLocation RParenLoc, bool ShouldTryDeref) {
   Scope *S = getCurScope();
 
   DeclStmt *RangeDS = cast<DeclStmt>(RangeDecl);
@@ -1840,50 +1885,49 @@
         return StmtError();
       }
     } else {
-      DeclarationNameInfo BeginNameInfo(&PP.getIdentifierTable().get("begin"),
-                                        ColonLoc);
-      DeclarationNameInfo EndNameInfo(&PP.getIdentifierTable().get("end"),
-                                      ColonLoc);
+      OverloadCandidateSet CandidateSet(RangeLoc);
+      Sema::BeginEndFunction BEFFailure;
+      ForRangeStatus RangeStatus =
+          BuildNonArrayForRange(*this, S, BeginRangeRef.get(),
+                                EndRangeRef.get(), RangeType,
+                                BeginVar, EndVar, ColonLoc, &CandidateSet,
+                                &BeginExpr, &EndExpr, &BEFFailure);
 
-      LookupResult BeginMemberLookup(*this, BeginNameInfo, LookupMemberName);
-      LookupResult EndMemberLookup(*this, EndNameInfo, LookupMemberName);
-
-      if (CXXRecordDecl *D = RangeType->getAsCXXRecordDecl()) {
-        // - if _RangeT is a class type, the unqualified-ids begin and end are
-        //   looked up in the scope of class _RangeT as if by class member access
-        //   lookup (3.4.5), and if either (or both) finds at least one
-        //   declaration, begin-expr and end-expr are __range.begin() and
-        //   __range.end(), respectively;
-        LookupQualifiedName(BeginMemberLookup, D);
-        LookupQualifiedName(EndMemberLookup, D);
-
-        if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {
-          Diag(ColonLoc, diag::err_for_range_member_begin_end_mismatch)
-            << RangeType << BeginMemberLookup.empty();
-          return StmtError();
+      // If building the range failed, try dereferencing the range expression
+      // unless a diagnostic was issued or the end function is problematic.
+      if (ShouldTryDeref && RangeStatus == FRS_NoViableFunction &&
+          BEFFailure == BEF_begin) {
+        StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc,
+                                                       LoopVarDecl, ColonLoc,
+                                                       Range, RangeLoc,
+                                                       RParenLoc);
+        if (!SR.isInvalid()) {
+          // The attempt to dereference would succeed; return the result of
+          // recovery.
+          Diag(RangeLoc, diag::err_for_range_dereference)
+              << RangeLoc << RangeType
+              << FixItHint::CreateInsertion(RangeLoc, "*");
+          return SR;
         }
-      } else {
-        // - otherwise, begin-expr and end-expr are begin(__range) and
-        //   end(__range), respectively, where begin and end are looked up with
-        //   argument-dependent lookup (3.4.2). For the purposes of this name
-        //   lookup, namespace std is an associated namespace.
       }
 
-      BeginExpr = BuildForRangeBeginEndCall(*this, S, ColonLoc, BeginVar,
-                                            BEF_begin, BeginNameInfo,
-                                            BeginMemberLookup,
-                                            BeginRangeRef.get());
-      if (BeginExpr.isInvalid())
-        return StmtError();
-
-      EndExpr = BuildForRangeBeginEndCall(*this, S, ColonLoc, EndVar,
-                                          BEF_end, EndNameInfo,
-                                          EndMemberLookup, EndRangeRef.get());
-      if (EndExpr.isInvalid())
+      // Otherwise, emit diagnostics if we haven't already.
+      if (RangeStatus == FRS_NoViableFunction) {
+        Expr *Range = BEFFailure ?  EndRangeRef.get() : BeginRangeRef.get();
+        Diag(Range->getLocStart(), diag::err_for_range_invalid)
+            << RangeLoc << Range->getType() << BEFFailure;
+        CandidateSet.NoteCandidates(*this, OCD_AllCandidates,
+                                    llvm::makeArrayRef(&Range, /*NumArgs=*/1));
+      }
+      // Return an error if no fix was discovered.
+      if (RangeStatus != FRS_Success)
         return StmtError();
     }
 
-    // C++0x [decl.spec.auto]p6: BeginType and EndType must be the same.
+    assert(!BeginExpr.isInvalid() && !EndExpr.isInvalid() &&
+           "invalid range expression in for loop");
+
+    // C++11 [dcl.spec.auto]p7: BeginType and EndType must be the same.
     QualType BeginType = BeginVar->getType(), EndType = EndVar->getType();
     if (!Context.hasSameType(BeginType, EndType)) {
       Diag(RangeLoc, diag::err_for_range_begin_end_types_differ)
@@ -1965,13 +2009,13 @@
                                              ColonLoc, RParenLoc));
 }
 
-/// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach 
+/// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach
 /// statement.
 StmtResult Sema::FinishObjCForCollectionStmt(Stmt *S, Stmt *B) {
   if (!S || !B)
     return StmtError();
   ObjCForCollectionStmt * ForStmt = cast<ObjCForCollectionStmt>(S);
-  
+
   ForStmt->setBody(B);
   return S;
 }
@@ -1986,7 +2030,7 @@
 
   if (isa<ObjCForCollectionStmt>(S))
     return FinishObjCForCollectionStmt(S, B);
-  
+
   CXXForRangeStmt *ForStmt = cast<CXXForRangeStmt>(S);
   ForStmt->setBody(B);
 
@@ -2215,7 +2259,7 @@
         FnRetType = RetValExp->getType();
       else
         FnRetType = CurCap->ReturnType = Context.DependentTy;
-    } else { 
+    } else {
       if (RetValExp) {
         // C++11 [expr.lambda.prim]p4 bans inferring the result from an
         // initializer list, because it is not an expression (even
@@ -2315,7 +2359,7 @@
   // Check for unexpanded parameter packs.
   if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
     return StmtError();
-  
+
   if (isa<CapturingScopeInfo>(getCurFunction()))
     return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
 
@@ -2331,7 +2375,7 @@
     FnRetType = MD->getResultType();
     if (MD->hasRelatedResultType() && MD->getClassInterface()) {
       // In the implementation of a method with a related return type, the
-      // type used to type-check the validity of return statements within the 
+      // type used to type-check the validity of return statements within the
       // method body is a pointer to the type of the class being implemented.
       RelatedRetType = Context.getObjCInterfaceType(MD->getClassInterface());
       RelatedRetType = Context.getObjCObjectPointerType(RelatedRetType);
@@ -2470,295 +2514,6 @@
   return Owned(Result);
 }
 
-/// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently
-/// ignore "noop" casts in places where an lvalue is required by an inline asm.
-/// We emulate this behavior when -fheinous-gnu-extensions is specified, but
-/// provide a strong guidance to not use it.
-///
-/// This method checks to see if the argument is an acceptable l-value and
-/// returns false if it is a case we can handle.
-static bool CheckAsmLValue(const Expr *E, Sema &S) {
-  // Type dependent expressions will be checked during instantiation.
-  if (E->isTypeDependent())
-    return false;
-
-  if (E->isLValue())
-    return false;  // Cool, this is an lvalue.
-
-  // Okay, this is not an lvalue, but perhaps it is the result of a cast that we
-  // are supposed to allow.
-  const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
-  if (E != E2 && E2->isLValue()) {
-    if (!S.getLangOpts().HeinousExtensions)
-      S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
-        << E->getSourceRange();
-    else
-      S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
-        << E->getSourceRange();
-    // Accept, even if we emitted an error diagnostic.
-    return false;
-  }
-
-  // None of the above, just randomly invalid non-lvalue.
-  return true;
-}
-
-/// isOperandMentioned - Return true if the specified operand # is mentioned
-/// anywhere in the decomposed asm string.
-static bool isOperandMentioned(unsigned OpNo, 
-                         ArrayRef<AsmStmt::AsmStringPiece> AsmStrPieces) {
-  for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) {
-    const AsmStmt::AsmStringPiece &Piece = AsmStrPieces[p];
-    if (!Piece.isOperand()) continue;
-
-    // If this is a reference to the input and if the input was the smaller
-    // one, then we have to reject this asm.
-    if (Piece.getOperandNo() == OpNo)
-      return true;
-  }
-  return false;
-}
-
-StmtResult Sema::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) {
-  unsigned NumClobbers = clobbers.size();
-  StringLiteral **Constraints =
-    reinterpret_cast<StringLiteral**>(constraints.get());
-  Expr **Exprs = exprs.get();
-  StringLiteral *AsmString = cast<StringLiteral>(asmString);
-  StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
-
-  SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
-
-  // The parser verifies that there is a string literal here.
-  if (!AsmString->isAscii())
-    return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character)
-      << AsmString->getSourceRange());
-
-  for (unsigned i = 0; i != NumOutputs; i++) {
-    StringLiteral *Literal = Constraints[i];
-    if (!Literal->isAscii())
-      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
-        << Literal->getSourceRange());
-
-    StringRef OutputName;
-    if (Names[i])
-      OutputName = Names[i]->getName();
-
-    TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
-    if (!Context.getTargetInfo().validateOutputConstraint(Info))
-      return StmtError(Diag(Literal->getLocStart(),
-                            diag::err_asm_invalid_output_constraint)
-                       << Info.getConstraintStr());
-
-    // Check that the output exprs are valid lvalues.
-    Expr *OutputExpr = Exprs[i];
-    if (CheckAsmLValue(OutputExpr, *this)) {
-      return StmtError(Diag(OutputExpr->getLocStart(),
-                  diag::err_asm_invalid_lvalue_in_output)
-        << OutputExpr->getSourceRange());
-    }
-
-    OutputConstraintInfos.push_back(Info);
-  }
-
-  SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
-
-  for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
-    StringLiteral *Literal = Constraints[i];
-    if (!Literal->isAscii())
-      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
-        << Literal->getSourceRange());
-
-    StringRef InputName;
-    if (Names[i])
-      InputName = Names[i]->getName();
-
-    TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
-    if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(),
-                                                NumOutputs, Info)) {
-      return StmtError(Diag(Literal->getLocStart(),
-                            diag::err_asm_invalid_input_constraint)
-                       << Info.getConstraintStr());
-    }
-
-    Expr *InputExpr = Exprs[i];
-
-    // Only allow void types for memory constraints.
-    if (Info.allowsMemory() && !Info.allowsRegister()) {
-      if (CheckAsmLValue(InputExpr, *this))
-        return StmtError(Diag(InputExpr->getLocStart(),
-                              diag::err_asm_invalid_lvalue_in_input)
-                         << Info.getConstraintStr()
-                         << InputExpr->getSourceRange());
-    }
-
-    if (Info.allowsRegister()) {
-      if (InputExpr->getType()->isVoidType()) {
-        return StmtError(Diag(InputExpr->getLocStart(),
-                              diag::err_asm_invalid_type_in_input)
-          << InputExpr->getType() << Info.getConstraintStr()
-          << InputExpr->getSourceRange());
-      }
-    }
-
-    ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
-    if (Result.isInvalid())
-      return StmtError();
-
-    Exprs[i] = Result.take();
-    InputConstraintInfos.push_back(Info);
-  }
-
-  // Check that the clobbers are valid.
-  for (unsigned i = 0; i != NumClobbers; i++) {
-    StringLiteral *Literal = Clobbers[i];
-    if (!Literal->isAscii())
-      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
-        << Literal->getSourceRange());
-
-    StringRef Clobber = Literal->getString();
-
-    if (!Context.getTargetInfo().isValidClobber(Clobber))
-      return StmtError(Diag(Literal->getLocStart(),
-                  diag::err_asm_unknown_register_name) << Clobber);
-  }
-
-  AsmStmt *NS =
-    new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm,
-                          NumOutputs, NumInputs, Names, Constraints, Exprs,
-                          AsmString, NumClobbers, Clobbers, RParenLoc);
-  // Validate the asm string, ensuring it makes sense given the operands we
-  // have.
-  SmallVector<AsmStmt::AsmStringPiece, 8> Pieces;
-  unsigned DiagOffs;
-  if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
-    Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
-           << AsmString->getSourceRange();
-    return StmtError();
-  }
-
-  // Validate tied input operands for type mismatches.
-  for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
-    TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
-
-    // If this is a tied constraint, verify that the output and input have
-    // either exactly the same type, or that they are int/ptr operands with the
-    // same size (int/long, int*/long, are ok etc).
-    if (!Info.hasTiedOperand()) continue;
-
-    unsigned TiedTo = Info.getTiedOperand();
-    unsigned InputOpNo = i+NumOutputs;
-    Expr *OutputExpr = Exprs[TiedTo];
-    Expr *InputExpr = Exprs[InputOpNo];
-
-    if (OutputExpr->isTypeDependent() || InputExpr->isTypeDependent())
-      continue;
-
-    QualType InTy = InputExpr->getType();
-    QualType OutTy = OutputExpr->getType();
-    if (Context.hasSameType(InTy, OutTy))
-      continue;  // All types can be tied to themselves.
-
-    // Decide if the input and output are in the same domain (integer/ptr or
-    // floating point.
-    enum AsmDomain {
-      AD_Int, AD_FP, AD_Other
-    } InputDomain, OutputDomain;
-
-    if (InTy->isIntegerType() || InTy->isPointerType())
-      InputDomain = AD_Int;
-    else if (InTy->isRealFloatingType())
-      InputDomain = AD_FP;
-    else
-      InputDomain = AD_Other;
-
-    if (OutTy->isIntegerType() || OutTy->isPointerType())
-      OutputDomain = AD_Int;
-    else if (OutTy->isRealFloatingType())
-      OutputDomain = AD_FP;
-    else
-      OutputDomain = AD_Other;
-
-    // They are ok if they are the same size and in the same domain.  This
-    // allows tying things like:
-    //   void* to int*
-    //   void* to int            if they are the same size.
-    //   double to long double   if they are the same size.
-    //
-    uint64_t OutSize = Context.getTypeSize(OutTy);
-    uint64_t InSize = Context.getTypeSize(InTy);
-    if (OutSize == InSize && InputDomain == OutputDomain &&
-        InputDomain != AD_Other)
-      continue;
-
-    // If the smaller input/output operand is not mentioned in the asm string,
-    // then we can promote the smaller one to a larger input and the asm string
-    // won't notice.
-    bool SmallerValueMentioned = false;
-
-    // If this is a reference to the input and if the input was the smaller
-    // one, then we have to reject this asm.
-    if (isOperandMentioned(InputOpNo, Pieces)) {
-      // This is a use in the asm string of the smaller operand.  Since we
-      // codegen this by promoting to a wider value, the asm will get printed
-      // "wrong".
-      SmallerValueMentioned |= InSize < OutSize;
-    }
-    if (isOperandMentioned(TiedTo, Pieces)) {
-      // If this is a reference to the output, and if the output is the larger
-      // value, then it's ok because we'll promote the input to the larger type.
-      SmallerValueMentioned |= OutSize < InSize;
-    }
-
-    // If the smaller value wasn't mentioned in the asm string, and if the
-    // output was a register, just extend the shorter one to the size of the
-    // larger one.
-    if (!SmallerValueMentioned && InputDomain != AD_Other &&
-        OutputConstraintInfos[TiedTo].allowsRegister())
-      continue;
-
-    // Either both of the operands were mentioned or the smaller one was
-    // mentioned.  One more special case that we'll allow: if the tied input is
-    // integer, unmentioned, and is a constant, then we'll allow truncating it
-    // down to the size of the destination.
-    if (InputDomain == AD_Int && OutputDomain == AD_Int &&
-        !isOperandMentioned(InputOpNo, Pieces) &&
-        InputExpr->isEvaluatable(Context)) {
-      CastKind castKind =
-        (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
-      InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take();
-      Exprs[InputOpNo] = InputExpr;
-      NS->setInputExpr(i, InputExpr);
-      continue;
-    }
-
-    Diag(InputExpr->getLocStart(),
-         diag::err_asm_tying_incompatible_types)
-      << InTy << OutTy << OutputExpr->getSourceRange()
-      << InputExpr->getSourceRange();
-    return StmtError();
-  }
-
-  return Owned(NS);
-}
-
-StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
-                                std::string &AsmString,
-                                SourceLocation EndLoc) {
-  // MS-style inline assembly is not fully supported, so emit a warning.
-  Diag(AsmLoc, diag::warn_unsupported_msasm);
-
-  MSAsmStmt *NS =
-    new (Context) MSAsmStmt(Context, AsmLoc, AsmString, EndLoc);
-
-  return Owned(NS);
-}
-
 StmtResult
 Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
                            SourceLocation RParen, Decl *Parm,
@@ -3012,17 +2767,17 @@
                                             Stmt *Nested)
 {
   return new (Context) MSDependentExistsStmt(KeywordLoc, IsIfExists,
-                                             QualifierLoc, NameInfo, 
+                                             QualifierLoc, NameInfo,
                                              cast<CompoundStmt>(Nested));
 }
 
 
-StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, 
+StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
                                             bool IsIfExists,
-                                            CXXScopeSpec &SS, 
+                                            CXXScopeSpec &SS,
                                             UnqualifiedId &Name,
                                             Stmt *Nested) {
-  return BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, 
+  return BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
                                     SS.getWithLocInContext(Context),
                                     GetNameFromUnqualifiedId(Name),
                                     Nested);
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
new file mode 100644
index 0000000..94223e4
--- /dev/null
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -0,0 +1,661 @@
+//===--- SemaStmtAsm.cpp - Semantic Analysis for Asm Statements -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for inline asm statements.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+using namespace clang;
+using namespace sema;
+
+/// CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently
+/// ignore "noop" casts in places where an lvalue is required by an inline asm.
+/// We emulate this behavior when -fheinous-gnu-extensions is specified, but
+/// provide a strong guidance to not use it.
+///
+/// This method checks to see if the argument is an acceptable l-value and
+/// returns false if it is a case we can handle.
+static bool CheckAsmLValue(const Expr *E, Sema &S) {
+  // Type dependent expressions will be checked during instantiation.
+  if (E->isTypeDependent())
+    return false;
+
+  if (E->isLValue())
+    return false;  // Cool, this is an lvalue.
+
+  // Okay, this is not an lvalue, but perhaps it is the result of a cast that we
+  // are supposed to allow.
+  const Expr *E2 = E->IgnoreParenNoopCasts(S.Context);
+  if (E != E2 && E2->isLValue()) {
+    if (!S.getLangOpts().HeinousExtensions)
+      S.Diag(E2->getLocStart(), diag::err_invalid_asm_cast_lvalue)
+        << E->getSourceRange();
+    else
+      S.Diag(E2->getLocStart(), diag::warn_invalid_asm_cast_lvalue)
+        << E->getSourceRange();
+    // Accept, even if we emitted an error diagnostic.
+    return false;
+  }
+
+  // None of the above, just randomly invalid non-lvalue.
+  return true;
+}
+
+/// isOperandMentioned - Return true if the specified operand # is mentioned
+/// anywhere in the decomposed asm string.
+static bool isOperandMentioned(unsigned OpNo,
+                         ArrayRef<AsmStmt::AsmStringPiece> AsmStrPieces) {
+  for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) {
+    const AsmStmt::AsmStringPiece &Piece = AsmStrPieces[p];
+    if (!Piece.isOperand()) continue;
+
+    // If this is a reference to the input and if the input was the smaller
+    // one, then we have to reject this asm.
+    if (Piece.getOperandNo() == OpNo)
+      return true;
+  }
+  return false;
+}
+
+StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
+                              bool IsVolatile, unsigned NumOutputs,
+                              unsigned NumInputs, IdentifierInfo **Names,
+                              MultiExprArg constraints, MultiExprArg exprs,
+                              Expr *asmString, MultiExprArg clobbers,
+                              SourceLocation RParenLoc) {
+  unsigned NumClobbers = clobbers.size();
+  StringLiteral **Constraints =
+    reinterpret_cast<StringLiteral**>(constraints.get());
+  Expr **Exprs = exprs.get();
+  StringLiteral *AsmString = cast<StringLiteral>(asmString);
+  StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
+
+  SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
+
+  // The parser verifies that there is a string literal here.
+  if (!AsmString->isAscii())
+    return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character)
+      << AsmString->getSourceRange());
+
+  for (unsigned i = 0; i != NumOutputs; i++) {
+    StringLiteral *Literal = Constraints[i];
+    if (!Literal->isAscii())
+      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
+        << Literal->getSourceRange());
+
+    StringRef OutputName;
+    if (Names[i])
+      OutputName = Names[i]->getName();
+
+    TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
+    if (!Context.getTargetInfo().validateOutputConstraint(Info))
+      return StmtError(Diag(Literal->getLocStart(),
+                            diag::err_asm_invalid_output_constraint)
+                       << Info.getConstraintStr());
+
+    // Check that the output exprs are valid lvalues.
+    Expr *OutputExpr = Exprs[i];
+    if (CheckAsmLValue(OutputExpr, *this)) {
+      return StmtError(Diag(OutputExpr->getLocStart(),
+                  diag::err_asm_invalid_lvalue_in_output)
+        << OutputExpr->getSourceRange());
+    }
+
+    OutputConstraintInfos.push_back(Info);
+  }
+
+  SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
+
+  for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
+    StringLiteral *Literal = Constraints[i];
+    if (!Literal->isAscii())
+      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
+        << Literal->getSourceRange());
+
+    StringRef InputName;
+    if (Names[i])
+      InputName = Names[i]->getName();
+
+    TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
+    if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos.data(),
+                                                NumOutputs, Info)) {
+      return StmtError(Diag(Literal->getLocStart(),
+                            diag::err_asm_invalid_input_constraint)
+                       << Info.getConstraintStr());
+    }
+
+    Expr *InputExpr = Exprs[i];
+
+    // Only allow void types for memory constraints.
+    if (Info.allowsMemory() && !Info.allowsRegister()) {
+      if (CheckAsmLValue(InputExpr, *this))
+        return StmtError(Diag(InputExpr->getLocStart(),
+                              diag::err_asm_invalid_lvalue_in_input)
+                         << Info.getConstraintStr()
+                         << InputExpr->getSourceRange());
+    }
+
+    if (Info.allowsRegister()) {
+      if (InputExpr->getType()->isVoidType()) {
+        return StmtError(Diag(InputExpr->getLocStart(),
+                              diag::err_asm_invalid_type_in_input)
+          << InputExpr->getType() << Info.getConstraintStr()
+          << InputExpr->getSourceRange());
+      }
+    }
+
+    ExprResult Result = DefaultFunctionArrayLvalueConversion(Exprs[i]);
+    if (Result.isInvalid())
+      return StmtError();
+
+    Exprs[i] = Result.take();
+    InputConstraintInfos.push_back(Info);
+  }
+
+  // Check that the clobbers are valid.
+  for (unsigned i = 0; i != NumClobbers; i++) {
+    StringLiteral *Literal = Clobbers[i];
+    if (!Literal->isAscii())
+      return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character)
+        << Literal->getSourceRange());
+
+    StringRef Clobber = Literal->getString();
+
+    if (!Context.getTargetInfo().isValidClobber(Clobber))
+      return StmtError(Diag(Literal->getLocStart(),
+                  diag::err_asm_unknown_register_name) << Clobber);
+  }
+
+  AsmStmt *NS =
+    new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
+                          NumInputs, Names, Constraints, Exprs, AsmString,
+                          NumClobbers, Clobbers, RParenLoc);
+  // Validate the asm string, ensuring it makes sense given the operands we
+  // have.
+  SmallVector<AsmStmt::AsmStringPiece, 8> Pieces;
+  unsigned DiagOffs;
+  if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
+    Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
+           << AsmString->getSourceRange();
+    return StmtError();
+  }
+
+  // Validate tied input operands for type mismatches.
+  for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
+    TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
+
+    // If this is a tied constraint, verify that the output and input have
+    // either exactly the same type, or that they are int/ptr operands with the
+    // same size (int/long, int*/long, are ok etc).
+    if (!Info.hasTiedOperand()) continue;
+
+    unsigned TiedTo = Info.getTiedOperand();
+    unsigned InputOpNo = i+NumOutputs;
+    Expr *OutputExpr = Exprs[TiedTo];
+    Expr *InputExpr = Exprs[InputOpNo];
+
+    if (OutputExpr->isTypeDependent() || InputExpr->isTypeDependent())
+      continue;
+
+    QualType InTy = InputExpr->getType();
+    QualType OutTy = OutputExpr->getType();
+    if (Context.hasSameType(InTy, OutTy))
+      continue;  // All types can be tied to themselves.
+
+    // Decide if the input and output are in the same domain (integer/ptr or
+    // floating point.
+    enum AsmDomain {
+      AD_Int, AD_FP, AD_Other
+    } InputDomain, OutputDomain;
+
+    if (InTy->isIntegerType() || InTy->isPointerType())
+      InputDomain = AD_Int;
+    else if (InTy->isRealFloatingType())
+      InputDomain = AD_FP;
+    else
+      InputDomain = AD_Other;
+
+    if (OutTy->isIntegerType() || OutTy->isPointerType())
+      OutputDomain = AD_Int;
+    else if (OutTy->isRealFloatingType())
+      OutputDomain = AD_FP;
+    else
+      OutputDomain = AD_Other;
+
+    // They are ok if they are the same size and in the same domain.  This
+    // allows tying things like:
+    //   void* to int*
+    //   void* to int            if they are the same size.
+    //   double to long double   if they are the same size.
+    //
+    uint64_t OutSize = Context.getTypeSize(OutTy);
+    uint64_t InSize = Context.getTypeSize(InTy);
+    if (OutSize == InSize && InputDomain == OutputDomain &&
+        InputDomain != AD_Other)
+      continue;
+
+    // If the smaller input/output operand is not mentioned in the asm string,
+    // then we can promote the smaller one to a larger input and the asm string
+    // won't notice.
+    bool SmallerValueMentioned = false;
+
+    // If this is a reference to the input and if the input was the smaller
+    // one, then we have to reject this asm.
+    if (isOperandMentioned(InputOpNo, Pieces)) {
+      // This is a use in the asm string of the smaller operand.  Since we
+      // codegen this by promoting to a wider value, the asm will get printed
+      // "wrong".
+      SmallerValueMentioned |= InSize < OutSize;
+    }
+    if (isOperandMentioned(TiedTo, Pieces)) {
+      // If this is a reference to the output, and if the output is the larger
+      // value, then it's ok because we'll promote the input to the larger type.
+      SmallerValueMentioned |= OutSize < InSize;
+    }
+
+    // If the smaller value wasn't mentioned in the asm string, and if the
+    // output was a register, just extend the shorter one to the size of the
+    // larger one.
+    if (!SmallerValueMentioned && InputDomain != AD_Other &&
+        OutputConstraintInfos[TiedTo].allowsRegister())
+      continue;
+
+    // Either both of the operands were mentioned or the smaller one was
+    // mentioned.  One more special case that we'll allow: if the tied input is
+    // integer, unmentioned, and is a constant, then we'll allow truncating it
+    // down to the size of the destination.
+    if (InputDomain == AD_Int && OutputDomain == AD_Int &&
+        !isOperandMentioned(InputOpNo, Pieces) &&
+        InputExpr->isEvaluatable(Context)) {
+      CastKind castKind =
+        (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);
+      InputExpr = ImpCastExprToType(InputExpr, OutTy, castKind).take();
+      Exprs[InputOpNo] = InputExpr;
+      NS->setInputExpr(i, InputExpr);
+      continue;
+    }
+
+    Diag(InputExpr->getLocStart(),
+         diag::err_asm_tying_incompatible_types)
+      << InTy << OutTy << OutputExpr->getSourceRange()
+      << InputExpr->getSourceRange();
+    return StmtError();
+  }
+
+  return Owned(NS);
+}
+
+// isMSAsmKeyword - Return true if this is an MS-style inline asm keyword. These
+// require special handling.
+static bool isMSAsmKeyword(StringRef Name) {
+  bool Ret = llvm::StringSwitch<bool>(Name)
+    .Cases("EVEN", "ALIGN", true) // Alignment directives.
+    .Cases("LENGTH", "SIZE", "TYPE", true) // Type and variable sizes.
+    .Case("_emit", true) // _emit Pseudoinstruction.
+    .Default(false);
+  return Ret;
+}
+
+static StringRef getSpelling(Sema &SemaRef, Token AsmTok) {
+  StringRef Asm;
+  SmallString<512> TokenBuf;
+  TokenBuf.resize(512);
+  bool StringInvalid = false;
+  Asm = SemaRef.PP.getSpelling(AsmTok, TokenBuf, &StringInvalid);
+  assert (!StringInvalid && "Expected valid string!");
+  return Asm;
+}
+
+static void patchMSAsmStrings(Sema &SemaRef, bool &IsSimple,
+                              SourceLocation AsmLoc,
+                              ArrayRef<Token> AsmToks,
+                              const TargetInfo &TI,
+                              std::vector<llvm::BitVector> &AsmRegs,
+                              std::vector<llvm::BitVector> &AsmNames,
+                              std::vector<std::string> &AsmStrings) {
+  assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
+
+  // Assume simple asm stmt until we parse a non-register identifer (or we just
+  // need to bail gracefully).
+  IsSimple = true;
+
+  SmallString<512> Asm;
+  unsigned NumAsmStrings = 0;
+  for (unsigned i = 0, e = AsmToks.size(); i != e; ++i) {
+
+    // Determine if this should be considered a new asm.
+    bool isNewAsm = i == 0 || AsmToks[i].isAtStartOfLine() ||
+      AsmToks[i].is(tok::kw_asm);
+
+    // Emit the previous asm string.
+    if (i && isNewAsm) {
+      AsmStrings[NumAsmStrings++] = Asm.c_str();
+      if (AsmToks[i].is(tok::kw_asm)) {
+        ++i; // Skip __asm
+        assert (i != e && "Expected another token.");
+      }
+    }
+
+    // Start a new asm string with the opcode.
+    if (isNewAsm) {
+      AsmRegs[NumAsmStrings].resize(AsmToks.size());
+      AsmNames[NumAsmStrings].resize(AsmToks.size());
+
+      StringRef Piece = AsmToks[i].getIdentifierInfo()->getName();
+      // MS-style inline asm keywords require special handling.
+      if (isMSAsmKeyword(Piece))
+        IsSimple = false;
+
+      // TODO: Verify this is a valid opcode.
+      Asm = Piece;
+      continue;
+    }
+
+    if (i && AsmToks[i].hasLeadingSpace())
+      Asm += ' ';
+
+    // Check the operand(s).
+    switch (AsmToks[i].getKind()) {
+    default:
+      IsSimple = false;
+      Asm += getSpelling(SemaRef, AsmToks[i]);
+      break;
+    case tok::comma: Asm += ","; break;
+    case tok::colon: Asm += ":"; break;
+    case tok::l_square: Asm += "["; break;
+    case tok::r_square: Asm += "]"; break;
+    case tok::l_brace: Asm += "{"; break;
+    case tok::r_brace: Asm += "}"; break;
+    case tok::numeric_constant:
+      Asm += getSpelling(SemaRef, AsmToks[i]);
+      break;
+    case tok::identifier: {
+      IdentifierInfo *II = AsmToks[i].getIdentifierInfo();
+      StringRef Name = II->getName();
+
+      // Valid register?
+      if (TI.isValidGCCRegisterName(Name)) {
+        AsmRegs[NumAsmStrings].set(i);
+        Asm += Name;
+        break;
+      }
+
+      IsSimple = false;
+
+      // MS-style inline asm keywords require special handling.
+      if (isMSAsmKeyword(Name)) {
+        IsSimple = false;
+        Asm += Name;
+        break;
+      }
+
+      // Lookup the identifier.
+      // TODO: Someone with more experience with clang should verify this the
+      // proper way of doing a symbol lookup.
+      DeclarationName DeclName(II);
+      Scope *CurScope = SemaRef.getCurScope();
+      LookupResult R(SemaRef, DeclName, AsmLoc, Sema::LookupOrdinaryName);
+      if (!SemaRef.LookupName(R, CurScope, false/*AllowBuiltinCreation*/))
+        break;
+
+      assert (R.isSingleResult() && "Expected a single result?!");
+      NamedDecl *Decl = R.getFoundDecl();
+      switch (Decl->getKind()) {
+      default:
+        assert(0 && "Unknown decl kind.");
+        break;
+      case Decl::Var: {
+      case Decl::ParmVar:
+        AsmNames[NumAsmStrings].set(i);
+
+        VarDecl *Var = cast<VarDecl>(Decl);
+        QualType Ty = Var->getType();
+        (void)Ty; // Avoid warning.
+        // TODO: Patch identifier with valid operand.  One potential idea is to
+        // probe the backend with type information to guess the possible
+        // operand.
+        Asm += getSpelling(SemaRef, AsmToks[i]);
+        break;
+      }
+      }
+      break;
+    }
+    }
+  }
+
+  // Emit the final (and possibly only) asm string.
+  AsmStrings[NumAsmStrings] = Asm.c_str();
+}
+
+// Break the AsmSting into pieces.
+static void buildMSAsmPieces(StringRef Asm, std::vector<StringRef> &Pieces) {
+  std::pair<StringRef,StringRef> Split = Asm.split(' ');
+
+  // Mnemonic
+  Pieces.push_back(Split.first);
+  Asm = Split.second;
+
+  // Operands
+  while (!Asm.empty()) {
+    Split = Asm.split(", ");
+    Pieces.push_back(Split.first);
+    Asm = Split.second;
+  }
+}
+
+// Build the unmodified MSAsmString.
+static std::string buildMSAsmString(Sema &SemaRef,
+                                    ArrayRef<Token> AsmToks,
+                                    std::vector<std::string> &AsmStrings) {
+  assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
+
+  SmallString<512> Res;
+  SmallString<512> Asm;
+  for (unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
+    bool isNewAsm = i == 0 || AsmToks[i].isAtStartOfLine() ||
+      AsmToks[i].is(tok::kw_asm);
+
+    if (isNewAsm) {
+      if (i) {
+        AsmStrings.push_back(Asm.c_str());
+        Res += Asm;
+        Asm.clear();
+        Res += '\n';
+      }
+      if (AsmToks[i].is(tok::kw_asm)) {
+        i++; // Skip __asm
+        assert (i != e && "Expected another token");
+      }
+    }
+
+    if (i && AsmToks[i].hasLeadingSpace() && !isNewAsm)
+      Asm += ' ';
+
+    Asm += getSpelling(SemaRef, AsmToks[i]);
+  }
+  AsmStrings.push_back(Asm.c_str());
+  Res += Asm;
+  return Res.c_str();
+}
+
+StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc,
+                                SourceLocation LBraceLoc,
+                                ArrayRef<Token> AsmToks,
+                                SourceLocation EndLoc) {
+  // MS-style inline assembly is not fully supported, so emit a warning.
+  Diag(AsmLoc, diag::warn_unsupported_msasm);
+  SmallVector<StringRef,4> Clobbers;
+  std::set<std::string> ClobberRegs;
+  SmallVector<IdentifierInfo*, 4> Inputs;
+  SmallVector<IdentifierInfo*, 4> Outputs;
+
+  // Empty asm statements don't need to instantiate the AsmParser, etc.
+  if (AsmToks.empty()) {
+    StringRef AsmString;
+    MSAsmStmt *NS =
+      new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
+                              /*IsVolatile*/ true, AsmToks, Inputs, Outputs,
+                              AsmString, Clobbers, EndLoc);
+    return Owned(NS);
+  }
+
+  unsigned NumAsmStrings;
+  std::vector<std::string> AsmStrings;
+  std::string AsmString = buildMSAsmString(*this, AsmToks, AsmStrings);
+  NumAsmStrings = AsmStrings.size();
+
+  std::vector<std::vector<StringRef> > Pieces;
+  Pieces.resize(NumAsmStrings);
+  for (unsigned i = 0; i != NumAsmStrings; ++i)
+    buildMSAsmPieces(AsmStrings[i], Pieces[i]);
+
+  bool IsSimple;
+  std::vector<llvm::BitVector> Regs;
+  std::vector<llvm::BitVector> Names;
+  std::vector<std::string> PatchedAsmStrings;
+
+  Regs.resize(NumAsmStrings);
+  Names.resize(NumAsmStrings);
+  PatchedAsmStrings.resize(NumAsmStrings);
+
+  // Rewrite operands to appease the AsmParser.
+  patchMSAsmStrings(*this, IsSimple, AsmLoc, AsmToks,
+                    Context.getTargetInfo(), Regs, Names, PatchedAsmStrings);
+
+  // patchMSAsmStrings doesn't correctly patch non-simple asm statements.
+  if (!IsSimple) {
+    MSAsmStmt *NS =
+      new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true,
+                              /*IsVolatile*/ true, AsmToks, Inputs, Outputs,
+                              AsmString, Clobbers, EndLoc);
+    return Owned(NS);
+  }
+
+  // Initialize targets and assembly printers/parsers.
+  llvm::InitializeAllTargetInfos();
+  llvm::InitializeAllTargetMCs();
+  llvm::InitializeAllAsmParsers();
+
+  // Get the target specific parser.
+  std::string Error;
+  const std::string &TT = Context.getTargetInfo().getTriple().getTriple();
+  const llvm::Target *TheTarget(llvm::TargetRegistry::lookupTarget(TT, Error));
+
+  OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TT));
+  OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
+  OwningPtr<llvm::MCObjectFileInfo> MOFI(new llvm::MCObjectFileInfo());
+  OwningPtr<llvm::MCSubtargetInfo>
+    STI(TheTarget->createMCSubtargetInfo(TT, "", ""));
+
+  for (unsigned i = 0, e = PatchedAsmStrings.size(); i != e; ++i) {
+    llvm::SourceMgr SrcMgr;
+    llvm::MCContext Ctx(*MAI, *MRI, MOFI.get(), &SrcMgr);
+    llvm::MemoryBuffer *Buffer =
+      llvm::MemoryBuffer::getMemBuffer(PatchedAsmStrings[i], "<inline asm>");
+
+    // Tell SrcMgr about this buffer, which is what the parser will pick up.
+    SrcMgr.AddNewSourceBuffer(Buffer, llvm::SMLoc());
+
+    OwningPtr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
+    OwningPtr<llvm::MCAsmParser>
+      Parser(createMCAsmParser(SrcMgr, Ctx, *Str.get(), *MAI));
+    OwningPtr<llvm::MCTargetAsmParser>
+      TargetParser(TheTarget->createMCAsmParser(*STI, *Parser));
+    // Change to the Intel dialect.
+    Parser->setAssemblerDialect(1);
+    Parser->setTargetParser(*TargetParser.get());
+
+    // Prime the lexer.
+    Parser->Lex();
+
+    // Parse the opcode.
+    StringRef IDVal;
+    Parser->ParseIdentifier(IDVal);
+
+    // Canonicalize the opcode to lower case.
+    SmallString<128> Opcode;
+    for (unsigned i = 0, e = IDVal.size(); i != e; ++i)
+      Opcode.push_back(tolower(IDVal[i]));
+
+    // Parse the operands.
+    llvm::SMLoc IDLoc;
+    SmallVector<llvm::MCParsedAsmOperand*, 8> Operands;
+    bool HadError = TargetParser->ParseInstruction(Opcode.str(), IDLoc,
+                                                   Operands);
+    assert (!HadError && "Unexpected error parsing instruction");
+
+    // Match the MCInstr.
+    unsigned ErrorInfo;
+    SmallVector<llvm::MCInst, 2> Instrs;
+    HadError = TargetParser->MatchInstruction(IDLoc, Operands, Instrs,
+                                              ErrorInfo,
+                                              /*matchingInlineAsm*/ true);
+    assert (!HadError && "Unexpected error matching instruction");
+    assert ((Instrs.size() == 1) && "Expected only a single instruction.");
+
+    // Get the instruction descriptor.
+    llvm::MCInst Inst = Instrs[0];
+    const llvm::MCInstrInfo *MII = TheTarget->createMCInstrInfo();
+    const llvm::MCInstrDesc &Desc = MII->get(Inst.getOpcode());
+    llvm::MCInstPrinter *IP =
+      TheTarget->createMCInstPrinter(1, *MAI, *MII, *MRI, *STI);
+
+    // Build the list of clobbers.
+    for (unsigned i = 0, e = Desc.getNumDefs(); i != e; ++i) {
+      const llvm::MCOperand &Op = Inst.getOperand(i);
+      if (!Op.isReg())
+        continue;
+
+      std::string Reg;
+      llvm::raw_string_ostream OS(Reg);
+      IP->printRegName(OS, Op.getReg());
+
+      StringRef Clobber(OS.str());
+      if (!Context.getTargetInfo().isValidClobber(Clobber))
+        return StmtError(Diag(AsmLoc, diag::err_asm_unknown_register_name) <<
+                         Clobber);
+      ClobberRegs.insert(Reg);
+    }
+  }
+  for (std::set<std::string>::iterator I = ClobberRegs.begin(),
+         E = ClobberRegs.end(); I != E; ++I)
+    Clobbers.push_back(*I);
+
+  MSAsmStmt *NS =
+    new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, IsSimple,
+                            /*IsVolatile*/ true, AsmToks, Inputs, Outputs,
+                            AsmString, Clobbers, EndLoc);
+  return Owned(NS);
+}
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 1c3feb5..4dbf3e4 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1064,8 +1064,10 @@
 
   // Add alignment attributes if necessary; these attributes are checked when
   // the ASTContext lays out the structure.
-  AddAlignmentAttributesForRecord(NewClass);
-  AddMsStructLayoutForRecord(NewClass);
+  if (TUK == TUK_Definition) {
+    AddAlignmentAttributesForRecord(NewClass);
+    AddMsStructLayoutForRecord(NewClass);
+  }
 
   ClassTemplateDecl *NewTemplate
     = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
@@ -1139,6 +1141,8 @@
   if (PrevClassTemplate)
     mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
 
+  ActOnDocumentableDecl(NewTemplate);
+
   return NewTemplate;
 }
 
@@ -5514,6 +5518,13 @@
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
+  // Add alignment attributes if necessary; these attributes are checked when
+  // the ASTContext lays out the structure.
+  if (TUK == TUK_Definition) {
+    AddAlignmentAttributesForRecord(Specialization);
+    AddMsStructLayoutForRecord(Specialization);
+  }
+
   if (ModulePrivateLoc.isValid())
     Diag(Specialization->getLocation(), diag::err_module_private_specialization)
       << (isPartialSpecialization? 1 : 0)
@@ -5568,7 +5579,9 @@
 Decl *Sema::ActOnTemplateDeclarator(Scope *S,
                               MultiTemplateParamsArg TemplateParameterLists,
                                     Declarator &D) {
-  return HandleDeclarator(S, D, move(TemplateParameterLists));
+  Decl *NewDecl = HandleDeclarator(S, D, move(TemplateParameterLists));
+  ActOnDocumentableDecl(NewDecl);
+  return NewDecl;
 }
 
 Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index d009e2f..20e755f 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -838,6 +838,19 @@
       return move(Result);
     }
 
+    ExprResult TransformLambdaExpr(LambdaExpr *E) {
+      LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+      return TreeTransform<TemplateInstantiator>::TransformLambdaExpr(E);
+    }
+
+    ExprResult TransformLambdaScope(LambdaExpr *E,
+                                    CXXMethodDecl *CallOperator) {
+      CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(),
+                                                     TSK_ImplicitInstantiation);
+      return TreeTransform<TemplateInstantiator>::
+         TransformLambdaScope(E, CallOperator);
+    }
+
   private:
     ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm,
                                                SourceLocation loc,
@@ -975,12 +988,11 @@
 
     SourceLocation TagLocation = KeywordLoc;
 
-    // FIXME: type might be anonymous.
     IdentifierInfo *Id = TD->getIdentifier();
 
     // TODO: should we even warn on struct/class mismatches for this?  Seems
     // like it's likely to produce a lot of spurious errors.
-    if (Keyword != ETK_None && Keyword != ETK_Typename) {
+    if (Id && Keyword != ETK_None && Keyword != ETK_Typename) {
       TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
       if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false,
                                                 TagLocation, *Id)) {
@@ -1983,8 +1995,7 @@
   Instantiator.disableLateAttributeInstantiation();
   LateAttrs.clear();
 
-  if (!FieldsWithMemberInitializers.empty())
-    ActOnFinishDelayedMemberInitializers(Instantiation);
+  ActOnFinishDelayedMemberInitializers(Instantiation);
 
   if (TSK == TSK_ImplicitInstantiation) {
     Instantiation->setLocation(Pattern->getLocation());
@@ -1993,6 +2004,9 @@
   }
 
   if (!Instantiation->isInvalidDecl()) {
+    // Perform any dependent diagnostics from the pattern.
+    PerformDependentDiagnostics(Pattern, TemplateArgs);
+
     // Instantiate any out-of-line class template partial
     // specializations now.
     for (TemplateDeclInstantiator::delayed_partial_spec_iterator 
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index aeda975..bdbe71d 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -935,8 +935,6 @@
   if (!Instantiated)
     return 0;
 
-  Instantiated->setAccess(D->getAccess());
-
   // Link the instantiated function template declaration to the function
   // template from which it was instantiated.
   FunctionTemplateDecl *InstTemplate
@@ -954,8 +952,12 @@
     InstTemplate->setInstantiatedFromMemberTemplate(D);
 
   // Make declarations visible in the appropriate context.
-  if (!isFriend)
+  if (!isFriend) {
     Owner->addDecl(InstTemplate);
+  } else if (InstTemplate->getDeclContext()->isRecord() &&
+             !D->getPreviousDecl()) {
+    SemaRef.CheckFriendAccess(InstTemplate);
+  }
 
   return InstTemplate;
 }
@@ -1526,7 +1528,15 @@
   if (D->isPure())
     SemaRef.CheckPureMethod(Method, SourceRange());
 
-  Method->setAccess(D->getAccess());
+  // Propagate access.  For a non-friend declaration, the access is
+  // whatever we're propagating from.  For a friend, it should be the
+  // previous declaration we just found.
+  if (isFriend && Method->getPreviousDecl())
+    Method->setAccess(Method->getPreviousDecl()->getAccess());
+  else 
+    Method->setAccess(D->getAccess());
+  if (FunctionTemplate)
+    FunctionTemplate->setAccess(Method->getAccess());
 
   SemaRef.CheckOverrideControl(Method);
 
@@ -1536,18 +1546,28 @@
   if (D->isDeletedAsWritten())
     Method->setDeletedAsWritten();
 
+  // If there's a function template, let our caller handle it.
   if (FunctionTemplate) {
-    // If there's a function template, let our caller handle it.
+    // do nothing
+
+  // Don't hide a (potentially) valid declaration with an invalid one.
   } else if (Method->isInvalidDecl() && !Previous.empty()) {
-    // Don't hide a (potentially) valid declaration with an invalid one.
-  } else {
-    NamedDecl *DeclToAdd = (TemplateParams
-                            ? cast<NamedDecl>(FunctionTemplate)
-                            : Method);
-    if (isFriend)
-      Record->makeDeclVisibleInContext(DeclToAdd);
-    else if (!IsClassScopeSpecialization)
-      Owner->addDecl(DeclToAdd);
+    // do nothing
+
+  // Otherwise, check access to friends and make them visible.
+  } else if (isFriend) {
+    // We only need to re-check access for methods which we didn't
+    // manage to match during parsing.
+    if (!D->getPreviousDecl())
+      SemaRef.CheckFriendAccess(Method);
+
+    Record->makeDeclVisibleInContext(Method);
+
+  // Otherwise, add the declaration.  We don't need to do this for
+  // class-scope specializations because we'll have matched them with
+  // the appropriate template.
+  } else if (!IsClassScopeSpecialization) {
+    Owner->addDecl(Method);
   }
 
   if (D->isExplicitlyDefaulted()) {
@@ -2395,8 +2415,17 @@
 
   InstantiatingTemplate Inst(*this, PointOfInstantiation, Decl,
                              InstantiatingTemplate::ExceptionSpecification());
-  if (Inst)
+  if (Inst) {
+    // We hit the instantiation depth limit. Clear the exception specification
+    // so that our callers don't have to cope with EST_Uninstantiated.
+    FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
+    EPI.ExceptionSpecType = EST_None;
+    Decl->setType(Context.getFunctionType(Proto->getResultType(),
+                                          Proto->arg_type_begin(),
+                                          Proto->getNumArgs(),
+                                          EPI));
     return;
+  }
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
@@ -2461,6 +2490,8 @@
       FunctionDecl *ExceptionSpecTemplate = Tmpl;
       if (EPI.ExceptionSpecType == EST_Uninstantiated)
         ExceptionSpecTemplate = EPI.ExceptionSpecTemplate;
+      assert(EPI.ExceptionSpecType != EST_Unevaluated &&
+             "instantiating implicitly-declared special member");
 
       // Mark the function has having an uninstantiated exception specification.
       const FunctionProtoType *NewProto
@@ -3431,7 +3462,7 @@
 void Sema::PerformPendingInstantiations(bool LocalOnly) {
   // Load pending instantiations from the external source.
   if (!LocalOnly && ExternalSource) {
-    SmallVector<std::pair<ValueDecl *, SourceLocation>, 4> Pending;
+    SmallVector<PendingImplicitInstantiation, 4> Pending;
     ExternalSource->ReadPendingInstantiations(Pending);
     PendingInstantiations.insert(PendingInstantiations.begin(),
                                  Pending.begin(), Pending.end());
diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index 0d0f992..aece90b 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/lib/Sema/SemaTemplateVariadic.cpp
@@ -12,6 +12,7 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/Template.h"
 #include "clang/AST/Expr.h"
@@ -34,10 +35,12 @@
 
     SmallVectorImpl<UnexpandedParameterPack> &Unexpanded;
 
+    bool InLambda;
+
   public:
     explicit CollectUnexpandedParameterPacksVisitor(
                   SmallVectorImpl<UnexpandedParameterPack> &Unexpanded)
-      : Unexpanded(Unexpanded) { }
+      : Unexpanded(Unexpanded), InLambda(false) { }
 
     bool shouldWalkTypesOfTypeLocs() const { return false; }
     
@@ -107,17 +110,17 @@
     /// \brief Suppress traversal into statements and expressions that
     /// do not contain unexpanded parameter packs.
     bool TraverseStmt(Stmt *S) { 
-      if (Expr *E = dyn_cast_or_null<Expr>(S))
-        if (E->containsUnexpandedParameterPack())
-          return inherited::TraverseStmt(E);
+      Expr *E = dyn_cast_or_null<Expr>(S);
+      if ((E && E->containsUnexpandedParameterPack()) || InLambda)
+        return inherited::TraverseStmt(S);
 
-      return true; 
+      return true;
     }
 
     /// \brief Suppress traversal into types that do not contain
     /// unexpanded parameter packs.
     bool TraverseType(QualType T) {
-      if (!T.isNull() && T->containsUnexpandedParameterPack())
+      if ((!T.isNull() && T->containsUnexpandedParameterPack()) || InLambda)
         return inherited::TraverseType(T);
 
       return true;
@@ -126,8 +129,9 @@
     /// \brief Suppress traversel into types with location information
     /// that do not contain unexpanded parameter packs.
     bool TraverseTypeLoc(TypeLoc TL) {
-      if (!TL.getType().isNull() && 
-          TL.getType()->containsUnexpandedParameterPack())
+      if ((!TL.getType().isNull() && 
+           TL.getType()->containsUnexpandedParameterPack()) ||
+          InLambda)
         return inherited::TraverseTypeLoc(TL);
 
       return true;
@@ -136,10 +140,10 @@
     /// \brief Suppress traversal of non-parameter declarations, since
     /// they cannot contain unexpanded parameter packs.
     bool TraverseDecl(Decl *D) { 
-      if (D && isa<ParmVarDecl>(D))
+      if ((D && isa<ParmVarDecl>(D)) || InLambda)
         return inherited::TraverseDecl(D);
 
-      return true; 
+      return true;
     }
 
     /// \brief Suppress traversal of template argument pack expansions.
@@ -157,17 +161,57 @@
       
       return inherited::TraverseTemplateArgumentLoc(ArgLoc);
     }
+
+    /// \brief Note whether we're traversing a lambda containing an unexpanded
+    /// parameter pack. In this case, the unexpanded pack can occur anywhere,
+    /// including all the places where we normally wouldn't look. Within a
+    /// lambda, we don't propagate the 'contains unexpanded parameter pack' bit
+    /// outside an expression.
+    bool TraverseLambdaExpr(LambdaExpr *Lambda) {
+      // The ContainsUnexpandedParameterPack bit on a lambda is always correct,
+      // even if it's contained within another lambda.
+      if (!Lambda->containsUnexpandedParameterPack())
+        return true;
+
+      bool WasInLambda = InLambda;
+      InLambda = true;
+
+      // If any capture names a function parameter pack, that pack is expanded
+      // when the lambda is expanded.
+      for (LambdaExpr::capture_iterator I = Lambda->capture_begin(),
+                                        E = Lambda->capture_end(); I != E; ++I)
+        if (VarDecl *VD = I->getCapturedVar())
+          if (VD->isParameterPack())
+            Unexpanded.push_back(std::make_pair(VD, I->getLocation()));
+
+      inherited::TraverseLambdaExpr(Lambda);
+
+      InLambda = WasInLambda;
+      return true;
+    }
   };
 }
 
 /// \brief Diagnose all of the unexpanded parameter packs in the given
 /// vector.
-void
+bool
 Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
                                        UnexpandedParameterPackContext UPPC,
                                  ArrayRef<UnexpandedParameterPack> Unexpanded) {
   if (Unexpanded.empty())
-    return;
+    return false;
+
+  // If we are within a lambda expression, that lambda contains an unexpanded
+  // parameter pack, and we are done.
+  // FIXME: Store 'Unexpanded' on the lambda so we don't need to recompute it
+  // later.
+  for (unsigned N = FunctionScopes.size(); N; --N) {
+    if (sema::LambdaScopeInfo *LSI =
+          dyn_cast<sema::LambdaScopeInfo>(FunctionScopes[N-1])) {
+      LSI->ContainsUnexpandedParameterPack = true;
+      return false;
+    }
+  }
   
   SmallVector<SourceLocation, 4> Locations;
   SmallVector<IdentifierInfo *, 4> Names;
@@ -200,6 +244,7 @@
 
   for (unsigned I = 0, N = Locations.size(); I != N; ++I)
     DB << SourceRange(Locations[I]);
+  return true;
 }
 
 bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc, 
@@ -215,8 +260,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseTypeLoc(
                                                               T->getTypeLoc());
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
-  return true;
+  return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
 }
 
 bool Sema::DiagnoseUnexpandedParameterPack(Expr *E,
@@ -230,8 +274,7 @@
   SmallVector<UnexpandedParameterPack, 2> Unexpanded;
   CollectUnexpandedParameterPacksVisitor(Unexpanded).TraverseStmt(E);
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
-  return true;
+  return DiagnoseUnexpandedParameterPacks(E->getLocStart(), UPPC, Unexpanded);
 }
 
 bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
@@ -247,9 +290,8 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseNestedNameSpecifier(SS.getScopeRep());
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(), 
-                                   UPPC, Unexpanded);
-  return true;
+  return DiagnoseUnexpandedParameterPacks(SS.getRange().getBegin(),
+                                          UPPC, Unexpanded);
 }
 
 bool Sema::DiagnoseUnexpandedParameterPack(const DeclarationNameInfo &NameInfo,
@@ -284,8 +326,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseType(NameInfo.getName().getCXXNameType());
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
-  return true;
+  return DiagnoseUnexpandedParameterPacks(NameInfo.getLoc(), UPPC, Unexpanded);
 }
 
 bool Sema::DiagnoseUnexpandedParameterPack(SourceLocation Loc,
@@ -299,8 +340,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseTemplateName(Template);
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
-  return true;
+  return DiagnoseUnexpandedParameterPacks(Loc, UPPC, Unexpanded);
 }
 
 bool Sema::DiagnoseUnexpandedParameterPack(TemplateArgumentLoc Arg,
@@ -313,8 +353,7 @@
   CollectUnexpandedParameterPacksVisitor(Unexpanded)
     .TraverseTemplateArgumentLoc(Arg);
   assert(!Unexpanded.empty() && "Unable to find unexpanded parameter packs");
-  DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
-  return true;  
+  return DiagnoseUnexpandedParameterPacks(Arg.getLocation(), UPPC, Unexpanded);
 }
 
 void Sema::collectUnexpandedParameterPacks(TemplateArgument Arg,
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 84e8a79..3e72c2d 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -554,7 +554,8 @@
   // ...and *prepend* it to the declarator.
   declarator.AddInnermostTypeInfo(DeclaratorChunk::getFunction(
                              /*proto*/ true,
-                             /*variadic*/ false, SourceLocation(),
+                             /*variadic*/ false,
+                             /*ambiguous*/ false, SourceLocation(),
                              /*args*/ 0, 0,
                              /*type quals*/ 0,
                              /*ref-qualifier*/true, SourceLocation(),
@@ -1084,7 +1085,7 @@
 
   // If we are in an unevaluated context, like sizeof, skip adding a
   // qualification.
-  } else if (S.ExprEvalContexts.back().Context == Sema::Unevaluated) {
+  } else if (S.isUnevaluatedContext()) {
     return type;
 
   // If that failed, give an error and recover using __strong.  __strong
@@ -1811,6 +1812,8 @@
     // Constructors and destructors don't have return types. Use
     // "void" instead.
     T = SemaRef.Context.VoidTy;
+    if (AttributeList *attrs = D.getDeclSpec().getAttributes().getList())
+      processTypeAttrs(state, T, true, attrs);
     break;
 
   case UnqualifiedId::IK_ConversionFunctionId:
@@ -2040,6 +2043,102 @@
     << getFunctionQualifiersAsString(T->castAs<FunctionProtoType>());
 }
 
+/// Produce an approprioate diagnostic for an ambiguity between a function
+/// declarator and a C++ direct-initializer.
+static void warnAboutAmbiguousFunction(Sema &S, Declarator &D,
+                                       DeclaratorChunk &DeclType, QualType RT) {
+  const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
+  assert(FTI.isAmbiguous && "no direct-initializer / function ambiguity");
+
+  // If the return type is void there is no ambiguity.
+  if (RT->isVoidType())
+    return;
+
+  // An initializer for a non-class type can have at most one argument.
+  if (!RT->isRecordType() && FTI.NumArgs > 1)
+    return;
+
+  // An initializer for a reference must have exactly one argument.
+  if (RT->isReferenceType() && FTI.NumArgs != 1)
+    return;
+
+  // Only warn if this declarator is declaring a function at block scope, and
+  // doesn't have a storage class (such as 'extern') specified.
+  if (!D.isFunctionDeclarator() ||
+      D.getFunctionDefinitionKind() != FDK_Declaration ||
+      !S.CurContext->isFunctionOrMethod() ||
+      D.getDeclSpec().getStorageClassSpecAsWritten()
+        != DeclSpec::SCS_unspecified)
+    return;
+
+  // Inside a condition, a direct initializer is not permitted. We allow one to
+  // be parsed in order to give better diagnostics in condition parsing.
+  if (D.getContext() == Declarator::ConditionContext)
+    return;
+
+  SourceRange ParenRange(DeclType.Loc, DeclType.EndLoc);
+
+  S.Diag(DeclType.Loc,
+         FTI.NumArgs ? diag::warn_parens_disambiguated_as_function_declaration
+                     : diag::warn_empty_parens_are_function_decl)
+    << ParenRange;
+
+  // If the declaration looks like:
+  //   T var1,
+  //   f();
+  // and name lookup finds a function named 'f', then the ',' was
+  // probably intended to be a ';'.
+  if (!D.isFirstDeclarator() && D.getIdentifier()) {
+    FullSourceLoc Comma(D.getCommaLoc(), S.SourceMgr);
+    FullSourceLoc Name(D.getIdentifierLoc(), S.SourceMgr);
+    if (Comma.getFileID() != Name.getFileID() ||
+        Comma.getSpellingLineNumber() != Name.getSpellingLineNumber()) {
+      LookupResult Result(S, D.getIdentifier(), SourceLocation(),
+                          Sema::LookupOrdinaryName);
+      if (S.LookupName(Result, S.getCurScope()))
+        S.Diag(D.getCommaLoc(), diag::note_empty_parens_function_call)
+          << FixItHint::CreateReplacement(D.getCommaLoc(), ";")
+          << D.getIdentifier();
+    }
+  }
+
+  if (FTI.NumArgs > 0) {
+    // For a declaration with parameters, eg. "T var(T());", suggest adding parens
+    // around the first parameter to turn the declaration into a variable
+    // declaration.
+    SourceRange Range = FTI.ArgInfo[0].Param->getSourceRange();
+    SourceLocation B = Range.getBegin();
+    SourceLocation E = S.PP.getLocForEndOfToken(Range.getEnd());
+    // FIXME: Maybe we should suggest adding braces instead of parens
+    // in C++11 for classes that don't have an initializer_list constructor.
+    S.Diag(B, diag::note_additional_parens_for_variable_declaration)
+      << FixItHint::CreateInsertion(B, "(")
+      << FixItHint::CreateInsertion(E, ")");
+  } else {
+    // For a declaration without parameters, eg. "T var();", suggest replacing the
+    // parens with an initializer to turn the declaration into a variable
+    // declaration.
+    const CXXRecordDecl *RD = RT->getAsCXXRecordDecl();
+
+    // Empty parens mean value-initialization, and no parens mean
+    // default initialization. These are equivalent if the default
+    // constructor is user-provided or if zero-initialization is a
+    // no-op.
+    if (RD && RD->hasDefinition() &&
+        (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor()))
+      S.Diag(DeclType.Loc, diag::note_empty_parens_default_ctor)
+        << FixItHint::CreateRemoval(ParenRange);
+    else {
+      std::string Init = S.getFixItZeroInitializerForType(RT);
+      if (Init.empty() && S.LangOpts.CPlusPlus0x)
+        Init = "{}";
+      if (!Init.empty())
+        S.Diag(DeclType.Loc, diag::note_empty_parens_zero_initialize)
+          << FixItHint::CreateReplacement(ParenRange, Init);
+    }
+  }
+}
+
 static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
                                                 QualType declSpecType,
                                                 TypeSourceInfo *TInfo) {
@@ -2159,6 +2258,51 @@
         ASM = ArrayType::Normal;
         D.setInvalidType(true);
       }
+
+      // C99 6.7.5.2p1: The optional type qualifiers and the keyword static
+      // shall appear only in a declaration of a function parameter with an
+      // array type, ...
+      if (ASM == ArrayType::Static || ATI.TypeQuals) {
+        if (!(D.isPrototypeContext() ||
+              D.getContext() == Declarator::KNRTypeListContext)) {
+          S.Diag(DeclType.Loc, diag::err_array_static_outside_prototype) <<
+              (ASM == ArrayType::Static ? "'static'" : "type qualifier");
+          // Remove the 'static' and the type qualifiers.
+          if (ASM == ArrayType::Static)
+            ASM = ArrayType::Normal;
+          ATI.TypeQuals = 0;
+          D.setInvalidType(true);
+        }
+
+        // C99 6.7.5.2p1: ... and then only in the outermost array type
+        // derivation.
+        unsigned x = chunkIndex;
+        while (x != 0) {
+          // Walk outwards along the declarator chunks.
+          x--;
+          const DeclaratorChunk &DC = D.getTypeObject(x);
+          switch (DC.Kind) {
+          case DeclaratorChunk::Paren:
+            continue;
+          case DeclaratorChunk::Array:
+          case DeclaratorChunk::Pointer:
+          case DeclaratorChunk::Reference:
+          case DeclaratorChunk::MemberPointer:
+            S.Diag(DeclType.Loc, diag::err_array_static_not_outermost) <<
+              (ASM == ArrayType::Static ? "'static'" : "type qualifier");
+            if (ASM == ArrayType::Static)
+              ASM = ArrayType::Normal;
+            ATI.TypeQuals = 0;
+            D.setInvalidType(true);
+            break;
+          case DeclaratorChunk::Function:
+          case DeclaratorChunk::BlockPointer:
+            // These are invalid anyway, so just ignore.
+            break;
+          }
+        }
+      }
+
       T = S.BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals,
                            SourceRange(DeclType.Loc, DeclType.EndLoc), Name);
       break;
@@ -2272,6 +2416,11 @@
           << (D.getContext() == Declarator::AliasDeclContext ||
               D.getContext() == Declarator::AliasTemplateContext);
 
+      // If we see "T var();" or "T var(T());" at block scope, it is probably
+      // an attempt to initialize a variable, not a function declaration.
+      if (FTI.isAmbiguous)
+        warnAboutAmbiguousFunction(S, D, DeclType, T);
+
       if (!FTI.NumArgs && !FTI.isVariadic && !LangOpts.CPlusPlus) {
         // Simple void foo(), where the incoming T is the result type.
         T = Context.getFunctionNoProtoType(T);
@@ -3120,7 +3269,6 @@
       assert(Chunk.Kind == DeclaratorChunk::Function);
       TL.setLocalRangeBegin(Chunk.Loc);
       TL.setLocalRangeEnd(Chunk.EndLoc);
-      TL.setTrailingReturn(Chunk.Fun.hasTrailingReturnType());
 
       const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
       for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) {
@@ -3440,7 +3588,7 @@
 
   // Forbid __weak if the runtime doesn't support it.
   if (lifetime == Qualifiers::OCL_Weak &&
-      !S.getLangOpts().ObjCRuntimeHasWeak && !NonObjCPointer) {
+      !S.getLangOpts().ObjCARCWeak && !NonObjCPointer) {
 
     // Actually, delay this until we know what we're parsing.
     if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index fff3b3f..391c0b3 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -98,25 +98,25 @@
   class ForgetPartiallySubstitutedPackRAII {
     Derived &Self;
     TemplateArgument Old;
-    
+
   public:
     ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
       Old = Self.ForgetPartiallySubstitutedPack();
     }
-    
+
     ~ForgetPartiallySubstitutedPackRAII() {
       Self.RememberPartiallySubstitutedPack(Old);
     }
   };
-  
+
 protected:
   Sema &SemaRef;
-  
+
   /// \brief The set of local declarations that have been transformed, for
   /// cases where we are forced to build new declarations within the transformer
   /// rather than in the subclass (e.g., lambda closure types).
   llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
-  
+
 public:
   /// \brief Initializes a new tree transformer.
   TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
@@ -177,7 +177,7 @@
                   DeclarationName Entity) : Self(Self) {
       OldLocation = Self.getDerived().getBaseLocation();
       OldEntity = Self.getDerived().getBaseEntity();
-      
+
       if (Location.isValid())
         Self.getDerived().setBase(Location, Entity);
     }
@@ -207,7 +207,7 @@
   bool DropCallArgument(Expr *E) {
     return E->isDefaultArgument();
   }
-  
+
   /// \brief Determine whether we should expand a pack expansion with the
   /// given set of parameter packs into separate arguments by repeatedly
   /// transforming the pattern.
@@ -221,7 +221,7 @@
   /// \param PatternRange The source range that covers the entire pattern of
   /// the pack expansion.
   ///
-  /// \param Unexpanded The set of unexpanded parameter packs within the 
+  /// \param Unexpanded The set of unexpanded parameter packs within the
   /// pattern.
   ///
   /// \param ShouldExpand Will be set to \c true if the transformer should
@@ -241,9 +241,9 @@
   /// The callee must set this value when \c ShouldExpand is \c true; it may
   /// set this value in other cases.
   ///
-  /// \returns true if an error occurred (e.g., because the parameter packs 
-  /// are to be instantiated with arguments of different lengths), false 
-  /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) 
+  /// \returns true if an error occurred (e.g., because the parameter packs
+  /// are to be instantiated with arguments of different lengths), false
+  /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
   /// must be set.
   bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
                                SourceRange PatternRange,
@@ -254,7 +254,7 @@
     ShouldExpand = false;
     return false;
   }
-  
+
   /// \brief "Forget" about the partially-substituted pack template argument,
   /// when performing an instantiation that must preserve the parameter pack
   /// use.
@@ -263,18 +263,18 @@
   TemplateArgument ForgetPartiallySubstitutedPack() {
     return TemplateArgument();
   }
-  
+
   /// \brief "Remember" the partially-substituted pack template argument
   /// after performing an instantiation that must preserve the parameter pack
   /// use.
   ///
   /// This routine is meant to be overridden by the template instantiator.
   void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
-  
+
   /// \brief Note to the derived class when a function parameter pack is
   /// being expanded.
   void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
-                                      
+
   /// \brief Transforms the given type into another type.
   ///
   /// By default, this routine transforms a type by creating a
@@ -325,8 +325,8 @@
 
   /// \brief Transform the given list of expressions.
   ///
-  /// This routine transforms a list of expressions by invoking 
-  /// \c TransformExpr() for each subexpression. However, it also provides 
+  /// This routine transforms a list of expressions by invoking
+  /// \c TransformExpr() for each subexpression. However, it also provides
   /// support for variadic templates by expanding any pack expansions (if the
   /// derived class permits such expansion) along the way. When pack expansions
   /// are present, the number of outputs may not equal the number of inputs.
@@ -336,7 +336,7 @@
   /// \param NumInputs The number of expressions in \c Inputs.
   ///
   /// \param IsCall If \c true, then this transform is being performed on
-  /// function-call arguments, and any arguments that should be dropped, will 
+  /// function-call arguments, and any arguments that should be dropped, will
   /// be.
   ///
   /// \param Outputs The transformed input expressions will be added to this
@@ -349,61 +349,61 @@
   bool TransformExprs(Expr **Inputs, unsigned NumInputs, bool IsCall,
                       SmallVectorImpl<Expr *> &Outputs,
                       bool *ArgChanged = 0);
-  
+
   /// \brief Transform the given declaration, which is referenced from a type
   /// or expression.
   ///
   /// By default, acts as the identity function on declarations, unless the
   /// transformer has had to transform the declaration itself. Subclasses
   /// may override this function to provide alternate behavior.
-  Decl *TransformDecl(SourceLocation Loc, Decl *D) { 
+  Decl *TransformDecl(SourceLocation Loc, Decl *D) {
     llvm::DenseMap<Decl *, Decl *>::iterator Known
       = TransformedLocalDecls.find(D);
     if (Known != TransformedLocalDecls.end())
       return Known->second;
-    
-    return D; 
+
+    return D;
   }
 
-  /// \brief Transform the attributes associated with the given declaration and 
+  /// \brief Transform the attributes associated with the given declaration and
   /// place them on the new declaration.
   ///
   /// By default, this operation does nothing. Subclasses may override this
   /// behavior to transform attributes.
   void transformAttrs(Decl *Old, Decl *New) { }
-  
+
   /// \brief Note that a local declaration has been transformed by this
   /// transformer.
   ///
-  /// Local declarations are typically transformed via a call to 
+  /// Local declarations are typically transformed via a call to
   /// TransformDefinition. However, in some cases (e.g., lambda expressions),
   /// the transformer itself has to transform the declarations. This routine
   /// can be overridden by a subclass that keeps track of such mappings.
   void transformedLocalDecl(Decl *Old, Decl *New) {
     TransformedLocalDecls[Old] = New;
   }
-  
+
   /// \brief Transform the definition of the given declaration.
   ///
   /// By default, invokes TransformDecl() to transform the declaration.
   /// Subclasses may override this function to provide alternate behavior.
-  Decl *TransformDefinition(SourceLocation Loc, Decl *D) { 
-    return getDerived().TransformDecl(Loc, D); 
+  Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
+    return getDerived().TransformDecl(Loc, D);
   }
 
   /// \brief Transform the given declaration, which was the first part of a
   /// nested-name-specifier in a member access expression.
   ///
-  /// This specific declaration transformation only applies to the first 
+  /// This specific declaration transformation only applies to the first
   /// identifier in a nested-name-specifier of a member access expression, e.g.,
   /// the \c T in \c x->T::member
   ///
   /// By default, invokes TransformDecl() to transform the declaration.
   /// Subclasses may override this function to provide alternate behavior.
-  NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) { 
-    return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D)); 
+  NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
+    return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
   }
-  
+
   /// \brief Transform the given nested-name-specifier with source-location
   /// information.
   ///
@@ -433,7 +433,7 @@
   ///
   /// \param NameLoc The source location of the template name.
   ///
-  /// \param ObjectType If we're translating a template name within a member 
+  /// \param ObjectType If we're translating a template name within a member
   /// access expression, this is the type of the object whose member template
   /// is being referenced.
   ///
@@ -463,7 +463,7 @@
 
   /// \brief Transform the given set of template arguments.
   ///
-  /// By default, this operation transforms all of the template arguments 
+  /// By default, this operation transforms all of the template arguments
   /// in the input set using \c TransformTemplateArgument(), and appends
   /// the transformed arguments to the output list.
   ///
@@ -487,9 +487,9 @@
 
   /// \brief Transform the given set of template arguments.
   ///
-  /// By default, this operation transforms all of the template arguments 
+  /// By default, this operation transforms all of the template arguments
   /// in the input set using \c TransformTemplateArgument(), and appends
-  /// the transformed arguments to the output list. 
+  /// the transformed arguments to the output list.
   ///
   /// \param First An iterator to the first template argument.
   ///
@@ -527,18 +527,18 @@
   StmtResult
   TransformSEHHandler(Stmt *Handler);
 
-  QualType 
+  QualType
   TransformTemplateSpecializationType(TypeLocBuilder &TLB,
                                       TemplateSpecializationTypeLoc TL,
                                       TemplateName Template);
 
-  QualType 
+  QualType
   TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
                                       DependentTemplateSpecializationTypeLoc TL,
                                                TemplateName Template,
                                                CXXScopeSpec &SS);
 
-  QualType 
+  QualType
   TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
                                                DependentTemplateSpecializationTypeLoc TL,
                                          NestedNameSpecifierLoc QualifierLoc);
@@ -571,6 +571,9 @@
   StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
   ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
 
+  /// \brief Transform the captures and body of a lambda expression.
+  ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator);
+
 #define STMT(Node, Parent)                        \
   StmtResult Transform##Node(Node *S);
 #define EXPR(Node, Parent)                        \
@@ -781,8 +784,8 @@
                                  ElaboratedTypeKeyword Keyword,
                                  NestedNameSpecifierLoc QualifierLoc,
                                  QualType Named) {
-    return SemaRef.Context.getElaboratedType(Keyword, 
-                                         QualifierLoc.getNestedNameSpecifier(), 
+    return SemaRef.Context.getElaboratedType(Keyword,
+                                         QualifierLoc.getNestedNameSpecifier(),
                                              Named);
   }
 
@@ -801,30 +804,30 @@
     // TODO: avoid TemplateName abstraction
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
-    TemplateName InstName 
+    TemplateName InstName
       = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(), 0);
-    
+
     if (InstName.isNull())
       return QualType();
-    
+
     // If it's still dependent, make a dependent specialization.
     if (InstName.getAsDependentTemplateName())
-      return SemaRef.Context.getDependentTemplateSpecializationType(Keyword, 
-                                          QualifierLoc.getNestedNameSpecifier(), 
-                                                                    Name, 
+      return SemaRef.Context.getDependentTemplateSpecializationType(Keyword,
+                                          QualifierLoc.getNestedNameSpecifier(),
+                                                                    Name,
                                                                     Args);
-    
+
     // Otherwise, make an elaborated type wrapping a non-dependent
     // specialization.
     QualType T =
     getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
     if (T.isNull()) return QualType();
-    
+
     if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == 0)
       return T;
-    
-    return SemaRef.Context.getElaboratedType(Keyword, 
-                                       QualifierLoc.getNestedNameSpecifier(), 
+
+    return SemaRef.Context.getElaboratedType(Keyword,
+                                       QualifierLoc.getNestedNameSpecifier(),
                                              T);
   }
 
@@ -844,8 +847,8 @@
     if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
       // If the name is still dependent, just build a new dependent name type.
       if (!SemaRef.computeDeclContext(SS))
-        return SemaRef.Context.getDependentNameType(Keyword, 
-                                          QualifierLoc.getNestedNameSpecifier(), 
+        return SemaRef.Context.getDependentNameType(Keyword,
+                                          QualifierLoc.getNestedNameSpecifier(),
                                                     Id);
     }
 
@@ -872,15 +875,15 @@
       case LookupResult::NotFound:
       case LookupResult::NotFoundInCurrentInstantiation:
         break;
-        
+
       case LookupResult::Found:
         Tag = Result.getAsSingle<TagDecl>();
         break;
-        
+
       case LookupResult::FoundOverloaded:
       case LookupResult::FoundUnresolvedValue:
         llvm_unreachable("Tag lookup cannot find non-tags");
-        
+
       case LookupResult::Ambiguous:
         // Let the LookupResult structure handle ambiguities.
         return QualType();
@@ -922,8 +925,8 @@
 
     // Build the elaborated-type-specifier type.
     QualType T = SemaRef.Context.getTypeDeclType(Tag);
-    return SemaRef.Context.getElaboratedType(Keyword, 
-                                         QualifierLoc.getNestedNameSpecifier(), 
+    return SemaRef.Context.getElaboratedType(Keyword,
+                                         QualifierLoc.getNestedNameSpecifier(),
                                              T);
   }
 
@@ -931,7 +934,7 @@
   ///
   /// By default, builds a new PackExpansionType type from the given pattern.
   /// Subclasses may override this routine to provide different behavior.
-  QualType RebuildPackExpansionType(QualType Pattern, 
+  QualType RebuildPackExpansionType(QualType Pattern,
                                     SourceRange PatternRange,
                                     SourceLocation EllipsisLoc,
                                     llvm::Optional<unsigned> NumExpansions) {
@@ -981,7 +984,7 @@
                                    QualType ObjectType);
 
   /// \brief Build a new template name given a template template parameter pack
-  /// and the 
+  /// and the
   ///
   /// By default, performs semantic analysis to determine whether the name can
   /// be resolved to a specific template, then builds the appropriate kind of
@@ -1061,7 +1064,7 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
-                           VarDecl *CondVar, Stmt *Then, 
+                           VarDecl *CondVar, Stmt *Then,
                            SourceLocation ElseLoc, Stmt *Else) {
     return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
   }
@@ -1072,7 +1075,7 @@
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
                                     Expr *Cond, VarDecl *CondVar) {
-    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond, 
+    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,
                                             CondVar);
   }
 
@@ -1110,10 +1113,10 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
-                            Stmt *Init, Sema::FullExprArg Cond, 
+                            Stmt *Init, Sema::FullExprArg Cond,
                             VarDecl *CondVar, Sema::FullExprArg Inc,
                             SourceLocation RParenLoc, Stmt *Body) {
-    return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, 
+    return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
                                   CondVar, Inc, RParenLoc, Body);
   }
 
@@ -1169,12 +1172,11 @@
                                   MultiExprArg Exprs,
                                   Expr *AsmString,
                                   MultiExprArg Clobbers,
-                                  SourceLocation RParenLoc,
-                                  bool MSAsm) {
-    return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, 
+                                  SourceLocation RParenLoc) {
+    return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
                                   NumInputs, Names, move(Constraints),
                                   Exprs, AsmString, Clobbers,
-                                  RParenLoc, MSAsm);
+                                  RParenLoc);
   }
 
   /// \brief Build a new MS style inline asm statement.
@@ -1182,9 +1184,10 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc,
-                              std::string &AsmString,
+                              SourceLocation LBraceLoc,
+                              ArrayRef<Token> AsmToks,
                               SourceLocation EndLoc) {
-    return getSema().ActOnMSAsmStmt(AsmLoc, AsmString, EndLoc);
+    return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, EndLoc);
   }
 
   /// \brief Build a new Objective-C \@try statement.
@@ -1210,7 +1213,7 @@
                                             ExceptionDecl->getLocation(),
                                             ExceptionDecl->getIdentifier());
   }
-  
+
   /// \brief Build a new Objective-C \@catch statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -1222,7 +1225,7 @@
     return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
                                           Var, Body);
   }
-  
+
   /// \brief Build a new Objective-C \@finally statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -1231,7 +1234,7 @@
                                             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.
@@ -1240,7 +1243,7 @@
                                           Expr *Operand) {
     return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
   }
-  
+
   /// \brief Rebuild the operand to an Objective-C \@synchronized statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -1273,12 +1276,11 @@
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
   StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
-                                          SourceLocation LParenLoc,
                                           Stmt *Element,
                                           Expr *Collection,
                                           SourceLocation RParenLoc,
                                           Stmt *Body) {
-    StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
+    StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
                                                 Element,
                                                 Collection,
                                                 RParenLoc);
@@ -1287,7 +1289,7 @@
 
     return getSema().FinishObjCForCollectionStmt(ForEachStmt.take(), Body);
   }
-  
+
   /// \brief Build a new C++ exception declaration.
   ///
   /// By default, performs semantic analysis to build the new decaration.
@@ -1336,14 +1338,14 @@
                                     Stmt *LoopVar,
                                     SourceLocation RParenLoc) {
     return getSema().BuildCXXForRangeStmt(ForLoc, ColonLoc, Range, BeginEnd,
-                                          Cond, Inc, LoopVar, RParenLoc);
+                                          Cond, Inc, LoopVar, RParenLoc, false);
   }
 
   /// \brief Build a new C++0x range-based for statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, 
+  StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
                                           bool IsIfExists,
                                           NestedNameSpecifierLoc QualifierLoc,
                                           DeclarationNameInfo NameInfo,
@@ -1359,7 +1361,7 @@
   StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
     return getSema().FinishCXXForRangeStmt(ForRange, Body);
   }
-  
+
   StmtResult RebuildSEHTryStmt(bool IsCXXTry,
                                SourceLocation TryLoc,
                                Stmt *TryBlock,
@@ -1449,8 +1451,8 @@
     return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
                                           NumComponents, RParenLoc);
   }
-  
-  /// \brief Build a new sizeof, alignof or vec_step expression with a 
+
+  /// \brief Build a new sizeof, alignof or vec_step expression with a
   /// type argument.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -1638,7 +1640,7 @@
       = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
     if (Result.isInvalid() || ResultTy->isDependentType())
       return move(Result);
-    
+
     // Patch in the result type we were given, which may have been computed
     // when the initial InitListExpr was built.
     InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get());
@@ -1888,7 +1890,7 @@
                                         SourceLocation TypeidLoc,
                                         TypeSourceInfo *Operand,
                                         SourceLocation RParenLoc) {
-    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, 
+    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
                                     RParenLoc);
   }
 
@@ -1913,7 +1915,7 @@
                                         SourceLocation TypeidLoc,
                                         TypeSourceInfo *Operand,
                                         SourceLocation RParenLoc) {
-    return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, 
+    return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand,
                                     RParenLoc);
   }
 
@@ -1957,7 +1959,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.
-  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 
+  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
                                             ParmVarDecl *Param) {
     return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
                                                      Param));
@@ -2047,7 +2049,7 @@
                               SourceLocation RParenLoc) {
     return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
   }
-  
+
   /// \brief Build a new array type trait expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -2118,10 +2120,10 @@
                              CXXConstructExpr::ConstructionKind ConstructKind,
                                      SourceRange ParenRange) {
     ASTOwningVector<Expr*> ConvertedArgs(SemaRef);
-    if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc, 
+    if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc,
                                           ConvertedArgs))
       return ExprError();
-    
+
     return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
                                            move_arg(ConvertedArgs),
                                            HadMultipleCandidates,
@@ -2212,17 +2214,17 @@
   }
 
   /// \brief Build a new expression to compute the length of a parameter pack.
-  ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack, 
-                                   SourceLocation PackLoc, 
+  ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
+                                   SourceLocation PackLoc,
                                    SourceLocation RParenLoc,
                                    llvm::Optional<unsigned> Length) {
     if (Length)
-      return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(), 
-                                                  OperatorLoc, Pack, PackLoc, 
+      return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(),
+                                                  OperatorLoc, Pack, PackLoc,
                                                   RParenLoc, *Length);
-    
-    return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(), 
-                                                OperatorLoc, Pack, PackLoc, 
+
+    return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(),
+                                                OperatorLoc, Pack, PackLoc,
                                                 RParenLoc);
   }
 
@@ -2233,18 +2235,18 @@
   ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
     return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
   }
-  
+
   /// \brief Build a new Objective-C array literal.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildObjCArrayLiteral(SourceRange Range,
                                      Expr **Elements, unsigned NumElements) {
-    return getSema().BuildObjCArrayLiteral(Range, 
+    return getSema().BuildObjCArrayLiteral(Range,
                                            MultiExprArg(Elements, NumElements));
   }
- 
-  ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, 
+
+  ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
                                          Expr *Base, Expr *Key,
                                          ObjCMethodDecl *getterMethod,
                                          ObjCMethodDecl *setterMethod) {
@@ -2261,7 +2263,7 @@
                                           unsigned NumElements) {
     return getSema().BuildObjCDictionaryLiteral(Range, Elements, NumElements);
   }
-  
+
   /// \brief Build a new Objective-C \@encode expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -2278,7 +2280,7 @@
                                           Selector Sel,
                                           ArrayRef<SourceLocation> SelectorLocs,
                                           ObjCMethodDecl *Method,
-                                          SourceLocation LBracLoc, 
+                                          SourceLocation LBracLoc,
                                           MultiExprArg Args,
                                           SourceLocation RBracLoc) {
     return SemaRef.BuildClassMessage(ReceiverTypeInfo,
@@ -2293,7 +2295,7 @@
                                           Selector Sel,
                                           ArrayRef<SourceLocation> SelectorLocs,
                                           ObjCMethodDecl *Method,
-                                          SourceLocation LBracLoc, 
+                                          SourceLocation LBracLoc,
                                           MultiExprArg Args,
                                           SourceLocation RBracLoc) {
     return SemaRef.BuildInstanceMessage(Receiver,
@@ -2321,15 +2323,15 @@
                                                          false);
     if (Result.isInvalid() || Base.isInvalid())
       return ExprError();
-    
+
     if (Result.get())
       return move(Result);
-    
+
     return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
                                               /*FIXME:*/IvarLoc, IsArrow,
                                               SS, SourceLocation(),
                                               /*FirstQualifierInScope=*/0,
-                                              R, 
+                                              R,
                                               /*TemplateArgs=*/0);
   }
 
@@ -2337,7 +2339,7 @@
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, 
+  ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
                                         ObjCPropertyDecl *Property,
                                         SourceLocation PropertyLoc) {
     CXXScopeSpec SS;
@@ -2350,18 +2352,18 @@
                                                          SS, 0, false);
     if (Result.isInvalid() || Base.isInvalid())
       return ExprError();
-    
+
     if (Result.get())
       return move(Result);
-    
+
     return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
-                                              /*FIXME:*/PropertyLoc, IsArrow, 
+                                              /*FIXME:*/PropertyLoc, IsArrow,
                                               SS, SourceLocation(),
                                               /*FirstQualifierInScope=*/0,
-                                              R, 
+                                              R,
                                               /*TemplateArgs=*/0);
   }
-  
+
   /// \brief Build a new Objective-C property reference expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -2393,18 +2395,18 @@
                                                          SS, 0, false);
     if (Result.isInvalid() || Base.isInvalid())
       return ExprError();
-    
+
     if (Result.get())
       return move(Result);
-    
+
     return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
                                               /*FIXME:*/IsaLoc, IsArrow,
                                               SS, SourceLocation(),
                                               /*FirstQualifierInScope=*/0,
-                                              R, 
+                                              R,
                                               /*TemplateArgs=*/0);
   }
-  
+
   /// \brief Build a new shuffle vector expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -2446,7 +2448,7 @@
   /// \brief Build a new template argument pack expansion.
   ///
   /// By default, performs semantic analysis to build a new pack expansion
-  /// for a template argument. Subclasses may override this routine to provide 
+  /// for a template argument. Subclasses may override this routine to provide
   /// different behavior.
   TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
                                            SourceLocation EllipsisLoc,
@@ -2458,10 +2460,10 @@
                                        EllipsisLoc, NumExpansions);
       if (Result.isInvalid())
         return TemplateArgumentLoc();
-          
+
       return TemplateArgumentLoc(Result.get(), Result.get());
     }
-        
+
     case TemplateArgument::Template:
       return TemplateArgumentLoc(TemplateArgument(
                                           Pattern.getArgument().getAsTemplate(),
@@ -2469,16 +2471,16 @@
                                  Pattern.getTemplateQualifierLoc(),
                                  Pattern.getTemplateNameLoc(),
                                  EllipsisLoc);
-        
+
     case TemplateArgument::Null:
     case TemplateArgument::Integral:
     case TemplateArgument::Declaration:
     case TemplateArgument::Pack:
     case TemplateArgument::TemplateExpansion:
       llvm_unreachable("Pack expansion pattern has no parameter packs");
-        
+
     case TemplateArgument::Type:
-      if (TypeSourceInfo *Expansion 
+      if (TypeSourceInfo *Expansion
             = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
                                            EllipsisLoc,
                                            NumExpansions))
@@ -2486,14 +2488,14 @@
                                    Expansion);
       break;
     }
-    
+
     return TemplateArgumentLoc();
   }
-  
+
   /// \brief Build a new expression pack expansion.
   ///
   /// By default, performs semantic analysis to build a new pack expansion
-  /// for an expression. Subclasses may override this routine to provide 
+  /// for an expression. Subclasses may override this routine to provide
   /// different behavior.
   ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
                                   llvm::Optional<unsigned> NumExpansions) {
@@ -2582,8 +2584,8 @@
 }
 
 template<typename Derived>
-bool TreeTransform<Derived>::TransformExprs(Expr **Inputs, 
-                                            unsigned NumInputs, 
+bool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
+                                            unsigned NumInputs,
                                             bool IsCall,
                                       SmallVectorImpl<Expr *> &Outputs,
                                             bool *ArgChanged) {
@@ -2592,17 +2594,17 @@
     if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
       if (ArgChanged)
         *ArgChanged = true;
-      
+
       break;
     }
-    
+
     if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
       Expr *Pattern = Expansion->getPattern();
-        
+
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
       getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
       assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
-      
+
       // Determine whether the set of unexpanded parameter packs can and should
       // be expanded.
       bool Expand = true;
@@ -2616,22 +2618,22 @@
                                                Expand, RetainExpansion,
                                                NumExpansions))
         return true;
-        
+
       if (!Expand) {
         // The transform has determined that we should perform a simple
-        // transformation on the pack expansion, producing another pack 
+        // transformation on the pack expansion, producing another pack
         // expansion.
         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
         ExprResult OutPattern = getDerived().TransformExpr(Pattern);
         if (OutPattern.isInvalid())
           return true;
-        
-        ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(), 
+
+        ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
                                                 Expansion->getEllipsisLoc(),
                                                            NumExpansions);
         if (Out.isInvalid())
           return true;
-        
+
         if (ArgChanged)
           *ArgChanged = true;
         Outputs.push_back(Out.get());
@@ -2641,7 +2643,7 @@
       // Record right away that the argument was changed.  This needs
       // to happen even if the array expands to nothing.
       if (ArgChanged) *ArgChanged = true;
-      
+
       // The transform has determined that we should perform an elementwise
       // expansion of the pattern. Do so.
       for (unsigned I = 0; I != *NumExpansions; ++I) {
@@ -2656,23 +2658,23 @@
           if (Out.isInvalid())
             return true;
         }
-        
+
         Outputs.push_back(Out.get());
       }
-        
+
       continue;
     }
-    
+
     ExprResult Result = getDerived().TransformExpr(Inputs[I]);
     if (Result.isInvalid())
       return true;
-    
+
     if (Result.get() != Inputs[I] && ArgChanged)
       *ArgChanged = true;
-    
-    Outputs.push_back(Result.get());    
+
+    Outputs.push_back(Result.get());
   }
-  
+
   return false;
 }
 
@@ -2683,7 +2685,7 @@
                                                      QualType ObjectType,
                                              NamedDecl *FirstQualifierInScope) {
   SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
-  for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; 
+  for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
        Qualifier = Qualifier.getPrefix())
     Qualifiers.push_back(Qualifier);
 
@@ -2691,19 +2693,19 @@
   while (!Qualifiers.empty()) {
     NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
     NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
-    
+
     switch (QNNS->getKind()) {
     case NestedNameSpecifier::Identifier:
-      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0, 
+      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0,
                                               *QNNS->getAsIdentifier(),
-                                              Q.getLocalBeginLoc(), 
+                                              Q.getLocalBeginLoc(),
                                               Q.getLocalEndLoc(),
-                                              ObjectType, false, SS, 
+                                              ObjectType, false, SS,
                                               FirstQualifierInScope, false))
         return NestedNameSpecifierLoc();
-        
+
       break;
-      
+
     case NestedNameSpecifier::Namespace: {
       NamespaceDecl *NS
         = cast_or_null<NamespaceDecl>(
@@ -2713,35 +2715,35 @@
       SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
       break;
     }
-      
+
     case NestedNameSpecifier::NamespaceAlias: {
       NamespaceAliasDecl *Alias
         = cast_or_null<NamespaceAliasDecl>(
                       getDerived().TransformDecl(Q.getLocalBeginLoc(),
                                                  QNNS->getAsNamespaceAlias()));
-      SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(), 
+      SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
                 Q.getLocalEndLoc());
       break;
     }
-      
+
     case NestedNameSpecifier::Global:
       // There is no meaningful transformation that one could perform on the
       // global scope.
       SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
       break;
-      
+
     case NestedNameSpecifier::TypeSpecWithTemplate:
     case NestedNameSpecifier::TypeSpec: {
       TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
                                               FirstQualifierInScope, SS);
-      
+
       if (!TL)
         return NestedNameSpecifierLoc();
-      
+
       if (TL.getType()->isDependentType() || TL.getType()->isRecordType() ||
-          (SemaRef.getLangOpts().CPlusPlus0x && 
+          (SemaRef.getLangOpts().CPlusPlus0x &&
            TL.getType()->isEnumeralType())) {
-        assert(!TL.getType().hasLocalQualifiers() && 
+        assert(!TL.getType().hasLocalQualifiers() &&
                "Can't get cv-qualifiers here");
         if (TL.getType()->isEnumeralType())
           SemaRef.Diag(TL.getBeginLoc(),
@@ -2754,24 +2756,24 @@
       // error because a previous error should have already been emitted.
       TypedefTypeLoc* TTL = dyn_cast<TypedefTypeLoc>(&TL);
       if (!TTL || !TTL->getTypedefNameDecl()->isInvalidDecl()) {
-        SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) 
+        SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
           << TL.getType() << SS.getRange();
       }
       return NestedNameSpecifierLoc();
     }
     }
-    
+
     // The qualifier-in-scope and object type only apply to the leftmost entity.
     FirstQualifierInScope = 0;
     ObjectType = QualType();
   }
-  
+
   // Don't rebuild the nested-name-specifier if we don't have to.
-  if (SS.getScopeRep() == NNS.getNestedNameSpecifier() && 
+  if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
       !getDerived().AlwaysRebuild())
     return NNS;
-  
-  // If we can re-use the source-location data from the original 
+
+  // If we can re-use the source-location data from the original
   // nested-name-specifier, do so.
   if (SS.location_size() == NNS.getDataLength() &&
       memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
@@ -2842,60 +2844,60 @@
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
     TemplateDecl *Template = QTN->getTemplateDecl();
     assert(Template && "qualified template name must refer to a template");
-    
+
     TemplateDecl *TransTemplate
-      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, 
+      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
                                                               Template));
     if (!TransTemplate)
       return TemplateName();
-      
+
     if (!getDerived().AlwaysRebuild() &&
         SS.getScopeRep() == QTN->getQualifier() &&
         TransTemplate == Template)
       return Name;
-      
+
     return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
                                             TransTemplate);
   }
-  
+
   if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
     if (SS.getScopeRep()) {
       // These apply to the scope specifier, not the template.
       ObjectType = QualType();
       FirstQualifierInScope = 0;
-    }      
-    
+    }
+
     if (!getDerived().AlwaysRebuild() &&
         SS.getScopeRep() == DTN->getQualifier() &&
         ObjectType.isNull())
       return Name;
-    
+
     if (DTN->isIdentifier()) {
       return getDerived().RebuildTemplateName(SS,
-                                              *DTN->getIdentifier(), 
+                                              *DTN->getIdentifier(),
                                               NameLoc,
                                               ObjectType,
                                               FirstQualifierInScope);
     }
-    
+
     return getDerived().RebuildTemplateName(SS, DTN->getOperator(), NameLoc,
                                             ObjectType);
   }
-  
+
   if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
     TemplateDecl *TransTemplate
-      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, 
+      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
                                                               Template));
     if (!TransTemplate)
       return TemplateName();
-    
+
     if (!getDerived().AlwaysRebuild() &&
         TransTemplate == Template)
       return Name;
-    
+
     return TemplateName(TransTemplate);
   }
-  
+
   if (SubstTemplateTemplateParmPackStorage *SubstPack
       = Name.getAsSubstTemplateTemplateParmPack()) {
     TemplateTemplateParmDecl *TransParam
@@ -2903,15 +2905,15 @@
             getDerived().TransformDecl(NameLoc, SubstPack->getParameterPack()));
     if (!TransParam)
       return TemplateName();
-    
+
     if (!getDerived().AlwaysRebuild() &&
         TransParam == SubstPack->getParameterPack())
       return Name;
-    
-    return getDerived().RebuildTemplateName(TransParam, 
+
+    return getDerived().RebuildTemplateName(TransParam,
                                             SubstPack->getArgumentPack());
   }
-  
+
   // These should be getting filtered out before they reach the AST.
   llvm_unreachable("overloaded function decl survived to here");
 }
@@ -2929,7 +2931,7 @@
   case TemplateArgument::Type:
     Output = TemplateArgumentLoc(Arg,
                SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
-                                            
+
     break;
 
   case TemplateArgument::Template:
@@ -2940,16 +2942,16 @@
       Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc);
     else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
       Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc);
-        
+
     if (Arg.getKind() == TemplateArgument::Template)
-      Output = TemplateArgumentLoc(Arg, 
+      Output = TemplateArgumentLoc(Arg,
                                    Builder.getWithLocInContext(SemaRef.Context),
                                    Loc);
     else
-      Output = TemplateArgumentLoc(Arg, 
+      Output = TemplateArgumentLoc(Arg,
                                    Builder.getWithLocInContext(SemaRef.Context),
                                    Loc, Loc);
-    
+
     break;
   }
 
@@ -3017,7 +3019,7 @@
       if (!QualifierLoc)
         return true;
     }
-    
+
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
     TemplateName Template
@@ -3025,7 +3027,7 @@
                                            Input.getTemplateNameLoc());
     if (Template.isNull())
       return true;
-    
+
     Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc,
                                  Input.getTemplateNameLoc());
     return false;
@@ -3072,8 +3074,8 @@
       = new (getSema().Context) TemplateArgument[TransformedArgs.size()];
     std::copy(TransformedArgs.begin(), TransformedArgs.end(),
               TransformedArgsPtr);
-    Output = TemplateArgumentLoc(TemplateArgument(TransformedArgsPtr, 
-                                                  TransformedArgs.size()), 
+    Output = TemplateArgumentLoc(TemplateArgument(TransformedArgsPtr,
+                                                  TransformedArgs.size()),
                                  Input.getLocInfo());
     return false;
   }
@@ -3089,48 +3091,48 @@
 class TemplateArgumentLocInventIterator {
   TreeTransform<Derived> &Self;
   InputIterator Iter;
-  
+
 public:
   typedef TemplateArgumentLoc value_type;
   typedef TemplateArgumentLoc reference;
   typedef typename std::iterator_traits<InputIterator>::difference_type
     difference_type;
   typedef std::input_iterator_tag iterator_category;
-  
+
   class pointer {
     TemplateArgumentLoc Arg;
-    
+
   public:
     explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
-    
+
     const TemplateArgumentLoc *operator->() const { return &Arg; }
   };
-  
+
   TemplateArgumentLocInventIterator() { }
-  
+
   explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
                                              InputIterator Iter)
     : Self(Self), Iter(Iter) { }
-  
+
   TemplateArgumentLocInventIterator &operator++() {
     ++Iter;
     return *this;
   }
-  
+
   TemplateArgumentLocInventIterator operator++(int) {
     TemplateArgumentLocInventIterator Old(*this);
     ++(*this);
     return Old;
   }
-  
+
   reference operator*() const {
     TemplateArgumentLoc Result;
     Self.InventTemplateArgumentLoc(*Iter, Result);
     return Result;
   }
-  
+
   pointer operator->() const { return pointer(**this); }
-  
+
   friend bool operator==(const TemplateArgumentLocInventIterator &X,
                          const TemplateArgumentLocInventIterator &Y) {
     return X.Iter == Y.Iter;
@@ -3141,7 +3143,7 @@
     return X.Iter != Y.Iter;
   }
 };
-  
+
 template<typename Derived>
 template<typename InputIterator>
 bool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
@@ -3150,39 +3152,39 @@
   for (; First != Last; ++First) {
     TemplateArgumentLoc Out;
     TemplateArgumentLoc In = *First;
-    
+
     if (In.getArgument().getKind() == TemplateArgument::Pack) {
       // Unpack argument packs, which we translate them into separate
       // arguments.
       // FIXME: We could do much better if we could guarantee that the
       // TemplateArgumentLocInfo for the pack expansion would be usable for
       // all of the template arguments in the argument pack.
-      typedef TemplateArgumentLocInventIterator<Derived, 
+      typedef TemplateArgumentLocInventIterator<Derived,
                                                 TemplateArgument::pack_iterator>
         PackLocIterator;
-      if (TransformTemplateArguments(PackLocIterator(*this, 
+      if (TransformTemplateArguments(PackLocIterator(*this,
                                                  In.getArgument().pack_begin()),
                                      PackLocIterator(*this,
                                                    In.getArgument().pack_end()),
                                      Outputs))
         return true;
-      
+
       continue;
     }
-    
+
     if (In.getArgument().isPackExpansion()) {
       // We have a pack expansion, for which we will be substituting into
       // the pattern.
       SourceLocation Ellipsis;
       llvm::Optional<unsigned> OrigNumExpansions;
       TemplateArgumentLoc Pattern
-        = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions, 
+        = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions,
                                      getSema().Context);
-      
+
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
       getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
       assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
-      
+
       // Determine whether the set of unexpanded parameter packs can and should
       // be expanded.
       bool Expand = true;
@@ -3191,29 +3193,29 @@
       if (getDerived().TryExpandParameterPacks(Ellipsis,
                                                Pattern.getSourceRange(),
                                                Unexpanded,
-                                               Expand, 
+                                               Expand,
                                                RetainExpansion,
                                                NumExpansions))
         return true;
-      
+
       if (!Expand) {
         // The transform has determined that we should perform a simple
-        // transformation on the pack expansion, producing another pack 
+        // transformation on the pack expansion, producing another pack
         // expansion.
         TemplateArgumentLoc OutPattern;
         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
         if (getDerived().TransformTemplateArgument(Pattern, OutPattern))
           return true;
-                
+
         Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
                                                 NumExpansions);
         if (Out.getArgument().isNull())
           return true;
-        
+
         Outputs.addArgument(Out);
         continue;
       }
-      
+
       // The transform has determined that we should perform an elementwise
       // expansion of the pattern. Do so.
       for (unsigned I = 0; I != *NumExpansions; ++I) {
@@ -3221,43 +3223,43 @@
 
         if (getDerived().TransformTemplateArgument(Pattern, Out))
           return true;
-        
+
         if (Out.getArgument().containsUnexpandedParameterPack()) {
           Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
                                                   OrigNumExpansions);
           if (Out.getArgument().isNull())
             return true;
         }
-          
+
         Outputs.addArgument(Out);
       }
-      
+
       // If we're supposed to retain a pack expansion, do so by temporarily
       // forgetting the partially-substituted parameter pack.
       if (RetainExpansion) {
         ForgetPartiallySubstitutedPackRAII Forget(getDerived());
-        
+
         if (getDerived().TransformTemplateArgument(Pattern, Out))
           return true;
-        
+
         Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
                                                 OrigNumExpansions);
         if (Out.getArgument().isNull())
           return true;
-        
+
         Outputs.addArgument(Out);
       }
-      
+
       continue;
     }
-    
-    // The simple case: 
+
+    // The simple case:
     if (getDerived().TransformTemplateArgument(In, Out))
       return true;
-    
+
     Outputs.addArgument(Out);
   }
-  
+
   return false;
 
 }
@@ -3275,7 +3277,7 @@
   // eventually turn into transformations on TypeLocs.
   TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
                                                 getDerived().getBaseLocation());
-  
+
   TypeSourceInfo *NewDI = getDerived().TransformType(DI);
 
   if (!NewDI)
@@ -3345,19 +3347,19 @@
     if (!Result->isObjCLifetimeType() && !Result->isDependentType())
       Quals.removeObjCLifetime();
     else if (Result.getObjCLifetime()) {
-      // Objective-C ARC: 
+      // Objective-C ARC:
       //   A lifetime qualifier applied to a substituted template parameter
       //   overrides the lifetime qualifier from the template argument.
-      if (const SubstTemplateTypeParmType *SubstTypeParam 
+      if (const SubstTemplateTypeParmType *SubstTypeParam
                                 = dyn_cast<SubstTemplateTypeParmType>(Result)) {
         QualType Replacement = SubstTypeParam->getReplacementType();
         Qualifiers Qs = Replacement.getQualifiers();
         Qs.removeObjCLifetime();
-        Replacement 
+        Replacement
           = SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(),
                                              Qs);
         Result = SemaRef.Context.getSubstTemplateTypeParmType(
-                                        SubstTypeParam->getReplacedParameter(), 
+                                        SubstTypeParam->getReplacedParameter(),
                                                               Replacement);
         TLB.TypeWasModifiedSafely(Result);
       } else {
@@ -3366,7 +3368,7 @@
         SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange();
         SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant)
           << Result << R;
-        
+
         Quals.removeObjCLifetime();
       }
     }
@@ -3389,37 +3391,37 @@
   QualType T = TL.getType();
   if (getDerived().AlreadyTransformed(T))
     return TL;
-  
+
   TypeLocBuilder TLB;
   QualType Result;
-  
+
   if (isa<TemplateSpecializationType>(T)) {
     TemplateSpecializationTypeLoc SpecTL
       = cast<TemplateSpecializationTypeLoc>(TL);
-    
+
     TemplateName Template =
       getDerived().TransformTemplateName(SS,
                                          SpecTL.getTypePtr()->getTemplateName(),
                                          SpecTL.getTemplateNameLoc(),
                                          ObjectType, UnqualLookup);
-    if (Template.isNull()) 
+    if (Template.isNull())
       return TypeLoc();
-    
-    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, 
+
+    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
                                                               Template);
   } else if (isa<DependentTemplateSpecializationType>(T)) {
     DependentTemplateSpecializationTypeLoc SpecTL
       = cast<DependentTemplateSpecializationTypeLoc>(TL);
-    
+
     TemplateName Template
-      = getDerived().RebuildTemplateName(SS, 
-                                         *SpecTL.getTypePtr()->getIdentifier(), 
+      = getDerived().RebuildTemplateName(SS,
+                                         *SpecTL.getTypePtr()->getIdentifier(),
                                          SpecTL.getTemplateNameLoc(),
                                          ObjectType, UnqualLookup);
     if (Template.isNull())
       return TypeLoc();
-    
-    Result = getDerived().TransformDependentTemplateSpecializationType(TLB, 
+
+    Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
                                                                        SpecTL,
                                                                      Template,
                                                                        SS);
@@ -3427,10 +3429,10 @@
     // Nothing special needs to be done for these.
     Result = getDerived().TransformType(TLB, TL);
   }
-  
-  if (Result.isNull()) 
+
+  if (Result.isNull())
     return TypeLoc();
-  
+
   return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc();
 }
 
@@ -3441,42 +3443,42 @@
                                                    NamedDecl *UnqualLookup,
                                                    CXXScopeSpec &SS) {
   // FIXME: Painfully copy-paste from the above!
-  
+
   QualType T = TSInfo->getType();
   if (getDerived().AlreadyTransformed(T))
     return TSInfo;
-  
+
   TypeLocBuilder TLB;
   QualType Result;
-  
+
   TypeLoc TL = TSInfo->getTypeLoc();
   if (isa<TemplateSpecializationType>(T)) {
     TemplateSpecializationTypeLoc SpecTL
       = cast<TemplateSpecializationTypeLoc>(TL);
-    
+
     TemplateName Template
     = getDerived().TransformTemplateName(SS,
                                          SpecTL.getTypePtr()->getTemplateName(),
                                          SpecTL.getTemplateNameLoc(),
                                          ObjectType, UnqualLookup);
-    if (Template.isNull()) 
+    if (Template.isNull())
       return 0;
-    
-    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, 
+
+    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
                                                               Template);
   } else if (isa<DependentTemplateSpecializationType>(T)) {
     DependentTemplateSpecializationTypeLoc SpecTL
       = cast<DependentTemplateSpecializationTypeLoc>(TL);
-    
+
     TemplateName Template
-      = getDerived().RebuildTemplateName(SS, 
-                                         *SpecTL.getTypePtr()->getIdentifier(), 
+      = getDerived().RebuildTemplateName(SS,
+                                         *SpecTL.getTypePtr()->getIdentifier(),
                                          SpecTL.getTemplateNameLoc(),
                                          ObjectType, UnqualLookup);
     if (Template.isNull())
       return 0;
-    
-    Result = getDerived().TransformDependentTemplateSpecializationType(TLB, 
+
+    Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
                                                                        SpecTL,
                                                                        Template,
                                                                        SS);
@@ -3484,10 +3486,10 @@
     // Nothing special needs to be done for these.
     Result = getDerived().TransformType(TLB, TL);
   }
-  
-  if (Result.isNull()) 
+
+  if (Result.isNull())
     return 0;
-  
+
   return TLB.getTypeSourceInfo(SemaRef.Context, Result);
 }
 
@@ -3518,8 +3520,8 @@
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
                                                       PointerTypeLoc TL) {
-  QualType PointeeType                                      
-    = getDerived().TransformType(TLB, TL.getPointeeLoc());  
+  QualType PointeeType
+    = getDerived().TransformType(TLB, TL.getPointeeLoc());
   if (PointeeType.isNull())
     return QualType();
 
@@ -3530,7 +3532,7 @@
     // resulting pointer type is an ObjCObjectPointerType, not a
     // PointerType.
     Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
-    
+
     ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
     NewT.setStarLoc(TL.getStarLoc());
     return Result;
@@ -3542,14 +3544,14 @@
     if (Result.isNull())
       return QualType();
   }
-               
+
   // Objective-C ARC can add lifetime qualifiers to the type that we're
   // pointing to.
   TLB.TypeWasModifiedSafely(Result->getPointeeType());
-  
+
   PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
   NewT.setSigilLoc(TL.getSigilLoc());
-  return Result;  
+  return Result;
 }
 
 template<typename Derived>
@@ -3557,14 +3559,14 @@
 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
                                                   BlockPointerTypeLoc TL) {
   QualType PointeeType
-    = getDerived().TransformType(TLB, TL.getPointeeLoc());  
-  if (PointeeType.isNull())                                 
-    return QualType();                                      
-  
-  QualType Result = TL.getType();                           
-  if (getDerived().AlwaysRebuild() ||                       
-      PointeeType != TL.getPointeeLoc().getType()) {        
-    Result = getDerived().RebuildBlockPointerType(PointeeType, 
+    = getDerived().TransformType(TLB, TL.getPointeeLoc());
+  if (PointeeType.isNull())
+    return QualType();
+
+  QualType Result = TL.getType();
+  if (getDerived().AlwaysRebuild() ||
+      PointeeType != TL.getPointeeLoc().getType()) {
+    Result = getDerived().RebuildBlockPointerType(PointeeType,
                                                   TL.getSigilLoc());
     if (Result.isNull())
       return QualType();
@@ -3734,7 +3736,7 @@
     if (Result.isNull())
       return QualType();
   }
-  
+
   IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
   NewTL.setRBracketLoc(TL.getRBracketLoc());
@@ -3771,7 +3773,7 @@
     if (Result.isNull())
       return QualType();
   }
-  
+
   VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
   NewTL.setRBracketLoc(TL.getRBracketLoc());
@@ -3888,7 +3890,7 @@
     if (Result.isNull())
       return QualType();
   }
-  
+
   VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
 
@@ -3912,7 +3914,7 @@
     if (Result.isNull())
       return QualType();
   }
-  
+
   ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
   NewTL.setNameLoc(TL.getNameLoc());
 
@@ -3927,29 +3929,29 @@
                                                    bool ExpectParameterPack) {
   TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
   TypeSourceInfo *NewDI = 0;
-  
+
   if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
-    // If we're substituting into a pack expansion type and we know the 
+    // If we're substituting into a pack expansion type and we know the
     // length we want to expand to, just substitute for the pattern.
     TypeLoc OldTL = OldDI->getTypeLoc();
     PackExpansionTypeLoc OldExpansionTL = cast<PackExpansionTypeLoc>(OldTL);
-    
+
     TypeLocBuilder TLB;
     TypeLoc NewTL = OldDI->getTypeLoc();
     TLB.reserve(NewTL.getFullDataSize());
-    
-    QualType Result = getDerived().TransformType(TLB, 
+
+    QualType Result = getDerived().TransformType(TLB,
                                                OldExpansionTL.getPatternLoc());
     if (Result.isNull())
       return 0;
-   
-    Result = RebuildPackExpansionType(Result, 
-                                OldExpansionTL.getPatternLoc().getSourceRange(), 
+
+    Result = RebuildPackExpansionType(Result,
+                                OldExpansionTL.getPatternLoc().getSourceRange(),
                                       OldExpansionTL.getEllipsisLoc(),
                                       NumExpansions);
     if (Result.isNull())
       return 0;
-    
+
     PackExpansionTypeLoc NewExpansionTL
       = TLB.push<PackExpansionTypeLoc>(Result);
     NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
@@ -4011,27 +4013,27 @@
         NumExpansions = OrigNumExpansions;
         if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
                                                  Pattern.getSourceRange(),
-                                                 Unexpanded, 
-                                                 ShouldExpand, 
+                                                 Unexpanded,
+                                                 ShouldExpand,
                                                  RetainExpansion,
                                                  NumExpansions)) {
           return true;
         }
-        
+
         if (ShouldExpand) {
           // Expand the function parameter pack into multiple, separate
           // parameters.
           getDerived().ExpandingFunctionParameterPack(OldParm);
           for (unsigned I = 0; I != *NumExpansions; ++I) {
             Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
-            ParmVarDecl *NewParm 
+            ParmVarDecl *NewParm
               = getDerived().TransformFunctionTypeParam(OldParm,
                                                         indexAdjustment++,
                                                         OrigNumExpansions,
                                                 /*ExpectParameterPack=*/false);
             if (!NewParm)
               return true;
-            
+
             OutParamTypes.push_back(NewParm->getType());
             if (PVars)
               PVars->push_back(NewParm);
@@ -4041,14 +4043,14 @@
           // forgetting the partially-substituted parameter pack.
           if (RetainExpansion) {
             ForgetPartiallySubstitutedPackRAII Forget(getDerived());
-            ParmVarDecl *NewParm 
+            ParmVarDecl *NewParm
               = getDerived().TransformFunctionTypeParam(OldParm,
                                                         indexAdjustment++,
                                                         OrigNumExpansions,
                                                 /*ExpectParameterPack=*/false);
             if (!NewParm)
               return true;
-            
+
             OutParamTypes.push_back(NewParm->getType());
             if (PVars)
               PVars->push_back(NewParm);
@@ -4063,8 +4065,8 @@
           // We're done with the pack expansion.
           continue;
         }
-        
-        // We'll substitute the parameter now without expanding the pack 
+
+        // We'll substitute the parameter now without expanding the pack
         // expansion.
         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
         NewParm = getDerived().TransformFunctionTypeParam(OldParm,
@@ -4080,7 +4082,7 @@
 
       if (!NewParm)
         return true;
-      
+
       OutParamTypes.push_back(NewParm->getType());
       if (PVars)
         PVars->push_back(NewParm);
@@ -4093,26 +4095,26 @@
     bool IsPackExpansion = false;
     llvm::Optional<unsigned> NumExpansions;
     QualType NewType;
-    if (const PackExpansionType *Expansion 
+    if (const PackExpansionType *Expansion
                                        = dyn_cast<PackExpansionType>(OldType)) {
       // We have a function parameter pack that may need to be expanded.
       QualType Pattern = Expansion->getPattern();
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
       getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
-      
+
       // Determine whether we should expand the parameter packs.
       bool ShouldExpand = false;
       bool RetainExpansion = false;
       if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
-                                               Unexpanded, 
-                                               ShouldExpand, 
+                                               Unexpanded,
+                                               ShouldExpand,
                                                RetainExpansion,
                                                NumExpansions)) {
         return true;
       }
-      
+
       if (ShouldExpand) {
-        // Expand the function parameter pack into multiple, separate 
+        // Expand the function parameter pack into multiple, separate
         // parameters.
         for (unsigned I = 0; I != *NumExpansions; ++I) {
           Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
@@ -4124,11 +4126,11 @@
           if (PVars)
             PVars->push_back(0);
         }
-        
+
         // We're done with the pack expansion.
         continue;
       }
-      
+
       // If we're supposed to retain a pack expansion, do so by temporarily
       // forgetting the partially-substituted parameter pack.
       if (RetainExpansion) {
@@ -4136,13 +4138,13 @@
         QualType NewType = getDerived().TransformType(Pattern);
         if (NewType.isNull())
           return true;
-        
+
         OutParamTypes.push_back(NewType);
         if (PVars)
           PVars->push_back(0);
       }
 
-      // We'll substitute the parameter now without expanding the pack 
+      // We'll substitute the parameter now without expanding the pack
       // expansion.
       OldType = Expansion->getPattern();
       IsPackExpansion = true;
@@ -4151,14 +4153,14 @@
     } else {
       NewType = getDerived().TransformType(OldType);
     }
-    
+
     if (NewType.isNull())
       return true;
 
     if (IsPackExpansion)
       NewType = getSema().Context.getPackExpansionType(NewType,
                                                        NumExpansions);
-      
+
     OutParamTypes.push_back(NewType);
     if (PVars)
       PVars->push_back(0);
@@ -4201,23 +4203,23 @@
 
   QualType ResultType;
 
-  if (TL.getTrailingReturn()) {
-    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(), 
+  if (T->hasTrailingReturn()) {
+    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(),
                                                  TL.getParmArray(),
                                                  TL.getNumArgs(),
-                                             TL.getTypePtr()->arg_type_begin(),                                                
+                                             TL.getTypePtr()->arg_type_begin(),
                                                  ParamTypes, &ParamDecls))
       return QualType();
 
     {
       // C++11 [expr.prim.general]p3:
-      //   If a declaration declares a member function or member function 
-      //   template of a class X, the expression this is a prvalue of type 
+      //   If a declaration declares a member function or member function
+      //   template of a class X, the expression this is a prvalue of type
       //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
-      //   and the end of the function-definition, member-declarator, or 
+      //   and the end of the function-definition, member-declarator, or
       //   declarator.
       Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
-      
+
       ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
       if (ResultType.isNull())
         return QualType();
@@ -4228,10 +4230,10 @@
     if (ResultType.isNull())
       return QualType();
 
-    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(), 
+    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(),
                                                  TL.getParmArray(),
                                                  TL.getNumArgs(),
-                                             TL.getTypePtr()->arg_type_begin(),                                                
+                                             TL.getTypePtr()->arg_type_begin(),
                                                  ParamTypes, &ParamDecls))
       return QualType();
   }
@@ -4258,7 +4260,6 @@
   FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
   NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
   NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
-  NewTL.setTrailingReturn(TL.getTrailingReturn());
   for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
     NewTL.setArg(i, ParamDecls[i]);
 
@@ -4282,7 +4283,6 @@
   FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
   NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
   NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
-  NewTL.setTrailingReturn(false);
 
   return Result;
 }
@@ -4542,7 +4542,7 @@
                                          TypeLocBuilder &TLB,
                                          SubstTemplateTypeParmTypeLoc TL) {
   const SubstTemplateTypeParmType *T = TL.getTypePtr();
-  
+
   // Substitute into the replacement type, which itself might involve something
   // that needs to be transformed. This only tends to occur with default
   // template arguments of template template parameters.
@@ -4550,13 +4550,13 @@
   QualType Replacement = getDerived().TransformType(T->getReplacementType());
   if (Replacement.isNull())
     return QualType();
-  
+
   // Always canonicalize the replacement type.
   Replacement = SemaRef.Context.getCanonicalType(Replacement);
   QualType Result
-    = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(), 
+    = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(),
                                                    Replacement);
-  
+
   // Propagate type-source information.
   SubstTemplateTypeParmTypeLoc NewTL
     = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
@@ -4614,7 +4614,7 @@
 }
 
 namespace {
-  /// \brief Simple iterator that traverses the template arguments in a 
+  /// \brief Simple iterator that traverses the template arguments in a
   /// container that provides a \c getArgLoc() member function.
   ///
   /// This iterator is intended to be used with the iterator form of
@@ -4623,63 +4623,63 @@
   class TemplateArgumentLocContainerIterator {
     ArgLocContainer *Container;
     unsigned Index;
-    
+
   public:
     typedef TemplateArgumentLoc value_type;
     typedef TemplateArgumentLoc reference;
     typedef int difference_type;
     typedef std::input_iterator_tag iterator_category;
-    
+
     class pointer {
       TemplateArgumentLoc Arg;
-      
+
     public:
       explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
-      
+
       const TemplateArgumentLoc *operator->() const {
         return &Arg;
       }
     };
-    
-    
+
+
     TemplateArgumentLocContainerIterator() {}
-    
+
     TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
                                  unsigned Index)
       : Container(&Container), Index(Index) { }
-    
+
     TemplateArgumentLocContainerIterator &operator++() {
       ++Index;
       return *this;
     }
-    
+
     TemplateArgumentLocContainerIterator operator++(int) {
       TemplateArgumentLocContainerIterator Old(*this);
       ++(*this);
       return Old;
     }
-    
+
     TemplateArgumentLoc operator*() const {
       return Container->getArgLoc(Index);
     }
-    
+
     pointer operator->() const {
       return pointer(Container->getArgLoc(Index));
     }
-    
+
     friend bool operator==(const TemplateArgumentLocContainerIterator &X,
                            const TemplateArgumentLocContainerIterator &Y) {
       return X.Container == Y.Container && X.Index == Y.Index;
     }
-    
+
     friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
                            const TemplateArgumentLocContainerIterator &Y) {
       return !(X == Y);
     }
   };
 }
-  
-  
+
+
 template <typename Derived>
 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
                                                         TypeLocBuilder &TLB,
@@ -4690,7 +4690,7 @@
   NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
   typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
     ArgIterator;
-  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), 
+  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
                                               ArgIterator(TL, TL.getNumArgs()),
                                               NewTemplateArgs))
     return QualType();
@@ -4745,13 +4745,13 @@
   NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
   typedef TemplateArgumentLocContainerIterator<
             DependentTemplateSpecializationTypeLoc> ArgIterator;
-  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), 
+  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
                                               ArgIterator(TL, TL.getNumArgs()),
                                               NewTemplateArgs))
     return QualType();
-  
+
   // FIXME: maybe don't rebuild if all the template arguments are the same.
-  
+
   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
     QualType Result
       = getSema().Context.getDependentTemplateSpecializationType(
@@ -4759,7 +4759,7 @@
                                                          DTN->getQualifier(),
                                                          DTN->getIdentifier(),
                                                                NewTemplateArgs);
-   
+
     DependentTemplateSpecializationTypeLoc NewTL
       = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
     NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
@@ -4772,12 +4772,12 @@
       NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
     return Result;
   }
-      
-  QualType Result 
+
+  QualType Result
     = getDerived().RebuildTemplateSpecializationType(Template,
                                                      TL.getTemplateNameLoc(),
                                                      NewTemplateArgs);
-  
+
   if (!Result.isNull()) {
     /// FIXME: Wrap this in an elaborated-type-specifier?
     TemplateSpecializationTypeLoc NewTL
@@ -4789,7 +4789,7 @@
     for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
       NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
   }
-  
+
   return Result;
 }
 
@@ -4802,7 +4802,7 @@
   NestedNameSpecifierLoc QualifierLoc;
   // NOTE: the qualifier in an ElaboratedType is optional.
   if (TL.getQualifierLoc()) {
-    QualifierLoc 
+    QualifierLoc
       = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
     if (!QualifierLoc)
       return QualType();
@@ -4834,7 +4834,7 @@
       QualifierLoc != TL.getQualifierLoc() ||
       NamedT != T->getNamedType()) {
     Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
-                                                T->getKeyword(), 
+                                                T->getKeyword(),
                                                 QualifierLoc, NamedT);
     if (Result.isNull())
       return QualType();
@@ -4951,7 +4951,7 @@
     if (!QualifierLoc)
       return QualType();
   }
-            
+
   return getDerived()
            .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
 }
@@ -4962,18 +4962,18 @@
                                    DependentTemplateSpecializationTypeLoc TL,
                                        NestedNameSpecifierLoc QualifierLoc) {
   const DependentTemplateSpecializationType *T = TL.getTypePtr();
-  
+
   TemplateArgumentListInfo NewTemplateArgs;
   NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
   NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
-  
+
   typedef TemplateArgumentLocContainerIterator<
   DependentTemplateSpecializationTypeLoc> ArgIterator;
   if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
                                               ArgIterator(TL, TL.getNumArgs()),
                                               NewTemplateArgs))
     return QualType();
-  
+
   QualType Result
     = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
                                                               QualifierLoc,
@@ -4982,10 +4982,10 @@
                                                             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);
@@ -4995,7 +4995,7 @@
     NamedTL.setRAngleLoc(TL.getRAngleLoc());
     for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
       NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
-    
+
     // Copy information relevant to the elaborated type.
     ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
     NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
@@ -5027,22 +5027,22 @@
 template<typename Derived>
 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
                                                       PackExpansionTypeLoc TL) {
-  QualType Pattern                                      
-    = getDerived().TransformType(TLB, TL.getPatternLoc());  
+  QualType Pattern
+    = getDerived().TransformType(TLB, TL.getPatternLoc());
   if (Pattern.isNull())
     return QualType();
-  
-  QualType Result = TL.getType();  
+
+  QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       Pattern != TL.getPatternLoc().getType()) {
-    Result = getDerived().RebuildPackExpansionType(Pattern, 
+    Result = getDerived().RebuildPackExpansionType(Pattern,
                                            TL.getPatternLoc().getSourceRange(),
                                                    TL.getEllipsisLoc(),
                                            TL.getTypePtr()->getNumExpansions());
     if (Result.isNull())
       return QualType();
   }
-  
+
   PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
   NewT.setEllipsisLoc(TL.getEllipsisLoc());
   return Result;
@@ -5226,7 +5226,7 @@
   ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
-    ConditionVar 
+    ConditionVar
       = cast_or_null<VarDecl>(
                    getDerived().TransformDefinition(
                                       S->getConditionVariable()->getLocation(),
@@ -5235,25 +5235,25 @@
       return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
-  
+
     if (Cond.isInvalid())
       return StmtError();
-    
+
     // Convert the condition to a boolean value.
     if (S->getCond()) {
-      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getIfLoc(), 
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getIfLoc(),
                                                          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 "then" branch.
   StmtResult Then = getDerived().TransformStmt(S->getThen());
   if (Then.isInvalid())
@@ -5283,7 +5283,7 @@
   ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
-    ConditionVar 
+    ConditionVar
       = cast_or_null<VarDecl>(
                    getDerived().TransformDefinition(
                                       S->getConditionVariable()->getLocation(),
@@ -5292,7 +5292,7 @@
       return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
-    
+
     if (Cond.isInvalid())
       return StmtError();
   }
@@ -5321,7 +5321,7 @@
   ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
-    ConditionVar 
+    ConditionVar
       = cast_or_null<VarDecl>(
                    getDerived().TransformDefinition(
                                       S->getConditionVariable()->getLocation(),
@@ -5330,13 +5330,13 @@
       return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
-    
+
     if (Cond.isInvalid())
       return StmtError();
 
     if (S->getCond()) {
       // Convert the condition to a boolean value.
-      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getWhileLoc(), 
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getWhileLoc(),
                                                          Cond.get());
       if (CondE.isInvalid())
         return StmtError();
@@ -5375,7 +5375,7 @@
   ExprResult Cond = getDerived().TransformExpr(S->getCond());
   if (Cond.isInvalid())
     return StmtError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == S->getCond() &&
       Body.get() == S->getBody())
@@ -5398,7 +5398,7 @@
   ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
-    ConditionVar 
+    ConditionVar
       = cast_or_null<VarDecl>(
                    getDerived().TransformDefinition(
                                       S->getConditionVariable()->getLocation(),
@@ -5407,13 +5407,13 @@
       return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
-    
+
     if (Cond.isInvalid())
       return StmtError();
 
     if (S->getCond()) {
       // Convert the condition to a boolean value.
-      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getForLoc(), 
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getForLoc(),
                                                          Cond.get());
       if (CondE.isInvalid())
         return StmtError();
@@ -5422,7 +5422,7 @@
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));  
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
   if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
     return StmtError();
 
@@ -5459,7 +5459,7 @@
                                         S->getLabel());
   if (!LD)
     return StmtError();
-  
+
   // Goto statements must always be rebuilt, to resolve the label.
   return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
                                       cast<LabelDecl>(LD));
@@ -5533,7 +5533,7 @@
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
-  
+
   ASTOwningVector<Expr*> Constraints(getSema());
   ASTOwningVector<Expr*> Exprs(getSema());
   SmallVector<IdentifierInfo *, 4> Names;
@@ -5542,43 +5542,43 @@
   ASTOwningVector<Expr*> Clobbers(getSema());
 
   bool ExprsChanged = false;
-  
+
   // Go through the outputs.
   for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
     Names.push_back(S->getOutputIdentifier(I));
-    
+
     // No need to transform the constraint literal.
     Constraints.push_back(S->getOutputConstraintLiteral(I));
-    
+
     // Transform the output expr.
     Expr *OutputExpr = S->getOutputExpr(I);
     ExprResult Result = getDerived().TransformExpr(OutputExpr);
     if (Result.isInvalid())
       return StmtError();
-    
+
     ExprsChanged |= Result.get() != OutputExpr;
-    
+
     Exprs.push_back(Result.get());
   }
-  
+
   // Go through the inputs.
   for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
     Names.push_back(S->getInputIdentifier(I));
-    
+
     // No need to transform the constraint literal.
     Constraints.push_back(S->getInputConstraintLiteral(I));
-    
+
     // Transform the input expr.
     Expr *InputExpr = S->getInputExpr(I);
     ExprResult Result = getDerived().TransformExpr(InputExpr);
     if (Result.isInvalid())
       return StmtError();
-    
+
     ExprsChanged |= Result.get() != InputExpr;
-    
+
     Exprs.push_back(Result.get());
   }
-  
+
   if (!getDerived().AlwaysRebuild() && !ExprsChanged)
     return SemaRef.Owned(S);
 
@@ -5599,17 +5599,17 @@
                                      move_arg(Exprs),
                                      AsmString.get(),
                                      move_arg(Clobbers),
-                                     S->getRParenLoc(),
-                                     S->isMSAsm());
+                                     S->getRParenLoc());
 }
 
 template<typename Derived>
 StmtResult
 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
-  // No need to transform the asm string literal.
-  return getDerived().RebuildMSAsmStmt(S->getAsmLoc(),
-                                       *S->getAsmString(),
-                                       S->getEndLoc());
+  ArrayRef<Token> AsmToks =
+    llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks());
+
+  return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
+                                       AsmToks, S->getEndLoc());
 }
 
 template<typename Derived>
@@ -5619,7 +5619,7 @@
   StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
   if (TryBody.isInvalid())
     return StmtError();
-  
+
   // Transform the @catch statements (if present).
   bool AnyCatchChanged = false;
   ASTOwningVector<Stmt*> CatchStmts(SemaRef);
@@ -5631,7 +5631,7 @@
       AnyCatchChanged = true;
     CatchStmts.push_back(Catch.release());
   }
-  
+
   // Transform the @finally statement (if present).
   StmtResult Finally;
   if (S->getFinallyStmt()) {
@@ -5646,7 +5646,7 @@
       !AnyCatchChanged &&
       Finally.get() == S->getFinallyStmt())
     return SemaRef.Owned(S);
-  
+
   // Build a new statement.
   return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
                                            move_arg(CatchStmts), Finally.get());
@@ -5664,26 +5664,26 @@
       if (!TSInfo)
         return StmtError();
     }
-    
+
     QualType T;
     if (TSInfo)
       T = TSInfo->getType();
     else {
       T = getDerived().TransformType(FromVar->getType());
       if (T.isNull())
-        return StmtError();        
+        return StmtError();
     }
-    
+
     Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
     if (!Var)
       return StmtError();
   }
-  
+
   StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
   if (Body.isInvalid())
     return StmtError();
-  
-  return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), 
+
+  return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
                                              S->getRParenLoc(),
                                              Var, Body.get());
 }
@@ -5695,7 +5695,7 @@
   StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
   if (Body.isInvalid())
     return StmtError();
-  
+
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Body.get() == S->getFinallyBody())
@@ -5715,11 +5715,11 @@
     if (Operand.isInvalid())
       return StmtError();
   }
-  
+
   if (!getDerived().AlwaysRebuild() &&
       Operand.get() == S->getThrowExpr())
     return getSema().Owned(S);
-    
+
   return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
 }
 
@@ -5736,12 +5736,12 @@
                                                   Object.get());
   if (Object.isInvalid())
     return StmtError();
-  
+
   // Transform the body.
   StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
   if (Body.isInvalid())
     return StmtError();
-  
+
   // If nothing change, just retain the current statement.
   if (!getDerived().AlwaysRebuild() &&
       Object.get() == S->getSynchExpr() &&
@@ -5761,7 +5761,7 @@
   StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
   if (Body.isInvalid())
     return StmtError();
-  
+
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Body.get() == S->getSubStmt())
@@ -5780,27 +5780,26 @@
   StmtResult Element = getDerived().TransformStmt(S->getElement());
   if (Element.isInvalid())
     return StmtError();
-  
+
   // Transform the collection expression.
   ExprResult Collection = getDerived().TransformExpr(S->getCollection());
   if (Collection.isInvalid())
     return StmtError();
-  
+
   // Transform the body.
   StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
     return StmtError();
-  
+
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
       Element.get() == S->getElement() &&
       Collection.get() == S->getCollection() &&
       Body.get() == S->getBody())
     return SemaRef.Owned(S);
-  
+
   // Build a new statement.
   return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
-                                                   /*FIXME:*/S->getForLoc(),
                                                    Element.get(),
                                                    Collection.get(),
                                                    S->getRParenLoc(),
@@ -5944,7 +5943,7 @@
   // Transform the nested-name-specifier, if any.
   NestedNameSpecifierLoc QualifierLoc;
   if (S->getQualifierLoc()) {
-    QualifierLoc 
+    QualifierLoc
       = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
     if (!QualifierLoc)
       return StmtError();
@@ -5963,7 +5962,7 @@
       QualifierLoc == S->getQualifierLoc() &&
       NameInfo.getName() == S->getNameInfo().getName())
     return S;
-  
+
   // Determine whether this name exists, if we can.
   CXXScopeSpec SS;
   SS.Adopt(QualifierLoc);
@@ -5972,32 +5971,32 @@
   case Sema::IER_Exists:
     if (S->isIfExists())
       break;
-      
+
     return new (getSema().Context) NullStmt(S->getKeywordLoc());
 
   case Sema::IER_DoesNotExist:
     if (S->isIfNotExists())
       break;
-    
+
     return new (getSema().Context) NullStmt(S->getKeywordLoc());
-      
+
   case Sema::IER_Dependent:
     Dependent = true;
     break;
-      
+
   case Sema::IER_Error:
     return StmtError();
   }
-  
+
   // We need to continue with the instantiation, so do so now.
   StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
     return StmtError();
-  
+
   // If we have resolved the name, just transform to the substatement.
   if (!Dependent)
     return SubStmt;
-  
+
   // The name is still dependent, so build a dependent expression again.
   return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
                                                    S->isIfExists(),
@@ -6114,7 +6113,7 @@
       return ExprError();
   }
 
-  return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo, 
+  return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
                                          TemplateArgs);
 }
 
@@ -6226,12 +6225,12 @@
   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 
+  // 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;
@@ -6249,36 +6248,36 @@
       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);
-  
+
   // Build a new offsetof expression.
   return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
                                           Components.data(), Components.size(),
@@ -6386,10 +6385,10 @@
   // Transform arguments.
   bool ArgChanged = false;
   ASTOwningVector<Expr*> Args(SemaRef);
-  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 
+  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
                                   &ArgChanged))
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       Callee.get() == E->getCallee() &&
       !ArgChanged)
@@ -6414,7 +6413,7 @@
   if (E->hasQualifier()) {
     QualifierLoc
       = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
-    
+
     if (!QualifierLoc)
       return ExprError();
   }
@@ -6442,7 +6441,7 @@
       Member == E->getMemberDecl() &&
       FoundDecl == E->getFoundDecl() &&
       !E->hasExplicitTemplateArgs()) {
-    
+
     // Mark it referenced in the new context regardless.
     // FIXME: this is a bit instantiation-specific.
     SemaRef.MarkMemberReferenced(E);
@@ -6459,7 +6458,7 @@
                                                 TransArgs))
       return ExprError();
   }
-  
+
   // FIXME: Bogus source location for the operator
   SourceLocation FakeOperatorLoc
     = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
@@ -6577,7 +6576,7 @@
   TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
   if (!Type)
     return ExprError();
-  
+
   ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
@@ -6645,10 +6644,10 @@
   bool InitChanged = false;
 
   ASTOwningVector<Expr*, 4> Inits(SemaRef);
-  if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false, 
+  if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
                                   Inits, &InitChanged))
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() && !InitChanged)
     return SemaRef.Owned(E);
 
@@ -6729,7 +6728,7 @@
 TreeTransform<Derived>::TransformImplicitValueInitExpr(
                                                      ImplicitValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
-  
+
   // FIXME: Will we ever have proper type location here? Will we actually
   // need to transform the type?
   QualType T = getDerived().TransformType(E->getType());
@@ -6771,7 +6770,7 @@
   if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
                      &ArgumentChanged))
     return ExprError();
-  
+
   return getDerived().RebuildParenListExpr(E->getLParenLoc(),
                                            move_arg(Inits),
                                            E->getRParenLoc());
@@ -6789,13 +6788,13 @@
                                         E->getLabel());
   if (!LD)
     return ExprError();
-  
+
   return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
                                            cast<LabelDecl>(LD));
 }
 
 template<typename Derived>
-ExprResult 
+ExprResult
 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
   SemaRef.ActOnStartStmtExpr();
   StmtResult SubStmt
@@ -6858,7 +6857,7 @@
   case OO_Array_New:
   case OO_Array_Delete:
     llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
-    
+
   case OO_Call: {
     // This is a call to an object's operator().
     assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
@@ -6875,7 +6874,7 @@
 
     // Transform the call arguments.
     ASTOwningVector<Expr*> Args(SemaRef);
-    if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true, 
+    if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
                                     Args))
       return ExprError();
 
@@ -6950,7 +6949,7 @@
   // Transform arguments.
   bool ArgChanged = false;
   ASTOwningVector<Expr*> Args(SemaRef);
-  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 
+  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
                                   &ArgChanged))
     return ExprError();
 
@@ -6973,7 +6972,7 @@
   TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
   if (!Type)
     return ExprError();
-  
+
   ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
@@ -7153,7 +7152,7 @@
     getSema().CheckCXXThisCapture(E->getLocStart());
     return SemaRef.Owned(E);
   }
-  
+
   return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
 }
 
@@ -7195,12 +7194,12 @@
   TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
   if (!T)
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       T == E->getTypeSourceInfo())
     return SemaRef.Owned(E);
 
-  return getDerived().RebuildCXXScalarValueInitExpr(T, 
+  return getDerived().RebuildCXXScalarValueInitExpr(T,
                                           /*FIXME:*/T->getTypeLoc().getEndLoc(),
                                                     E->getRParenLoc());
 }
@@ -7222,7 +7221,7 @@
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
   ASTOwningVector<Expr*> PlacementArgs(SemaRef);
-  if (getDerived().TransformExprs(E->getPlacementArgs(), 
+  if (getDerived().TransformExprs(E->getPlacementArgs(),
                                   E->getNumPlacementArgs(), true,
                                   PlacementArgs, &ArgumentChanged))
     return ExprError();
@@ -7253,7 +7252,7 @@
     if (!OperatorDelete)
       return ExprError();
   }
-  
+
   if (!getDerived().AlwaysRebuild() &&
       AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
       ArraySize.get() == E->getArraySize() &&
@@ -7267,7 +7266,7 @@
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew);
     if (OperatorDelete)
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
-    
+
     if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
       QualType ElementType
         = SemaRef.Context.getBaseElementType(E->getAllocatedType());
@@ -7294,9 +7293,9 @@
       // Do nothing
     } else if (const ConstantArrayType *ConsArrayT
                                      = dyn_cast<ConstantArrayType>(ArrayT)) {
-      ArraySize 
+      ArraySize
         = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
-                                               ConsArrayT->getSize(), 
+                                               ConsArrayT->getSize(),
                                                SemaRef.Context.getSizeType(),
                                                /*FIXME:*/E->getLocStart()));
       AllocType = ConsArrayT->getElementType();
@@ -7338,7 +7337,7 @@
     if (!OperatorDelete)
       return ExprError();
   }
-  
+
   if (!getDerived().AlwaysRebuild() &&
       Operand.get() == E->getArgument() &&
       OperatorDelete == E->getOperatorDelete()) {
@@ -7346,17 +7345,17 @@
     // FIXME: instantiation-specific.
     if (OperatorDelete)
       SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
-    
+
     if (!E->getArgument()->isTypeDependent()) {
       QualType Destroyed = SemaRef.Context.getBaseElementType(
                                                          E->getDestroyedType());
       if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
         CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
-        SemaRef.MarkFunctionReferenced(E->getLocStart(), 
+        SemaRef.MarkFunctionReferenced(E->getLocStart(),
                                        SemaRef.LookupDestructor(Record));
       }
     }
-    
+
     return SemaRef.Owned(E);
   }
 
@@ -7376,14 +7375,14 @@
 
   ParsedType ObjectTypePtr;
   bool MayBePseudoDestructor = false;
-  Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(), 
+  Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
                                               E->getOperatorLoc(),
                                         E->isArrow()? tok::arrow : tok::period,
                                               ObjectTypePtr,
                                               MayBePseudoDestructor);
   if (Base.isInvalid())
     return ExprError();
-                                              
+
   QualType ObjectType = ObjectTypePtr.get();
   NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
   if (QualifierLoc) {
@@ -7418,7 +7417,7 @@
                                                 false);
     if (!T)
       return ExprError();
-    
+
     Destroyed
       = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
                                                  E->getDestroyedTypeLoc());
@@ -7430,7 +7429,7 @@
     if (!ScopeTypeInfo)
       return ExprError();
   }
-  
+
   return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
                                                      E->getOperatorLoc(),
                                                      E->isArrow(),
@@ -7486,10 +7485,10 @@
       = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
     if (!QualifierLoc)
       return ExprError();
-    
+
     SS.Adopt(QualifierLoc);
-  } 
-  
+  }
+
   if (Old->getNamingClass()) {
     CXXRecordDecl *NamingClass
       = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
@@ -7497,7 +7496,7 @@
                                                         Old->getNamingClass()));
     if (!NamingClass)
       return ExprError();
-    
+
     R.setNamingClass(NamingClass);
   }
 
@@ -7572,7 +7571,7 @@
       QualType To = getDerived().TransformType(TLB, FromTL);
       if (To.isNull())
         return ExprError();
-      
+
       if (To == From->getType())
         Args.push_back(From);
       else {
@@ -7581,15 +7580,15 @@
       }
       continue;
     }
-    
+
     ArgChanged = true;
-    
+
     // We have a pack expansion. Instantiate it.
-    PackExpansionTypeLoc ExpansionTL = cast<PackExpansionTypeLoc>(FromTL);      
+    PackExpansionTypeLoc ExpansionTL = cast<PackExpansionTypeLoc>(FromTL);
     TypeLoc PatternTL = ExpansionTL.getPatternLoc();
     SmallVector<UnexpandedParameterPack, 2> Unexpanded;
     SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
-    
+
     // Determine whether the set of unexpanded parameter packs can and should
     // be expanded.
     bool Expand = true;
@@ -7603,13 +7602,13 @@
                                              Expand, RetainExpansion,
                                              NumExpansions))
       return ExprError();
-    
+
     if (!Expand) {
       // The transform has determined that we should perform a simple
-      // transformation on the pack expansion, producing another pack 
+      // transformation on the pack expansion, producing another pack
       // expansion.
       Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
-      
+
       TypeLocBuilder TLB;
       TLB.reserve(From->getTypeLoc().getFullDataSize());
 
@@ -7617,13 +7616,13 @@
       if (To.isNull())
         return ExprError();
 
-      To = getDerived().RebuildPackExpansionType(To, 
+      To = getDerived().RebuildPackExpansionType(To,
                                                  PatternTL.getSourceRange(),
                                                  ExpansionTL.getEllipsisLoc(),
                                                  NumExpansions);
       if (To.isNull())
         return ExprError();
-      
+
       PackExpansionTypeLoc ToExpansionTL
         = TLB.push<PackExpansionTypeLoc>(To);
       ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
@@ -7643,34 +7642,34 @@
 
       Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
     }
-    
+
     if (!RetainExpansion)
       continue;
-    
+
     // If we're supposed to retain a pack expansion, do so by temporarily
     // forgetting the partially-substituted parameter pack.
     ForgetPartiallySubstitutedPackRAII Forget(getDerived());
 
     TypeLocBuilder TLB;
     TLB.reserve(From->getTypeLoc().getFullDataSize());
-    
+
     QualType To = getDerived().TransformType(TLB, PatternTL);
     if (To.isNull())
       return ExprError();
-    
-    To = getDerived().RebuildPackExpansionType(To, 
+
+    To = getDerived().RebuildPackExpansionType(To,
                                                PatternTL.getSourceRange(),
                                                ExpansionTL.getEllipsisLoc(),
                                                NumExpansions);
     if (To.isNull())
       return ExprError();
-    
+
     PackExpansionTypeLoc ToExpansionTL
       = TLB.push<PackExpansionTypeLoc>(To);
     ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
     Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
   }
-  
+
   if (!getDerived().AlwaysRebuild() && !ArgChanged)
     return SemaRef.Owned(E);
 
@@ -7796,10 +7795,10 @@
 
   bool ArgumentChanged = false;
   ASTOwningVector<Expr*> Args(SemaRef);
-  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 
+  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
                                   &ArgumentChanged))
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType() &&
       Constructor == E->getConstructor() &&
@@ -7850,7 +7849,7 @@
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
-                                  getDerived().TransformDecl(E->getLocStart(), 
+                                  getDerived().TransformDecl(E->getLocStart(),
                                                          E->getConstructor()));
   if (!Constructor)
     return ExprError();
@@ -7858,7 +7857,7 @@
   bool ArgumentChanged = false;
   ASTOwningVector<Expr*> Args(SemaRef);
   Args.reserve(E->getNumArgs());
-  if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 
+  if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
                      &ArgumentChanged))
     return ExprError();
 
@@ -7870,7 +7869,7 @@
     SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
     return SemaRef.MaybeBindToTemporary(E);
   }
-  
+
   return getDerived().RebuildCXXTemporaryObjectExpr(T,
                                           /*FIXME:*/T->getTypeLoc().getEndLoc(),
                                                     move_arg(Args),
@@ -7885,23 +7884,22 @@
     = getSema().createLambdaClosureType(E->getIntroducerRange(),
                                         /*KnownDependent=*/false);
   getDerived().transformedLocalDecl(E->getLambdaClass(), Class);
-  
+
   // Transform the type of the lambda parameters and start the definition of
   // the lambda itself.
   TypeSourceInfo *MethodTy
-    = TransformType(E->getCallOperator()->getTypeSourceInfo());  
+    = TransformType(E->getCallOperator()->getTypeSourceInfo());
   if (!MethodTy)
     return ExprError();
 
   // Transform lambda parameters.
-  bool Invalid = false;
   llvm::SmallVector<QualType, 4> ParamTypes;
   llvm::SmallVector<ParmVarDecl *, 4> Params;
   if (getDerived().TransformFunctionTypeParams(E->getLocStart(),
         E->getCallOperator()->param_begin(),
         E->getCallOperator()->param_size(),
         0, ParamTypes, &Params))
-    Invalid = true;  
+    return ExprError();
 
   // Build the call operator.
   CXXMethodDecl *CallOperator
@@ -7910,11 +7908,14 @@
                                       E->getCallOperator()->getLocEnd(),
                                       Params);
   getDerived().transformAttrs(E->getCallOperator(), CallOperator);
-  
-  // FIXME: Instantiation-specific.
-  CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(), 
-                                                 TSK_ImplicitInstantiation);
 
+  return getDerived().TransformLambdaScope(E, CallOperator);
+}
+
+template<typename Derived>
+ExprResult
+TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
+                                             CXXMethodDecl *CallOperator) {
   // Introduce the context of the call operator.
   Sema::ContextRAII SavedContext(getSema(), CallOperator);
 
@@ -7925,10 +7926,11 @@
                                  E->hasExplicitParameters(),
                                  E->hasExplicitResultType(),
                                  E->isMutable());
-  
+
   // Transform captures.
+  bool Invalid = false;
   bool FinishedExplicitCaptures = false;
-  for (LambdaExpr::capture_iterator C = E->capture_begin(), 
+  for (LambdaExpr::capture_iterator C = E->capture_begin(),
                                  CEnd = E->capture_end();
        C != CEnd; ++C) {
     // When we hit the first implicit capture, tell Sema that we've finished
@@ -7937,13 +7939,13 @@
       getSema().finishLambdaExplicitCaptures(LSI);
       FinishedExplicitCaptures = true;
     }
-    
+
     // Capturing 'this' is trivial.
     if (C->capturesThis()) {
       getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit());
       continue;
     }
-    
+
     // Determine the capture kind for Sema.
     Sema::TryCaptureKind Kind
       = C->isImplicit()? Sema::TryCapture_Implicit
@@ -7956,13 +7958,13 @@
       bool ShouldExpand = false;
       bool RetainExpansion = false;
       llvm::Optional<unsigned> NumExpansions;
-      if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), 
-                                               C->getLocation(), 
+      if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
+                                               C->getLocation(),
                                                Unexpanded,
                                                ShouldExpand, RetainExpansion,
                                                NumExpansions))
         return ExprError();
-      
+
       if (ShouldExpand) {
         // The transform has determined that we should perform an expansion;
         // transform and capture each of the arguments.
@@ -7971,31 +7973,31 @@
         for (unsigned I = 0; I != *NumExpansions; ++I) {
           Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
           VarDecl *CapturedVar
-            = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), 
+            = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
                                                                Pack));
           if (!CapturedVar) {
             Invalid = true;
             continue;
           }
-          
+
           // Capture the transformed variable.
-          getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);          
-        }          
+          getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
+        }
         continue;
       }
-      
+
       EllipsisLoc = C->getEllipsisLoc();
     }
-    
+
     // Transform the captured variable.
     VarDecl *CapturedVar
-      = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), 
+      = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
                                                          C->getCapturedVar()));
     if (!CapturedVar) {
       Invalid = true;
       continue;
     }
-  
+
     // Capture the transformed variable.
     getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
   }
@@ -8005,10 +8007,10 @@
 
   // Enter a new evaluation context to insulate the lambda from any
   // cleanups from the enclosing full-expression.
-  getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);  
+  getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
 
   if (Invalid) {
-    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0, 
+    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
                                /*IsInstantiation=*/true);
     return ExprError();
   }
@@ -8016,12 +8018,12 @@
   // Instantiate the body of the lambda expression.
   StmtResult Body = getDerived().TransformStmt(E->getBody());
   if (Body.isInvalid()) {
-    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0, 
+    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
                                /*IsInstantiation=*/true);
-    return ExprError();    
+    return ExprError();
   }
 
-  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(), 
+  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
                                    /*CurScope=*/0, /*IsInstantiation=*/true);
 }
 
@@ -8036,10 +8038,10 @@
   bool ArgumentChanged = false;
   ASTOwningVector<Expr*> Args(SemaRef);
   Args.reserve(E->arg_size());
-  if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args, 
+  if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args,
                                   &ArgumentChanged))
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       T == E->getTypeSourceInfo() &&
       !ArgumentChanged)
@@ -8218,16 +8220,16 @@
 
   // Determine the naming class.
   if (Old->getNamingClass()) {
-    CXXRecordDecl *NamingClass 
+    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());
@@ -8243,7 +8245,7 @@
   // base (and therefore couldn't do the check) and a
   // nested-name-qualifier (and therefore could do the lookup).
   NamedDecl *FirstQualifierInScope = 0;
-  
+
   return getDerived().RebuildUnresolvedMemberExpr(Base.get(),
                                                   BaseType,
                                                   Old->getOperatorLoc(),
@@ -8276,7 +8278,7 @@
   ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
   if (Pattern.isInvalid())
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
     return SemaRef.Owned(E);
 
@@ -8294,33 +8296,33 @@
 
   // Note: None of the implementations of TryExpandParameterPacks can ever
   // produce a diagnostic when given only a single unexpanded parameter pack,
-  // so 
+  // so
   UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
   bool ShouldExpand = false;
   bool RetainExpansion = false;
   llvm::Optional<unsigned> NumExpansions;
-  if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(), 
+  if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
                                            Unexpanded,
                                            ShouldExpand, RetainExpansion,
                                            NumExpansions))
     return ExprError();
-  
+
   if (RetainExpansion)
     return SemaRef.Owned(E);
-    
+
   NamedDecl *Pack = E->getPack();
   if (!ShouldExpand) {
-    Pack = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getPackLoc(), 
+    Pack = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getPackLoc(),
                                                               Pack));
     if (!Pack)
       return ExprError();
   }
 
-  
+
   // We now know the length of the parameter pack, so build a new expression
   // that stores that length.
-  return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack, 
-                                            E->getPackLoc(), E->getRParenLoc(), 
+  return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack,
+                                            E->getPackLoc(), E->getRParenLoc(),
                                             NumExpansions);
 }
 
@@ -8346,7 +8348,7 @@
                                                   MaterializeTemporaryExpr *E) {
   return getDerived().TransformExpr(E->GetTemporaryExpr());
 }
-  
+
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
@@ -8379,13 +8381,13 @@
   // Transform each of the elements.
   llvm::SmallVector<Expr *, 8> Elements;
   bool ArgChanged = false;
-  if (getDerived().TransformExprs(E->getElements(), E->getNumElements(), 
+  if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
                                   /*IsCall=*/false, Elements, &ArgChanged))
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() && !ArgChanged)
     return SemaRef.MaybeBindToTemporary(E);
-  
+
   return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
                                               Elements.data(),
                                               Elements.size());
@@ -8394,13 +8396,13 @@
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
-                                                    ObjCDictionaryLiteral *E) {  
+                                                    ObjCDictionaryLiteral *E) {
   // Transform each of the elements.
   llvm::SmallVector<ObjCDictionaryElement, 8> Elements;
   bool ArgChanged = false;
   for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
     ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
-    
+
     if (OrigElement.isPackExpansion()) {
       // This key/value element is a pack expansion.
       SmallVector<UnexpandedParameterPack, 2> Unexpanded;
@@ -8425,7 +8427,7 @@
 
       if (!Expand) {
         // The transform has determined that we should perform a simple
-        // transformation on the pack expansion, producing another pack 
+        // transformation on the pack expansion, producing another pack
         // expansion.
         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
         ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
@@ -8438,11 +8440,11 @@
         ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
         if (Value.isInvalid())
           return ExprError();
-        
+
         if (Value.get() != OrigElement.Value)
           ArgChanged = true;
 
-        ObjCDictionaryElement Expansion = { 
+        ObjCDictionaryElement Expansion = {
           Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
         };
         Elements.push_back(Expansion);
@@ -8452,7 +8454,7 @@
       // Record right away that the argument was changed.  This needs
       // to happen even if the array expands to nothing.
       ArgChanged = true;
-      
+
       // The transform has determined that we should perform an elementwise
       // expansion of the pattern. Do so.
       for (unsigned I = 0; I != *NumExpansions; ++I) {
@@ -8465,7 +8467,7 @@
         if (Value.isInvalid())
           return ExprError();
 
-        ObjCDictionaryElement Element = { 
+        ObjCDictionaryElement Element = {
           Key.get(), Value.get(), SourceLocation(), NumExpansions
         };
 
@@ -8474,7 +8476,7 @@
         if (Key.get()->containsUnexpandedParameterPack() ||
             Value.get()->containsUnexpandedParameterPack())
           Element.EllipsisLoc = OrigElement.EllipsisLoc;
-          
+
         Elements.push_back(Element);
       }
 
@@ -8486,25 +8488,25 @@
     ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
     if (Key.isInvalid())
       return ExprError();
-    
+
     if (Key.get() != OrigElement.Key)
       ArgChanged = true;
-    
+
     // Transform and check value.
     ExprResult Value
       = getDerived().TransformExpr(OrigElement.Value);
     if (Value.isInvalid())
       return ExprError();
-    
+
     if (Value.get() != OrigElement.Value)
       ArgChanged = true;
-    
-    ObjCDictionaryElement Element = { 
+
+    ObjCDictionaryElement Element = {
       Key.get(), Value.get(), SourceLocation(), llvm::Optional<unsigned>()
     };
     Elements.push_back(Element);
   }
-  
+
   if (!getDerived().AlwaysRebuild() && !ArgChanged)
     return SemaRef.MaybeBindToTemporary(E);
 
@@ -8548,22 +8550,22 @@
 template<typename Derived>
 ExprResult TreeTransform<Derived>::
 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
-  TypeSourceInfo *TSInfo 
+  TypeSourceInfo *TSInfo
     = getDerived().TransformType(E->getTypeInfoAsWritten());
   if (!TSInfo)
     return ExprError();
-  
+
   ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
-  if (Result.isInvalid()) 
+  if (Result.isInvalid())
     return ExprError();
-  
+
   if (!getDerived().AlwaysRebuild() &&
       TSInfo == E->getTypeInfoAsWritten() &&
       Result.get() == E->getSubExpr())
     return SemaRef.Owned(E);
-  
+
   return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
-                                      E->getBridgeKeywordLoc(), TSInfo, 
+                                      E->getBridgeKeywordLoc(), TSInfo,
                                       Result.get());
 }
 
@@ -8574,17 +8576,17 @@
   bool ArgChanged = false;
   ASTOwningVector<Expr*> Args(SemaRef);
   Args.reserve(E->getNumArgs());
-  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args, 
+  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
                                   &ArgChanged))
     return ExprError();
-  
+
   if (E->getReceiverKind() == ObjCMessageExpr::Class) {
     // Class message: transform the receiver type.
     TypeSourceInfo *ReceiverTypeInfo
       = getDerived().TransformType(E->getClassReceiverTypeInfo());
     if (!ReceiverTypeInfo)
       return ExprError();
-    
+
     // If nothing changed, just retain the existing message send.
     if (!getDerived().AlwaysRebuild() &&
         ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
@@ -8614,7 +8616,7 @@
   if (!getDerived().AlwaysRebuild() &&
       Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
     return SemaRef.MaybeBindToTemporary(E);
-  
+
   // Build a new instance message send.
   SmallVector<SourceLocation, 16> SelLocs;
   E->getSelectorLocs(SelLocs);
@@ -8648,12 +8650,12 @@
     return ExprError();
 
   // We don't need to transform the ivar; it will never change.
-  
+
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
     return SemaRef.Owned(E);
-  
+
   return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
                                              E->getLocation(),
                                              E->isArrow(), E->isFreeIvar());
@@ -8666,14 +8668,14 @@
   // retain the existing expression.
   if (!E->isObjectReceiver())
     return SemaRef.Owned(E);
-  
+
   // Transform the base expression.
   ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
     return ExprError();
-  
+
   // We don't need to transform the property; it will never change.
-  
+
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
@@ -8709,7 +8711,7 @@
       Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
     return SemaRef.Owned(E);
 
-  return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(), 
+  return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
                                                   Base.get(), Key.get(),
                                                   E->getAtIndexMethodDecl(),
                                                   E->setAtIndexMethodDecl());
@@ -8722,12 +8724,12 @@
   ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
     return ExprError();
-  
+
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
     return SemaRef.Owned(E);
-  
+
   return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
                                          E->isArrow());
 }
@@ -8738,7 +8740,7 @@
   bool ArgumentChanged = false;
   ASTOwningVector<Expr*> SubExprs(SemaRef);
   SubExprs.reserve(E->getNumSubExprs());
-  if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, 
+  if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
                                   SubExprs, &ArgumentChanged))
     return ExprError();
 
@@ -8755,17 +8757,17 @@
 ExprResult
 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
   BlockDecl *oldBlock = E->getBlockDecl();
-  
+
   SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/0);
   BlockScopeInfo *blockScope = SemaRef.getCurBlock();
 
   blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
   blockScope->TheDecl->setBlockMissingReturnType(
                          oldBlock->blockMissingReturnType());
-  
+
   SmallVector<ParmVarDecl*, 4> params;
   SmallVector<QualType, 4> paramTypes;
-  
+
   // Parameter substitution.
   if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(),
                                                oldBlock->param_begin(),
@@ -8781,8 +8783,8 @@
 
   // Don't allow returning a objc interface by value.
   if (exprResultType->isObjCObjectType()) {
-    getSema().Diag(E->getCaretLocation(), 
-                   diag::err_object_cannot_be_passed_returned_by_value) 
+    getSema().Diag(E->getCaretLocation(),
+                   diag::err_object_cannot_be_passed_returned_by_value)
       << 0 << exprResultType;
     getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
     return ExprError();
@@ -8805,7 +8807,7 @@
     blockScope->HasImplicitReturnType = false;
     blockScope->ReturnType = exprResultType;
   }
-  
+
   // Transform the body
   StmtResult body = getDerived().TransformStmt(E->getBody());
   if (body.isInvalid()) {
@@ -8863,7 +8865,7 @@
   return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), move_arg(SubExprs),
                                         RetTy, E->getOp(), E->getRParenLoc());
 }
-  
+
 //===----------------------------------------------------------------------===//
 // Type reconstruction
 //===----------------------------------------------------------------------===//
@@ -9045,7 +9047,7 @@
     // A valid resolved using typename decl points to exactly one type decl.
     assert(++Using->shadow_begin() == Using->shadow_end());
     Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl());
-    
+
   } else {
     assert(isa<UnresolvedUsingTypenameDecl>(D) &&
            "UnresolvedUsingTypenameDecl transformed to non-using decl");
@@ -9140,7 +9142,7 @@
                                        Template);
   return Template.template getAsVal<TemplateName>();
 }
-  
+
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
@@ -9240,7 +9242,7 @@
 }
 
 template<typename Derived>
-ExprResult 
+ExprResult
 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
                                                      SourceLocation OperatorLoc,
                                                        bool isArrow,
@@ -9252,7 +9254,7 @@
   QualType BaseType = Base->getType();
   if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
       (!isArrow && !BaseType->getAs<RecordType>()) ||
-      (isArrow && BaseType->getAs<PointerType>() && 
+      (isArrow && BaseType->getAs<PointerType>() &&
        !BaseType->getAs<PointerType>()->getPointeeType()
                                               ->template getAs<RecordType>())){
     // This pseudo-destructor expression is still a pseudo-destructor.
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 4073e32..3adbc57 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3906,6 +3906,8 @@
     } else if (EST == EST_Uninstantiated) {
       EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
       EPI.ExceptionSpecTemplate = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
+    } else if (EST == EST_Unevaluated) {
+      EPI.ExceptionSpecDecl = ReadDeclAs<FunctionDecl>(*Loc.F, Record, Idx);
     }
     return Context.getFunctionType(ResultType, ParamTypes.data(), NumParams,
                                     EPI);
@@ -4257,7 +4259,6 @@
 void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
   TL.setLocalRangeBegin(ReadSourceLocation(Record, Idx));
   TL.setLocalRangeEnd(ReadSourceLocation(Record, Idx));
-  TL.setTrailingReturn(Record[Idx++]);
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
     TL.setArg(i, ReadDeclAs<ParmVarDecl>(Record, Idx));
   }
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index c5325b5..e6f62f8 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -297,7 +297,6 @@
   S->setRParenLoc(ReadSourceLocation(Record, Idx));
   S->setVolatile(Record[Idx++]);
   S->setSimple(Record[Idx++]);
-  S->setMSAsm(Record[Idx++]);
 
   S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
 
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 6a6863f..425d2e3 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -198,6 +198,8 @@
   } else if (T->getExceptionSpecType() == EST_Uninstantiated) {
     Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
     Writer.AddDeclRef(T->getExceptionSpecTemplate(), Record);
+  } else if (T->getExceptionSpecType() == EST_Unevaluated) {
+    Writer.AddDeclRef(T->getExceptionSpecDecl(), Record);
   }
   Code = TYPE_FUNCTION_PROTO;
 }
@@ -484,7 +486,6 @@
 void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) {
   Writer.AddSourceLocation(TL.getLocalRangeBegin(), Record);
   Writer.AddSourceLocation(TL.getLocalRangeEnd(), Record);
-  Record.push_back(TL.getTrailingReturn());
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     Writer.AddDeclRef(TL.getArg(i), Record);
 }
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index f63388f..9f12b8a 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -227,7 +227,6 @@
   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
diff --git a/lib/Serialization/CMakeLists.txt b/lib/Serialization/CMakeLists.txt
index a0f4ac8..20999e1 100644
--- a/lib/Serialization/CMakeLists.txt
+++ b/lib/Serialization/CMakeLists.txt
@@ -16,13 +16,15 @@
 add_dependencies(clangSerialization
   ClangAttrClasses
   ClangAttrList
+  ClangAttrParsedAttrList
   ClangAttrPCHRead
   ClangAttrPCHWrite
+  ClangCommentNodes
+  ClangDeclNodes
+  ClangDiagnosticCommon
   ClangDiagnosticLex
   ClangDiagnosticSema
   ClangDiagnosticSerialization
-  ClangCommentNodes
-  ClangDeclNodes
   ClangStmtNodes
   )
 
diff --git a/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp b/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
index 27faf18..c582cfc 100644
--- a/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AttrNonNullChecker.cpp
@@ -15,7 +15,7 @@
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 
@@ -105,8 +105,7 @@
         // Highlight the range of the argument that was null.
         R->addRange(Call.getArgSourceRange(idx));
         if (const Expr *ArgE = Call.getArgExpr(idx))
-          R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(errorNode,
-                                                                     ArgE, R));
+          bugreporter::addTrackNullOrUndefValueVisitor(errorNode, ArgE, R);
         // Emit the bug report.
         C.EmitReport(R);
       }
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 1d0c4b3..955e79a 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -17,7 +17,7 @@
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
@@ -432,8 +432,7 @@
 
     BugReport *report = new BugReport(*BT, description, N);
     report->addRange(Arg->getSourceRange());
-    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Arg,
-                                                                    report));
+    bugreporter::addTrackNullOrUndefValueVisitor(N, Arg, report);
     C.EmitReport(report);
     return;
   }
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 86eb533..7fe51d3 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -29,11 +29,11 @@
   DebugCheckers.cpp
   DereferenceChecker.cpp
   DivZeroChecker.cpp
+  DynamicTypePropagation.cpp
   ExprInspectionChecker.cpp
   FixedAddressChecker.cpp
   GenericTaintChecker.cpp
   IdempotentOperationChecker.cpp
-  IteratorsChecker.cpp
   LLVMConventionsChecker.cpp
   MacOSKeychainAPIChecker.cpp
   MacOSXAPIChecker.cpp
@@ -76,6 +76,7 @@
   ClangAttrList
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticCommon
   ClangStmtNodes
   ClangSACheckers
   )
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 6937374..483082a 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -252,8 +252,7 @@
     BugReport *report = new BugReport(*BT, os.str(), N);
 
     report->addRange(S->getSourceRange());
-    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, S,
-                                                                    report));
+    bugreporter::addTrackNullOrUndefValueVisitor(N, S, report);
     C.EmitReport(report);
     return NULL;
   }
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 17ed692..5edcf09 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -15,7 +15,7 @@
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/AST/ParentMap.h"
@@ -31,6 +31,8 @@
                     check::PreCall > {
   mutable OwningPtr<BugType> BT_call_null;
   mutable OwningPtr<BugType> BT_call_undef;
+  mutable OwningPtr<BugType> BT_cxx_call_null;
+  mutable OwningPtr<BugType> BT_cxx_call_undef;
   mutable OwningPtr<BugType> BT_call_arg;
   mutable OwningPtr<BugType> BT_msg_undef;
   mutable OwningPtr<BugType> BT_objc_prop_undef;
@@ -49,7 +51,7 @@
                                  bool IsFirstArgument, bool checkUninitFields,
                                  const CallEvent &Call, OwningPtr<BugType> &BT);
 
-  static void EmitBadCall(BugType *BT, CheckerContext &C, const CallExpr *CE);
+  static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
   void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
                           ExplodedNode *N) const;
 
@@ -64,15 +66,17 @@
 };
 } // end anonymous namespace
 
-void CallAndMessageChecker::EmitBadCall(BugType *BT, CheckerContext &C,
-                                        const CallExpr *CE) {
+void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
+                                        const Expr *BadE) {
   ExplodedNode *N = C.generateSink();
   if (!N)
     return;
 
   BugReport *R = new BugReport(*BT, BT->getName(), N);
-  R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                               bugreporter::GetCalleeExpr(N), R));
+  if (BadE) {
+    R->addRange(BadE->getSourceRange());
+    bugreporter::addTrackNullOrUndefValueVisitor(N, BadE, R);
+  }
   C.EmitReport(R);
 }
 
@@ -118,8 +122,7 @@
       BugReport *R = new BugReport(*BT, Desc, N);
       R->addRange(argRange);
       if (argEx)
-        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, argEx,
-                                                                   R));
+        bugreporter::addTrackNullOrUndefValueVisitor(N, argEx, R);
       C.EmitReport(R);
     }
     return true;
@@ -225,28 +228,60 @@
     if (!BT_call_undef)
       BT_call_undef.reset(new BuiltinBug("Called function pointer is an "
                                          "uninitalized pointer value"));
-    EmitBadCall(BT_call_undef.get(), C, CE);
+    emitBadCall(BT_call_undef.get(), C, Callee);
     return;
   }
 
-  if (L.isZeroConstant()) {
+  ProgramStateRef StNonNull, StNull;
+  llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(L));
+
+  if (StNull && !StNonNull) {
     if (!BT_call_null)
       BT_call_null.reset(
         new BuiltinBug("Called function pointer is null (null dereference)"));
-    EmitBadCall(BT_call_null.get(), C, CE);
+    emitBadCall(BT_call_null.get(), C, Callee);
   }
+
+  C.addTransition(StNonNull);
 }
 
 void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
                                          CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+
+  // If this is a call to a C++ method, check if the callee is null or
+  // undefined.
+  if (const CXXInstanceCall *CC = dyn_cast<CXXInstanceCall>(&Call)) {
+    SVal V = CC->getCXXThisVal();
+    if (V.isUndef()) {
+      if (!BT_cxx_call_undef)
+        BT_cxx_call_undef.reset(new BuiltinBug("Called C++ object pointer is "
+                                               "uninitialized"));
+      emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
+      return;
+    }
+
+    ProgramStateRef StNonNull, StNull;
+    llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
+
+    if (StNull && !StNonNull) {
+      if (!BT_cxx_call_null)
+        BT_cxx_call_null.reset(new BuiltinBug("Called C++ object pointer "
+                                              "is null"));
+      emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
+      return;
+    }
+
+    State = StNonNull;
+  }
+
   // Don't check for uninitialized field values in arguments if the
   // caller has a body that is available and we have the chance to inline it.
   // This is a hack, but is a reasonable compromise betweens sometimes warning
   // and sometimes not depending on if we decide to inline a function.
   const Decl *D = Call.getDecl();
   const bool checkUninitFields =
-    !(C.getAnalysisManager().shouldInlineCall() &&
-      (D && D->getBody()));
+    !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody()));
 
   OwningPtr<BugType> *BT;
   if (isa<ObjCMethodCall>(Call))
@@ -259,6 +294,9 @@
                            Call.getArgExpr(i), /*IsFirstArgument=*/i == 0,
                            checkUninitFields, Call, *BT))
       return;
+
+  // If we make it here, record our assumptions about the callee.
+  C.addTransition(State);
 }
 
 void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
@@ -297,9 +335,7 @@
 
       // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
       if (const Expr *ReceiverE = ME->getInstanceReceiver())
-        R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                   ReceiverE,
-                                                                   R));
+        bugreporter::addTrackNullOrUndefValueVisitor(N, ReceiverE, R);
       C.EmitReport(R);
     }
     return;
@@ -341,9 +377,7 @@
   report->addRange(ME->getReceiverRange());
   // FIXME: This won't track "self" in messages to super.
   if (const Expr *receiver = ME->getInstanceReceiver()) {
-    report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                    receiver,
-                                                                    report));
+    bugreporter::addTrackNullOrUndefValueVisitor(N, receiver, report);
   }
   C.EmitReport(report);
 }
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index dde9071..b8b7c36 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -31,6 +31,7 @@
          T.getOS() == llvm::Triple::FreeBSD ||
          T.getOS() == llvm::Triple::NetBSD ||
          T.getOS() == llvm::Triple::OpenBSD ||
+         T.getOS() == llvm::Triple::Bitrig ||
          T.getOS() == llvm::Triple::DragonFly;
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td
index 99410de..8110bd0 100644
--- a/lib/StaticAnalyzer/Checkers/Checkers.td
+++ b/lib/StaticAnalyzer/Checkers/Checkers.td
@@ -84,6 +84,10 @@
   HelpText<"Check that addresses to stack memory do not escape the function">,
   DescFile<"StackAddrEscapeChecker.cpp">;
 
+def DynamicTypePropagation : Checker<"DynamicTypePropagation">,
+  HelpText<"Generate dynamic type information">,
+  DescFile<"DynamicTypePropagation.cpp">;
+
 } // end "core"
 
 let ParentPackage = CoreExperimental in {
@@ -168,10 +172,6 @@
 
 let ParentPackage = CplusplusExperimental in {
 
-def IteratorsChecker : Checker<"Iterators">,
-  HelpText<"Check improper uses of STL vector iterators">,
-  DescFile<"IteratorsChecker.cpp">;
-
 def VirtualCallChecker : Checker<"VirtualCall">,
   HelpText<"Check virtual function calls during construction or destruction">, 
   DescFile<"VirtualCallChecker.cpp">;
diff --git a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
index 9b56c9f..e98c131 100644
--- a/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp
@@ -26,13 +26,18 @@
 namespace {
 class DereferenceChecker
     : public Checker< check::Location,
-                        EventDispatcher<ImplicitNullDerefEvent> > {
+                      check::Bind,
+                      EventDispatcher<ImplicitNullDerefEvent> > {
   mutable OwningPtr<BuiltinBug> BT_null;
   mutable OwningPtr<BuiltinBug> BT_undef;
 
+  void reportBug(ProgramStateRef State, const Stmt *S, CheckerContext &C,
+                 bool IsBind = false) const;
+
 public:
   void checkLocation(SVal location, bool isLoad, const Stmt* S,
                      CheckerContext &C) const;
+  void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
 
   static const MemRegion *AddDerefSource(raw_ostream &os,
                              SmallVectorImpl<SourceRange> &Ranges,
@@ -76,6 +81,106 @@
   return sourceR;
 }
 
+void DereferenceChecker::reportBug(ProgramStateRef State, const Stmt *S,
+                                   CheckerContext &C, bool IsBind) const {
+  // Generate an error node.
+  ExplodedNode *N = C.generateSink(State);
+  if (!N)
+    return;
+
+  // We know that 'location' cannot be non-null.  This is what
+  // we call an "explicit" null dereference.
+  if (!BT_null)
+    BT_null.reset(new BuiltinBug("Dereference of null pointer"));
+
+  SmallString<100> buf;
+  SmallVector<SourceRange, 2> Ranges;
+
+  // Walk through lvalue casts to get the original expression
+  // that syntactically caused the load.
+  if (const Expr *expr = dyn_cast<Expr>(S))
+    S = expr->IgnoreParenLValueCasts();
+
+  const MemRegion *sourceR = 0;
+
+  if (IsBind) {
+    if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
+      if (BO->isAssignmentOp())
+        S = BO->getRHS();
+    } else if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+      assert(DS->isSingleDecl() && "We process decls one by one");
+      if (const VarDecl *VD = dyn_cast<VarDecl>(DS->getSingleDecl()))
+        if (const Expr *Init = VD->getAnyInitializer())
+          S = Init;
+    }
+  }
+
+  switch (S->getStmtClass()) {
+  case Stmt::ArraySubscriptExprClass: {
+    llvm::raw_svector_ostream os(buf);
+    os << "Array access";
+    const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
+    sourceR = AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
+                             State.getPtr(), N->getLocationContext());
+    os << " results in a null pointer dereference";
+    break;
+  }
+  case Stmt::UnaryOperatorClass: {
+    llvm::raw_svector_ostream os(buf);
+    os << "Dereference of null pointer";
+    const UnaryOperator *U = cast<UnaryOperator>(S);
+    sourceR = AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
+                             State.getPtr(), N->getLocationContext(), true);
+    break;
+  }
+  case Stmt::MemberExprClass: {
+    const MemberExpr *M = cast<MemberExpr>(S);
+    if (M->isArrow()) {
+      llvm::raw_svector_ostream os(buf);
+      os << "Access to field '" << M->getMemberNameInfo()
+         << "' results in a dereference of a null pointer";
+      sourceR = AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
+                               State.getPtr(), N->getLocationContext(), true);
+    }
+    break;
+  }
+  case Stmt::ObjCIvarRefExprClass: {
+    const ObjCIvarRefExpr *IV = cast<ObjCIvarRefExpr>(S);
+    if (const DeclRefExpr *DR =
+        dyn_cast<DeclRefExpr>(IV->getBase()->IgnoreParenCasts())) {
+      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
+        llvm::raw_svector_ostream os(buf);
+        os << "Instance variable access (via '" << VD->getName()
+           << "') results in a null pointer dereference";
+      }
+    }
+    Ranges.push_back(IV->getSourceRange());
+    break;
+  }
+  default:
+    break;
+  }
+
+  BugReport *report =
+    new BugReport(*BT_null,
+                  buf.empty() ? BT_null->getDescription() : buf.str(),
+                  N);
+
+  bugreporter::addTrackNullOrUndefValueVisitor(N, bugreporter::GetDerefExpr(N),
+                                               report);
+
+  for (SmallVectorImpl<SourceRange>::iterator
+       I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
+    report->addRange(*I);
+
+  if (sourceR) {
+    report->markInteresting(sourceR);
+    report->markInteresting(State->getRawSVal(loc::MemRegionVal(sourceR)));
+  }
+
+  C.EmitReport(report);
+}
+
 void DereferenceChecker::checkLocation(SVal l, bool isLoad, const Stmt* S,
                                        CheckerContext &C) const {
   // Check for dereference of an undefined value.
@@ -86,8 +191,9 @@
 
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                        bugreporter::GetDerefExpr(N), report));
+      bugreporter::addTrackNullOrUndefValueVisitor(N,
+                                                   bugreporter::GetDerefExpr(N),
+                                                   report);
       report->disablePathPruning();
       C.EmitReport(report);
     }
@@ -101,110 +207,23 @@
     return;
 
   ProgramStateRef state = C.getState();
-  const LocationContext *LCtx = C.getLocationContext();
+
   ProgramStateRef notNullState, nullState;
   llvm::tie(notNullState, nullState) = state->assume(location);
 
   // The explicit NULL case.
   if (nullState) {
     if (!notNullState) {
-      // Generate an error node.
-      ExplodedNode *N = C.generateSink(nullState);
-      if (!N)
-        return;
-
-      // We know that 'location' cannot be non-null.  This is what
-      // we call an "explicit" null dereference.
-      if (!BT_null)
-        BT_null.reset(new BuiltinBug("Dereference of null pointer"));
-
-      SmallString<100> buf;
-      SmallVector<SourceRange, 2> Ranges;
-      
-      // Walk through lvalue casts to get the original expression
-      // that syntactically caused the load.
-      if (const Expr *expr = dyn_cast<Expr>(S))
-        S = expr->IgnoreParenLValueCasts();
-      
-      const MemRegion *sourceR = 0;
-
-      switch (S->getStmtClass()) {
-        case Stmt::ArraySubscriptExprClass: {
-          llvm::raw_svector_ostream os(buf);
-          os << "Array access";
-          const ArraySubscriptExpr *AE = cast<ArraySubscriptExpr>(S);
-          sourceR =
-            AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(),
-                           state.getPtr(), LCtx);
-          os << " results in a null pointer dereference";
-          break;
-        }
-        case Stmt::UnaryOperatorClass: {
-          llvm::raw_svector_ostream os(buf);
-          os << "Dereference of null pointer";
-          const UnaryOperator *U = cast<UnaryOperator>(S);
-          sourceR =
-            AddDerefSource(os, Ranges, U->getSubExpr()->IgnoreParens(),
-                           state.getPtr(), LCtx, true);
-          break;
-        }
-        case Stmt::MemberExprClass: {
-          const MemberExpr *M = cast<MemberExpr>(S);
-          if (M->isArrow()) {
-            llvm::raw_svector_ostream os(buf);
-            os << "Access to field '" << M->getMemberNameInfo()
-               << "' results in a dereference of a null pointer";
-            sourceR =
-              AddDerefSource(os, Ranges, M->getBase()->IgnoreParenCasts(),
-                             state.getPtr(), LCtx, true);
-          }
-          break;
-        }
-        case Stmt::ObjCIvarRefExprClass: {
-          const ObjCIvarRefExpr *IV = cast<ObjCIvarRefExpr>(S);
-          if (const DeclRefExpr *DR =
-              dyn_cast<DeclRefExpr>(IV->getBase()->IgnoreParenCasts())) {
-            if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
-              llvm::raw_svector_ostream os(buf);
-              os << "Instance variable access (via '" << VD->getName()
-                 << "') results in a null pointer dereference";
-            }
-          }
-          Ranges.push_back(IV->getSourceRange());
-          break;
-        }
-        default:
-          break;
-      }
-
-      BugReport *report =
-        new BugReport(*BT_null,
-                              buf.empty() ? BT_null->getDescription():buf.str(),
-                              N);
-
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                        bugreporter::GetDerefExpr(N), report));
-
-      for (SmallVectorImpl<SourceRange>::iterator
-            I = Ranges.begin(), E = Ranges.end(); I!=E; ++I)
-        report->addRange(*I);
-
-      if (sourceR) {
-        report->markInteresting(sourceR);
-        report->markInteresting(state->getRawSVal(loc::MemRegionVal(sourceR)));
-      }
-
-      C.EmitReport(report);
+      reportBug(nullState, S, C);
       return;
     }
-    else {
-      // Otherwise, we have the case where the location could either be
-      // null or not-null.  Record the error node as an "implicit" null
-      // dereference.
-      if (ExplodedNode *N = C.generateSink(nullState)) {
-        ImplicitNullDerefEvent event = { l, isLoad, N, &C.getBugReporter() };
-        dispatchEvent(event);
-      }
+
+    // Otherwise, we have the case where the location could either be
+    // null or not-null.  Record the error node as an "implicit" null
+    // dereference.
+    if (ExplodedNode *N = C.generateSink(nullState)) {
+      ImplicitNullDerefEvent event = { l, isLoad, N, &C.getBugReporter() };
+      dispatchEvent(event);
     }
   }
 
@@ -212,6 +231,59 @@
   C.addTransition(notNullState);
 }
 
+void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S,
+                                   CheckerContext &C) const {
+  // If we're binding to a reference, check if the value is known to be null.
+  if (V.isUndef())
+    return;
+
+  const MemRegion *MR = L.getAsRegion();
+  const TypedValueRegion *TVR = dyn_cast_or_null<TypedValueRegion>(MR);
+  if (!TVR)
+    return;
+
+  if (!TVR->getValueType()->isReferenceType())
+    return;
+
+  ProgramStateRef State = C.getState();
+
+  ProgramStateRef StNonNull, StNull;
+  llvm::tie(StNonNull, StNull) = State->assume(cast<DefinedOrUnknownSVal>(V));
+
+  if (StNull) {
+    if (!StNonNull) {
+      reportBug(StNull, S, C, /*isBind=*/true);
+      return;
+    }
+
+    // At this point the value could be either null or non-null.
+    // Record this as an "implicit" null dereference.
+    if (ExplodedNode *N = C.generateSink(StNull)) {
+      ImplicitNullDerefEvent event = { V, /*isLoad=*/true, N,
+                                       &C.getBugReporter() };
+      dispatchEvent(event);
+    }
+  }
+
+  // Unlike a regular null dereference, initializing a reference with a
+  // dereferenced null pointer does not actually cause a runtime exception in
+  // Clang's implementation of references.
+  //
+  //   int &r = *p; // safe??
+  //   if (p != NULL) return; // uh-oh
+  //   r = 5; // trap here
+  //
+  // The standard says this is invalid as soon as we try to create a "null
+  // reference" (there is no such thing), but turning this into an assumption
+  // that 'p' is never null will not match our actual runtime behavior.
+  // So we do not record this assumption, allowing us to warn on the last line
+  // of this example.
+  //
+  // We do need to add a transition because we may have generated a sink for
+  // the "implicit" null dereference.
+  C.addTransition(State, this);
+}
+
 void ento::registerDereferenceChecker(CheckerManager &mgr) {
   mgr.registerChecker<DereferenceChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
index 5094a03..dcf6a86 100644
--- a/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp
@@ -42,8 +42,9 @@
     BugReport *R =
       new BugReport(*BT, Msg, N);
 
-    R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                 bugreporter::GetDenomExpr(N), R));
+    bugreporter::addTrackNullOrUndefValueVisitor(N,
+                                                 bugreporter::GetDenomExpr(N),
+                                                 R);
     C.EmitReport(R);
   }
 }
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
new file mode 100644
index 0000000..b636efb
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -0,0 +1,264 @@
+//== DynamicTypePropagation.cpp ----------------------------------- -*- C++ -*--=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker defines the rules for dynamic type gathering and propagation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/Basic/Builtins.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class DynamicTypePropagation:
+    public Checker< check::PreCall,
+                    check::PostCall,
+                    check::PostStmt<ImplicitCastExpr> > {
+  const ObjCObjectType *getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE,
+                                                    CheckerContext &C) const;
+
+  /// \brief Return a better dynamic type if one can be derived from the cast.
+  const ObjCObjectPointerType *getBetterObjCType(const Expr *CastE,
+                                                 CheckerContext &C) const;
+public:
+  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
+  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
+  void checkPostStmt(const ImplicitCastExpr *CastE, CheckerContext &C) const;
+};
+}
+
+static void recordFixedType(const MemRegion *Region, const CXXMethodDecl *MD,
+                            CheckerContext &C) {
+  assert(Region);
+  assert(MD);
+
+  ASTContext &Ctx = C.getASTContext();
+  QualType Ty = Ctx.getPointerType(Ctx.getRecordType(MD->getParent()));
+
+  ProgramStateRef State = C.getState();
+  State = State->setDynamicTypeInfo(Region, Ty, /*CanBeSubclass=*/false);
+  C.addTransition(State);
+  return;
+}
+
+void DynamicTypePropagation::checkPreCall(const CallEvent &Call,
+                                          CheckerContext &C) const {
+  if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
+    // C++11 [class.cdtor]p4: When a virtual function is called directly or
+    //   indirectly from a constructor or from a destructor, including during
+    //   the construction or destruction of the class’s non-static data members,
+    //   and the object to which the call applies is the object under
+    //   construction or destruction, the function called is the final overrider
+    //   in the constructor's or destructor's class and not one overriding it in
+    //   a more-derived class.
+
+    switch (Ctor->getOriginExpr()->getConstructionKind()) {
+    case CXXConstructExpr::CK_Complete:
+    case CXXConstructExpr::CK_Delegating:
+      // No additional type info necessary.
+      return;
+    case CXXConstructExpr::CK_NonVirtualBase:
+    case CXXConstructExpr::CK_VirtualBase:
+      if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion())
+        recordFixedType(Target, Ctor->getDecl(), C);
+      return;
+    }
+
+    return;
+  }
+
+  if (const CXXDestructorCall *Dtor = dyn_cast<CXXDestructorCall>(&Call)) {
+    // C++11 [class.cdtor]p4 (see above)
+
+    const MemRegion *Target = Dtor->getCXXThisVal().getAsRegion();
+    if (!Target)
+      return;
+
+    // FIXME: getRuntimeDefinition() can be expensive. It would be better to do
+    // this when we are entering the stack frame for the destructor.
+    const Decl *D = Dtor->getRuntimeDefinition().getDecl();
+    if (!D)
+      return;
+
+    recordFixedType(Target, cast<CXXDestructorDecl>(D), C);
+    return;
+  }
+}
+
+void DynamicTypePropagation::checkPostCall(const CallEvent &Call,
+                                           CheckerContext &C) const {
+  // We can obtain perfect type info for return values from some calls.
+  if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(&Call)) {
+
+    // Get the returned value if it's a region.
+    SVal Result = C.getSVal(Call.getOriginExpr());
+    const MemRegion *RetReg = Result.getAsRegion();
+    if (!RetReg)
+      return;
+
+    ProgramStateRef State = C.getState();
+
+    switch (Msg->getMethodFamily()) {
+    default:
+      break;
+
+    // We assume that the type of the object returned by alloc and new are the
+    // pointer to the object of the class specified in the receiver of the
+    // message.
+    case OMF_alloc:
+    case OMF_new: {
+      // Get the type of object that will get created.
+      const ObjCMessageExpr *MsgE = Msg->getOriginExpr();
+      const ObjCObjectType *ObjTy = getObjectTypeForAllocAndNew(MsgE, C);
+      if (!ObjTy)
+        return;
+      QualType DynResTy =
+                 C.getASTContext().getObjCObjectPointerType(QualType(ObjTy, 0));
+      C.addTransition(State->setDynamicTypeInfo(RetReg, DynResTy, false));
+      break;
+    }
+    case OMF_init: {
+      // Assume, the result of the init method has the same dynamic type as
+      // the receiver and propagate the dynamic type info.
+      const MemRegion *RecReg = Msg->getReceiverSVal().getAsRegion();
+      if (!RecReg)
+        return;
+      DynamicTypeInfo RecDynType = State->getDynamicTypeInfo(RecReg);
+      C.addTransition(State->setDynamicTypeInfo(RetReg, RecDynType));
+      break;
+    }
+    }
+
+    return;
+  }
+
+  if (const CXXConstructorCall *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
+    // We may need to undo the effects of our pre-call check.
+    switch (Ctor->getOriginExpr()->getConstructionKind()) {
+    case CXXConstructExpr::CK_Complete:
+    case CXXConstructExpr::CK_Delegating:
+      // No additional work necessary.
+      // Note: This will leave behind the actual type of the object for
+      // complete constructors, but arguably that's a good thing, since it
+      // means the dynamic type info will be correct even for objects
+      // constructed with operator new.
+      return;
+    case CXXConstructExpr::CK_NonVirtualBase:
+    case CXXConstructExpr::CK_VirtualBase:
+      if (const MemRegion *Target = Ctor->getCXXThisVal().getAsRegion()) {
+        // We just finished a base constructor. Now we can use the subclass's
+        // type when resolving virtual calls.
+        const Decl *D = C.getLocationContext()->getDecl();
+        recordFixedType(Target, cast<CXXConstructorDecl>(D), C);
+      }
+      return;
+    }
+  }
+}
+
+void DynamicTypePropagation::checkPostStmt(const ImplicitCastExpr *CastE,
+                                           CheckerContext &C) const {
+  // We only track dynamic type info for regions.
+  const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
+  if (!ToR)
+    return;
+
+  switch (CastE->getCastKind()) {
+  default:
+    break;
+  case CK_BitCast:
+    // Only handle ObjCObjects for now.
+    if (const Type *NewTy = getBetterObjCType(CastE, C))
+      C.addTransition(C.getState()->setDynamicTypeInfo(ToR, QualType(NewTy,0)));
+    break;
+  }
+  return;
+}
+
+const ObjCObjectType *
+DynamicTypePropagation::getObjectTypeForAllocAndNew(const ObjCMessageExpr *MsgE,
+                                                    CheckerContext &C) const {
+  if (MsgE->getReceiverKind() == ObjCMessageExpr::Class) {
+    if (const ObjCObjectType *ObjTy
+          = MsgE->getClassReceiver()->getAs<ObjCObjectType>())
+    return ObjTy;
+  }
+
+  if (MsgE->getReceiverKind() == ObjCMessageExpr::SuperClass) {
+    if (const ObjCObjectType *ObjTy
+          = MsgE->getSuperType()->getAs<ObjCObjectType>())
+      return ObjTy;
+  }
+
+  const Expr *RecE = MsgE->getInstanceReceiver();
+  if (!RecE)
+    return 0;
+
+  RecE= RecE->IgnoreParenImpCasts();
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(RecE)) {
+    const StackFrameContext *SFCtx = C.getStackFrame();
+    // Are we calling [self alloc]? If this is self, get the type of the
+    // enclosing ObjC class.
+    if (DRE->getDecl() == SFCtx->getSelfDecl()) {
+      if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(SFCtx->getDecl()))
+        if (const ObjCObjectType *ObjTy =
+            dyn_cast<ObjCObjectType>(MD->getClassInterface()->getTypeForDecl()))
+          return ObjTy;
+    }
+  }
+  return 0;
+}
+
+// Return a better dynamic type if one can be derived from the cast.
+// Compare the current dynamic type of the region and the new type to which we
+// are casting. If the new type is lower in the inheritance hierarchy, pick it.
+const ObjCObjectPointerType *
+DynamicTypePropagation::getBetterObjCType(const Expr *CastE,
+                                          CheckerContext &C) const {
+  const MemRegion *ToR = C.getSVal(CastE).getAsRegion();
+  assert(ToR);
+
+  // Get the old and new types.
+  const ObjCObjectPointerType *NewTy =
+      CastE->getType()->getAs<ObjCObjectPointerType>();
+  if (!NewTy)
+    return 0;
+  QualType OldDTy = C.getState()->getDynamicTypeInfo(ToR).getType();
+  if (OldDTy.isNull()) {
+    return NewTy;
+  }
+  const ObjCObjectPointerType *OldTy =
+    OldDTy->getAs<ObjCObjectPointerType>();
+  if (!OldTy)
+    return 0;
+
+  // Id the old type is 'id', the new one is more precise.
+  if (OldTy->isObjCIdType() && !NewTy->isObjCIdType())
+    return NewTy;
+
+  // Return new if it's a subclass of old.
+  const ObjCInterfaceDecl *ToI = NewTy->getInterfaceDecl();
+  const ObjCInterfaceDecl *FromI = OldTy->getInterfaceDecl();
+  if (ToI && FromI && FromI->isSuperClassOf(ToI))
+    return NewTy;
+
+  return 0;
+}
+
+void ento::registerDynamicTypePropagation(CheckerManager &mgr) {
+  mgr.registerChecker<DynamicTypePropagation>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index f638dda..7acf223 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -18,65 +18,102 @@
 namespace {
 class ExprInspectionChecker : public Checker< eval::Call > {
   mutable OwningPtr<BugType> BT;
+
+  void analyzerEval(const CallExpr *CE, CheckerContext &C) const;
+  void analyzerCheckInlined(const CallExpr *CE, CheckerContext &C) const;
+
+  typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
+                                                 CheckerContext &C) const;
+
 public:
   bool evalCall(const CallExpr *CE, CheckerContext &C) const;
 };
 }
 
 bool ExprInspectionChecker::evalCall(const CallExpr *CE,
-                                       CheckerContext &C) const {
+                                     CheckerContext &C) const {
   // These checks should have no effect on the surrounding environment
-  // (globals should not be evaluated, etc), hence the use of evalCall.
+  // (globals should not be invalidated, etc), hence the use of evalCall.
+  FnCheck Handler = llvm::StringSwitch<FnCheck>(C.getCalleeName(CE))
+    .Case("clang_analyzer_eval", &ExprInspectionChecker::analyzerEval)
+    .Case("clang_analyzer_checkInlined",
+          &ExprInspectionChecker::analyzerCheckInlined)
+    .Default(0);
+
+  if (!Handler)
+    return false;
+
+  (this->*Handler)(CE, C);
+  return true;
+}
+
+static const char *getArgumentValueString(const CallExpr *CE,
+                                          CheckerContext &C) {
+  if (CE->getNumArgs() == 0)
+    return "Missing assertion argument";
+
+  ExplodedNode *N = C.getPredecessor();
+  const LocationContext *LC = N->getLocationContext();
+  ProgramStateRef State = N->getState();
+
+  const Expr *Assertion = CE->getArg(0);
+  SVal AssertionVal = State->getSVal(Assertion, LC);
+
+  if (AssertionVal.isUndef())
+    return "UNDEFINED";
+
+  ProgramStateRef StTrue, StFalse;
+  llvm::tie(StTrue, StFalse) =
+    State->assume(cast<DefinedOrUnknownSVal>(AssertionVal));
+
+  if (StTrue) {
+    if (StFalse)
+      return "UNKNOWN";
+    else
+      return "TRUE";
+  } else {
+    if (StFalse)
+      return "FALSE";
+    else
+      llvm_unreachable("Invalid constraint; neither true or false.");
+  }
+}
+
+void ExprInspectionChecker::analyzerEval(const CallExpr *CE,
+                                         CheckerContext &C) const {
   ExplodedNode *N = C.getPredecessor();
   const LocationContext *LC = N->getLocationContext();
 
-  if (!C.getCalleeName(CE).equals("clang_analyzer_eval"))
-    return false;
-
   // A specific instantiation of an inlined function may have more constrained
   // values than can generally be assumed. Skip the check.
-  if (LC->getParent() != 0)
-    return true;
-
-  const char *Msg = 0;
-
-  if (CE->getNumArgs() == 0)
-    Msg = "Missing assertion argument";
-  else {
-    ProgramStateRef State = N->getState();
-    const Expr *Assertion = CE->getArg(0);
-    SVal AssertionVal = State->getSVal(Assertion, LC);
-
-    if (AssertionVal.isUndef())
-      Msg = "UNDEFINED";
-    else {
-      ProgramStateRef StTrue, StFalse;
-      llvm::tie(StTrue, StFalse) =
-        State->assume(cast<DefinedOrUnknownSVal>(AssertionVal));
-
-      if (StTrue) {
-        if (StFalse)
-          Msg = "UNKNOWN";
-        else
-          Msg = "TRUE";
-      } else {
-        if (StFalse)
-          Msg = "FALSE";
-        else
-          llvm_unreachable("Invalid constraint; neither true or false.");
-      }      
-    }
-  }
-
-  assert(Msg);
+  if (LC->getCurrentStackFrame()->getParent() != 0)
+    return;
 
   if (!BT)
     BT.reset(new BugType("Checking analyzer assumptions", "debug"));
 
-  BugReport *R = new BugReport(*BT, Msg, N);
+  BugReport *R = new BugReport(*BT, getArgumentValueString(CE, C), N);
   C.EmitReport(R);
+}
 
-  return true;
+void ExprInspectionChecker::analyzerCheckInlined(const CallExpr *CE,
+                                                 CheckerContext &C) const {
+  ExplodedNode *N = C.getPredecessor();
+  const LocationContext *LC = N->getLocationContext();
+
+  // An inlined function could conceivably also be analyzed as a top-level
+  // function. We ignore this case and only emit a message (TRUE or FALSE)
+  // when we are analyzing it as an inlined function. This means that
+  // clang_analyzer_checkInlined(true) should always print TRUE, but
+  // clang_analyzer_checkInlined(false) should never actually print anything.
+  if (LC->getCurrentStackFrame()->getParent() == 0)
+    return;
+
+  if (!BT)
+    BT.reset(new BugType("Checking analyzer assumptions", "debug"));
+
+  BugReport *R = new BugReport(*BT, getArgumentValueString(CE, C), N);
+  C.EmitReport(R);
 }
 
 void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
diff --git a/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp b/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
deleted file mode 100644
index b0bac33..0000000
--- a/lib/StaticAnalyzer/Checkers/IteratorsChecker.cpp
+++ /dev/null
@@ -1,603 +0,0 @@
-//=== IteratorsChecker.cpp - Check for Invalidated Iterators ------*- C++ -*----
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This defines IteratorsChecker, a number of small checks for conditions
-// leading to invalid iterators being used.
-// FIXME: Currently only supports 'vector' and 'deque'
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/AST/DeclTemplate.h"
-#include "clang/Basic/SourceManager.h"
-#include "ClangSACheckers.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringSwitch.h"
-
-
-using namespace clang;
-using namespace ento;
-
-// This is the state associated with each iterator which includes both the
-// kind of state and the instance used to initialize it.
-// FIXME: add location where invalidated for better error reporting.
-namespace {
-class RefState {
-  enum Kind { BeginValid, EndValid, Invalid, Undefined, Unknown } K;
-  const void *VR;
-
-public:
-  RefState(Kind k, const void *vr) : K(k), VR(vr) {}
-
-  bool isValid() const { return K == BeginValid || K == EndValid; }
-  bool isInvalid() const { return K == Invalid; }
-  bool isUndefined() const { return K == Undefined; }
-  bool isUnknown() const { return K == Unknown; }
-  const MemRegion *getMemRegion() const {
-    if (K == BeginValid || K == EndValid)
-      return(const MemRegion *)VR;
-    return 0;
-  }
-  const MemberExpr *getMemberExpr() const {
-    if (K == Invalid)
-      return(const MemberExpr *)VR;
-    return 0;
-  }
-
-  bool operator==(const RefState &X) const {
-    return K == X.K && VR == X.VR;
-  }
-
-  static RefState getBeginValid(const MemRegion *vr) {
-    assert(vr);
-    return RefState(BeginValid, vr);
-  }
-  static RefState getEndValid(const MemRegion *vr) {
-    assert(vr);
-    return RefState(EndValid, vr);
-  }
-  static RefState getInvalid( const MemberExpr *ME ) {
-    return RefState(Invalid, ME);
-  }
-  static RefState getUndefined( void ) {
-    return RefState(Undefined, 0);
-  }
-  static RefState getUnknown( void ) {
-    return RefState(Unknown, 0);
-  }
-
-  void Profile(llvm::FoldingSetNodeID &ID) const {
-    ID.AddInteger(K);
-    ID.AddPointer(VR);
-  }
-};
-
-enum RefKind { NoKind, VectorKind, VectorIteratorKind };
-
-class IteratorsChecker : 
-    public Checker<check::PreStmt<CXXOperatorCallExpr>,
-                   check::PreStmt<DeclStmt>,
-                   check::PreStmt<CXXMemberCallExpr>,
-                   check::PreStmt<CallExpr> >
-  {
-  // Used when parsing iterators and vectors and deques.
-  BuiltinBug *BT_Invalid, *BT_Undefined, *BT_Incompatible;
-
-public:
-  IteratorsChecker() :
-    BT_Invalid(0), BT_Undefined(0), BT_Incompatible(0)
-  {}
-  static void *getTag() { static int tag; return &tag; }
-    
-  // Checker entry points.
-  void checkPreStmt(const CXXOperatorCallExpr *OCE,
-                    CheckerContext &C) const;
-
-  void checkPreStmt(const DeclStmt *DS,
-                    CheckerContext &C) const;
-
-  void checkPreStmt(const CXXMemberCallExpr *MCE,
-                    CheckerContext &C) const;
-
-  void checkPreStmt(const CallExpr *CE,
-                    CheckerContext &C) const;
-
-private:
-  ProgramStateRef handleAssign(ProgramStateRef state,
-                                   const Expr *lexp,
-                                   const Expr *rexp,
-                                   const LocationContext *LC) const;
-
-  ProgramStateRef handleAssign(ProgramStateRef state,
-                                   const MemRegion *MR,
-                                   const Expr *rexp,
-                                   const LocationContext *LC) const;
-
-  ProgramStateRef invalidateIterators(ProgramStateRef state,
-                                          const MemRegion *MR,
-                                          const MemberExpr *ME) const;
-
-  void checkExpr(CheckerContext &C, const Expr *E) const;
-
-  void checkArgs(CheckerContext &C, const CallExpr *CE) const;
-
-  const MemRegion *getRegion(ProgramStateRef state,
-                             const Expr *E,
-                             const LocationContext *LC) const;
-
-  const DeclRefExpr *getDeclRefExpr(const Expr *E) const;
-};
-
-class IteratorState {
-public:
-  typedef llvm::ImmutableMap<const MemRegion *, RefState> EntryMap;
-};
-} //end anonymous namespace
-
-namespace clang {
-  namespace ento {
-    template <>
-    struct ProgramStateTrait<IteratorState> 
-      : public ProgramStatePartialTrait<IteratorState::EntryMap> {
-      static void *GDMIndex() { return IteratorsChecker::getTag(); }
-    };
-  }
-}
-
-void ento::registerIteratorsChecker(CheckerManager &mgr) {
-  mgr.registerChecker<IteratorsChecker>();
-}
-
-// ===============================================
-// Utility functions used by visitor functions
-// ===============================================
-
-// check a templated type for std::vector or std::deque
-static RefKind getTemplateKind(const NamedDecl *td) {
-  const DeclContext *dc = td->getDeclContext();
-  const NamespaceDecl *nameSpace = dyn_cast<NamespaceDecl>(dc);
-  if (!nameSpace || !isa<TranslationUnitDecl>(nameSpace->getDeclContext())
-      || nameSpace->getName() != "std")
-    return NoKind;
-  
-  StringRef name = td->getName();
-  return llvm::StringSwitch<RefKind>(name)
-    .Cases("vector", "deque", VectorKind)
-    .Default(NoKind);
-}
-
-static RefKind getTemplateKind(const DeclContext *dc) {
-  if (const ClassTemplateSpecializationDecl *td =
-      dyn_cast<ClassTemplateSpecializationDecl>(dc))
-    return getTemplateKind(cast<NamedDecl>(td));
-  return NoKind;
-}
-
-static RefKind getTemplateKind(const TypedefType *tdt) {
-  const TypedefNameDecl *td = tdt->getDecl();
-  RefKind parentKind = getTemplateKind(td->getDeclContext());
-  if (parentKind == VectorKind) {
-    return llvm::StringSwitch<RefKind>(td->getName())
-    .Cases("iterator",
-           "const_iterator",
-           "reverse_iterator", VectorIteratorKind)
-    .Default(NoKind);
-  }
-  return NoKind;
-}
-
-static RefKind getTemplateKind(const TemplateSpecializationType *tsp) {
-  const TemplateName &tname = tsp->getTemplateName();
-  TemplateDecl *td = tname.getAsTemplateDecl();
-  if (!td)
-    return NoKind;
-  return getTemplateKind(td);
-}
-
-static RefKind getTemplateKind(QualType T) {
-  if (const TemplateSpecializationType *tsp = 
-      T->getAs<TemplateSpecializationType>()) {
-    return getTemplateKind(tsp);      
-  }
-  if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) {
-    QualType namedType = ET->getNamedType();
-    if (const TypedefType *tdt = namedType->getAs<TypedefType>()) 
-      return getTemplateKind(tdt);
-    if (const TemplateSpecializationType *tsp = 
-        namedType->getAs<TemplateSpecializationType>()) {
-      return getTemplateKind(tsp);      
-    }
-  }
-  return NoKind;  
-}
-
-// Iterate through our map and invalidate any iterators that were
-// initialized fromt the specified instance MemRegion.
-ProgramStateRef IteratorsChecker::invalidateIterators(ProgramStateRef state,
-                          const MemRegion *MR, const MemberExpr *ME) const {
-  IteratorState::EntryMap Map = state->get<IteratorState>();
-  if (Map.isEmpty())
-    return state;
-
-  // Loop over the entries in the current state.
-  // The key doesn't change, so the map iterators won't change.
-  for (IteratorState::EntryMap::iterator I = Map.begin(), E = Map.end();
-                                                            I != E; ++I) {
-    RefState RS = I.getData();
-    if (RS.getMemRegion() == MR)
-      state = state->set<IteratorState>(I.getKey(), RefState::getInvalid(ME));
-  }
-
-  return state;
-}
-
-// Handle assigning to an iterator where we don't have the LValue MemRegion.
-ProgramStateRef IteratorsChecker::handleAssign(ProgramStateRef state,
-    const Expr *lexp, const Expr *rexp, const LocationContext *LC) const {
-  // Skip the cast if present.
-  if (const MaterializeTemporaryExpr *M 
-                                    = dyn_cast<MaterializeTemporaryExpr>(lexp))
-    lexp = M->GetTemporaryExpr();
-  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(lexp))
-    lexp = ICE->getSubExpr();
-  SVal sv = state->getSVal(lexp, LC);
-  const MemRegion *MR = sv.getAsRegion();
-  if (!MR)
-    return state;
-  RefKind kind = getTemplateKind(lexp->getType());
-
-  // If assigning to a vector, invalidate any iterators currently associated.
-  if (kind == VectorKind)
-    return invalidateIterators(state, MR, 0);
-
-  // Make sure that we are assigning to an iterator.
-  if (getTemplateKind(lexp->getType()) != VectorIteratorKind)
-    return state;
-  return handleAssign(state, MR, rexp, LC);
-}
-
-// handle assigning to an iterator
-ProgramStateRef IteratorsChecker::handleAssign(ProgramStateRef state,
-    const MemRegion *MR, const Expr *rexp, const LocationContext *LC) const {
-  // Assume unknown until we find something definite.
-  state = state->set<IteratorState>(MR, RefState::getUnknown());
-  if (const MaterializeTemporaryExpr *M 
-                                    = dyn_cast<MaterializeTemporaryExpr>(rexp))
-    rexp = M->GetTemporaryExpr();
-  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(rexp))
-    rexp = ICE->getSubExpr();
-  // Need to handle three cases: MemberCall, copy, copy with addition.
-  if (const CallExpr *CE = dyn_cast<CallExpr>(rexp)) {
-    // Handle MemberCall.
-    if (const MemberExpr *ME = dyn_cast<MemberExpr>(CE->getCallee())) {
-      const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ME->getBase());
-      if (!DRE)
-        return state;
-      // Verify that the type is std::vector<T>.
-      if (getTemplateKind(DRE->getType()) != VectorKind)
-          return state;
-      // Now get the MemRegion associated with the instance.
-      const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
-      if (!VD)
-        return state;
-      const MemRegion *IMR = state->getRegion(VD, LC);
-      if (!IMR)
-        return state;
-      // Finally, see if it is one of the calls that will create
-      // a valid iterator and mark it if so, else mark as Unknown.
-      StringRef mName = ME->getMemberDecl()->getName();
-      
-      if (llvm::StringSwitch<bool>(mName)        
-          .Cases("begin", "insert", "erase", true).Default(false)) {
-        return state->set<IteratorState>(MR, RefState::getBeginValid(IMR));
-      }
-      if (mName == "end")
-        return state->set<IteratorState>(MR, RefState::getEndValid(IMR));
-
-      return state->set<IteratorState>(MR, RefState::getUnknown());
-    }
-  }
-  // Handle straight copy from another iterator.
-  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(rexp)) {
-    if (getTemplateKind(DRE->getType()) != VectorIteratorKind)
-      return state;
-    // Now get the MemRegion associated with the instance.
-    const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
-    if (!VD)
-      return state;
-    const MemRegion *IMR = state->getRegion(VD, LC);
-    if (!IMR)
-      return state;
-    // Get the RefState of the iterator being copied.
-    const RefState *RS = state->get<IteratorState>(IMR);
-    if (!RS)
-      return state;
-    // Use it to set the state of the LValue.
-    return state->set<IteratorState>(MR, *RS);
-  }
-  // If we have operator+ or operator- ...
-  if (const CXXOperatorCallExpr *OCE = dyn_cast<CXXOperatorCallExpr>(rexp)) {
-    OverloadedOperatorKind Kind = OCE->getOperator();
-    if (Kind == OO_Plus || Kind == OO_Minus) {
-      // Check left side of tree for a valid value.
-      state = handleAssign( state, MR, OCE->getArg(0), LC);
-      const RefState *RS = state->get<IteratorState>(MR);
-      // If found, return it.
-      if (!RS->isUnknown())
-        return state;
-      // Otherwise return what we find in the right side.
-      return handleAssign(state, MR, OCE->getArg(1), LC);
-    }
-  }
-  // Fall through if nothing matched.
-  return state;
-}
-
-// Iterate through the arguments looking for an Invalid or Undefined iterator.
-void IteratorsChecker::checkArgs(CheckerContext &C, const CallExpr *CE) const {
-  for (CallExpr::const_arg_iterator I = CE->arg_begin(), E = CE->arg_end();
-       I != E; ++I) {
-    checkExpr(C, *I);
-  }
-}
-
-// Get the DeclRefExpr associated with the expression.
-const DeclRefExpr *IteratorsChecker::getDeclRefExpr(const Expr *E) const {
-  // If it is a CXXConstructExpr, need to get the subexpression.
-  if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) {
-    if (CE->getNumArgs()== 1) {
-      CXXConstructorDecl *CD = CE->getConstructor();
-      if (CD->isTrivial())
-        E = CE->getArg(0);
-    }
-  }
-  if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E))
-    E = M->GetTemporaryExpr();
-  if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
-    E = ICE->getSubExpr();
-  // If it isn't one of our types, don't do anything.
-  if (getTemplateKind(E->getType()) != VectorIteratorKind)
-    return NULL;
-  return dyn_cast<DeclRefExpr>(E);
-}
-
-// Get the MemRegion associated with the expresssion.
-const MemRegion *IteratorsChecker::getRegion(ProgramStateRef state,
-    const Expr *E, const LocationContext *LC) const {
-  const DeclRefExpr *DRE = getDeclRefExpr(E);
-  if (!DRE)
-    return NULL;
-  const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
-  if (!VD)
-    return NULL;
-  // return the MemRegion associated with the iterator
-  return state->getRegion(VD, LC);
-}
-
-// Check the expression and if it is an iterator, generate a diagnostic
-// if the iterator is not valid.
-// FIXME: this method can generate new nodes, and subsequent logic should
-// use those nodes.  We also cannot create multiple nodes at one ProgramPoint
-// with the same tag.
-void IteratorsChecker::checkExpr(CheckerContext &C, const Expr *E) const {
-  ProgramStateRef state = C.getState();
-  const MemRegion *MR = getRegion(state, E, C.getLocationContext());
-  if (!MR)
-    return;
-
-  // Get the state associated with the iterator.
-  const RefState *RS = state->get<IteratorState>(MR);
-  if (!RS)
-    return;
-  if (RS->isInvalid()) {
-    if (ExplodedNode *N = C.addTransition()) {
-      if (!BT_Invalid)
-        // FIXME: We are eluding constness here.
-        const_cast<IteratorsChecker*>(this)->BT_Invalid = new BuiltinBug("");
-
-      std::string msg;
-      const MemberExpr *ME = RS->getMemberExpr();
-      if (ME) {
-        std::string name = ME->getMemberNameInfo().getAsString();
-        msg = "Attempt to use an iterator made invalid by call to '" +
-                                                                  name + "'";
-      }
-      else {
-        msg = "Attempt to use an iterator made invalid by copying another "
-                    "container to its container";
-      }
-
-      BugReport *R = new BugReport(*BT_Invalid, msg, N);
-      R->addRange(getDeclRefExpr(E)->getSourceRange());
-      C.EmitReport(R);
-    }
-  }
-  else if (RS->isUndefined()) {
-    if (ExplodedNode *N = C.addTransition()) {
-      if (!BT_Undefined)
-        // FIXME: We are eluding constness here.
-        const_cast<IteratorsChecker*>(this)->BT_Undefined =
-          new BuiltinBug("Use of iterator that is not defined");
-
-      BugReport *R = new BugReport(*BT_Undefined,
-                                           BT_Undefined->getDescription(), N);
-      R->addRange(getDeclRefExpr(E)->getSourceRange());
-      C.EmitReport(R);
-    }
-  }
-}
-
-// ===============================================
-// Path analysis visitor functions
-// ===============================================
-
-// For a generic Call, just check the args for bad iterators.
-void IteratorsChecker::checkPreStmt(const CallExpr *CE,
-                                    CheckerContext &C) const{
-  
-  // FIXME: These checks are to currently work around a bug
-  // in CheckerManager.
-  if (isa<CXXOperatorCallExpr>(CE))
-    return;
-  if (isa<CXXMemberCallExpr>(CE))
-    return;
-
-  checkArgs(C, CE);
-}
-
-// Handle operator calls. First, if it is operator=, check the argument,
-// and handle assigning and set target state appropriately. Otherwise, for
-// other operators, check the args for bad iterators and handle comparisons.
-void IteratorsChecker::checkPreStmt(const CXXOperatorCallExpr *OCE,
-                                    CheckerContext &C) const
-{
-  const LocationContext *LC = C.getLocationContext();
-  ProgramStateRef state = C.getState();
-  OverloadedOperatorKind Kind = OCE->getOperator();
-  if (Kind == OO_Equal) {
-    checkExpr(C, OCE->getArg(1));
-    state = handleAssign(state, OCE->getArg(0), OCE->getArg(1), LC);
-    C.addTransition(state);
-    return;
-  }
-  else {
-    checkArgs(C, OCE);
-    // If it is a compare and both are iterators, ensure that they are for
-    // the same container.
-    if (Kind == OO_EqualEqual || Kind == OO_ExclaimEqual ||
-        Kind == OO_Less || Kind == OO_LessEqual ||
-        Kind == OO_Greater || Kind == OO_GreaterEqual) {
-      const MemRegion *MR0, *MR1;
-      MR0 = getRegion(state, OCE->getArg(0), LC);
-      if (!MR0)
-        return;
-      MR1 = getRegion(state, OCE->getArg(1), LC);
-      if (!MR1)
-        return;
-      const RefState *RS0, *RS1;
-      RS0 = state->get<IteratorState>(MR0);
-      if (!RS0)
-        return;
-      RS1 = state->get<IteratorState>(MR1);
-      if (!RS1)
-        return;
-      if (RS0->getMemRegion() != RS1->getMemRegion()) {
-      if (ExplodedNode *N = C.addTransition()) {
-          if (!BT_Incompatible)
-            const_cast<IteratorsChecker*>(this)->BT_Incompatible =
-              new BuiltinBug(
-                      "Cannot compare iterators from different containers");
-
-          BugReport *R = new BugReport(*BT_Incompatible,
-                                        BT_Incompatible->getDescription(), N);
-          R->addRange(OCE->getSourceRange());
-          C.EmitReport(R);
-        }
-      }
-    }
-  }
-}
-
-// Need to handle DeclStmts to pick up initializing of iterators and to mark
-// uninitialized ones as Undefined.
-void IteratorsChecker::checkPreStmt(const DeclStmt *DS,
-                                    CheckerContext &C) const {
-  const Decl *D = *DS->decl_begin();
-  const VarDecl *VD = dyn_cast<VarDecl>(D);
-  // Only care about iterators.
-  if (getTemplateKind(VD->getType()) != VectorIteratorKind)
-    return;
-
-  // Get the MemRegion associated with the iterator and mark it as Undefined.
-  ProgramStateRef state = C.getState();
-  Loc VarLoc = state->getLValue(VD, C.getLocationContext());
-  const MemRegion *MR = VarLoc.getAsRegion();
-  if (!MR)
-    return;
-  state = state->set<IteratorState>(MR, RefState::getUndefined());
-
-  // if there is an initializer, handle marking Valid if a proper initializer
-  const Expr *InitEx = VD->getInit();
-  if (InitEx) {
-    // FIXME: This is too syntactic.  Since 'InitEx' will be analyzed first
-    // it should resolve to an SVal that we can check for validity
-    // *semantically* instead of walking through the AST.
-    if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(InitEx)) {
-      if (CE->getNumArgs() == 1) {
-        const Expr *E = CE->getArg(0);
-        if (const MaterializeTemporaryExpr *M
-                                        = dyn_cast<MaterializeTemporaryExpr>(E))
-          E = M->GetTemporaryExpr();
-        if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
-          InitEx = ICE->getSubExpr();
-        state = handleAssign(state, MR, InitEx, C.getLocationContext());
-      }
-    }
-  }
-  C.addTransition(state);
-}
-
-
-namespace { struct CalledReserved {}; }
-namespace clang { namespace ento {
-template<> struct ProgramStateTrait<CalledReserved> 
-    :  public ProgramStatePartialTrait<llvm::ImmutableSet<const MemRegion*> > {
-  static void *GDMIndex() { static int index = 0; return &index; }
-};
-}}
-
-// on a member call, first check the args for any bad iterators
-// then, check to see if it is a call to a function that will invalidate
-// the iterators
-void IteratorsChecker::checkPreStmt(const CXXMemberCallExpr *MCE,
-                                    CheckerContext &C) const {
-  // Check the arguments.
-  checkArgs(C, MCE);
-  const MemberExpr *ME = dyn_cast<MemberExpr>(MCE->getCallee());
-  if (!ME)
-    return;
-  // Make sure we have the right kind of container.
-  const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ME->getBase());
-  if (!DRE || getTemplateKind(DRE->getType()) != VectorKind)
-    return;
-  SVal tsv = C.getState()->getSVal(DRE, C.getLocationContext());
-  // Get the MemRegion associated with the container instance.
-  const MemRegion *MR = tsv.getAsRegion();
-  if (!MR)
-    return;
-  // If we are calling a function that invalidates iterators, mark them
-  // appropriately by finding matching instances.
-  ProgramStateRef state = C.getState();
-  StringRef mName = ME->getMemberDecl()->getName();
-  if (llvm::StringSwitch<bool>(mName)
-      .Cases("insert", "reserve", "push_back", true)
-      .Cases("erase", "pop_back", "clear", "resize", true)
-      .Default(false)) {
-    // If there was a 'reserve' call, assume iterators are good.
-    if (!state->contains<CalledReserved>(MR))
-      state = invalidateIterators(state, MR, ME);
-  }
-  // Keep track of instances that have called 'reserve'
-  // note: do this after we invalidate any iterators by calling 
-  // 'reserve' itself.
-  if (mName == "reserve")
-    state = state->add<CalledReserved>(MR);
-  
-  if (state != C.getState())
-    C.addTransition(state);
-}
-
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 1f8ec69..dfcedf6 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -18,7 +18,7 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
@@ -38,9 +38,6 @@
               Allocated,
               // Reference to released/freed memory.
               Released,
-              // Reference to escaped memory - no assumptions can be made of
-              // the state after the reference escapes.
-              Escaped,
               // The responsibility for freeing resources has transfered from
               // this reference. A relinquished symbol should not be freed.
               Relinquished } K;
@@ -63,7 +60,6 @@
     return RefState(Allocated, s);
   }
   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);
   }
@@ -194,7 +190,6 @@
   ///\brief Check if the memory associated with this symbol was released.
   bool isReleased(SymbolRef Sym, CheckerContext &C) const;
 
-  bool checkEscape(SymbolRef Sym, const Stmt *S, CheckerContext &C) const;
   bool checkUseAfterFree(SymbolRef Sym, CheckerContext &C,
                          const Stmt *S = 0) const;
 
@@ -679,14 +674,8 @@
   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 0;
-
   // Check double free.
-  if (RS->isReleased() || RS->isRelinquished()) {
+  if (RS && (RS->isReleased() || RS->isRelinquished())) {
     if (ExplodedNode *N = C.generateSink()) {
       if (!BT_DoubleFree)
         BT_DoubleFree.reset(
@@ -902,10 +891,8 @@
     if (ProgramStateRef stateFree = FreeMemAux(C, CE, StateSizeIsZero,0,false)){
       // The semantics of the return value are:
       // If size was equal to 0, either NULL or a pointer suitable to be passed
-      // to free() is returned.
-      stateFree = stateFree->set<ReallocPairs>(ToPtr,
-                                            ReallocPair(FromPtr, FreesOnFail));
-      C.getSymbolManager().addSymbolDependency(ToPtr, FromPtr);
+      // to free() is returned. We just free the input pointer and do not add
+      // any constrains on the output pointer.
       return stateFree;
     }
 
@@ -1008,10 +995,10 @@
   SmallString<200> buf;
   llvm::raw_svector_ostream os(buf);
   os << "Memory is never released; potential leak";
-  if (Region) {
+  if (Region && Region->canPrintPretty()) {
     os << " of memory pointed to by '";
-    Region->dumpPretty(os);
-    os <<'\'';
+    Region->printPretty(os);
+    os << '\'';
   }
 
   BugReport *R = new BugReport(*BT_Leak, os.str(), N, LocUsedForUniqueing);
@@ -1084,21 +1071,6 @@
   }
 }
 
-bool MallocChecker::checkEscape(SymbolRef Sym, const Stmt *S,
-                                CheckerContext &C) const {
-  ProgramStateRef state = C.getState();
-  const RefState *RS = state->get<RegionState>(Sym);
-  if (!RS)
-    return false;
-
-  if (RS->isAllocated()) {
-    state = state->set<RegionState>(Sym, RefState::getEscaped(S));
-    C.addTransition(state);
-    return true;
-  }
-  return false;
-}
-
 void MallocChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
   // We will check for double free in the post visit.
   if (isFreeFunction(C.getCalleeDecl(CE), C.getASTContext()))
@@ -1125,7 +1097,8 @@
     return;
 
   // Check if we are returning a symbol.
-  SVal RetVal = C.getState()->getSVal(E, C.getLocationContext());
+  ProgramStateRef State = C.getState();
+  SVal RetVal = State->getSVal(E, C.getLocationContext());
   SymbolRef Sym = RetVal.getAsSymbol();
   if (!Sym)
     // If we are returning a field of the allocated struct or an array element,
@@ -1136,16 +1109,18 @@
         if (const SymbolicRegion *BMR =
               dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
           Sym = BMR->getSymbol();
-  if (!Sym)
-    return;
 
   // Check if we are returning freed memory.
-  if (checkUseAfterFree(Sym, C, E))
-    return;
+  if (Sym)
+    if (checkUseAfterFree(Sym, C, E))
+      return;
 
-  // If this function body is not inlined, check if the symbol is escaping.
-  if (C.getLocationContext()->getParent() == 0)
-    checkEscape(Sym, E, C);
+  // If this function body is not inlined, stop tracking any returned symbols.
+  if (C.getLocationContext()->getParent() == 0) {
+    State =
+      State->scanReachableSymbols<StopTrackingCallback>(RetVal).getState();
+    C.addTransition(State);
+  }
 }
 
 // TODO: Blocks should be either inlined or should call invalidate regions
@@ -1253,12 +1228,6 @@
       if (StoredVal != val)
         escapes = (state == (state->bindLoc(*regionLoc, val)));
     }
-    if (!escapes) {
-      // Case 4: We do not currently model what happens when a symbol is
-      // assigned to a struct field, so be conservative here and let the symbol
-      // go. TODO: This could definitely be improved upon.
-      escapes = !isa<VarRegion>(regionLoc->getRegion());
-    }
   }
 
   // If our store can represent the binding and we aren't storing to something
@@ -1486,8 +1455,7 @@
     // relinquished symbols.
     if (const RefState *RS = State->get<RegionState>(sym)) {
       if (RS->isAllocated())
-        State = State->set<RegionState>(sym,
-                                        RefState::getEscaped(RS->getStmt()));
+        State = State->remove<RegionState>(sym);
     }
   }
   return State;
@@ -1518,7 +1486,7 @@
 
   const RefState *RS = state->get<RegionState>(Sym);
   const RefState *RSPrev = statePrev->get<RegionState>(Sym);
-  if (!RS && !RSPrev)
+  if (!RS)
     return 0;
 
   const Stmt *S = 0;
@@ -1577,11 +1545,6 @@
 
     // Is this is the first appearance of the reallocated symbol?
     if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
-      // If we ever hit this assert, that means BugReporter has decided to skip
-      // node pairs or visit them out of order.
-      assert(state->get<RegionState>(FailedReallocSymbol) &&
-        "Missed the reallocation point");
-
       // We're at the reallocation point.
       Msg = "Attempt to reallocate memory";
       StackHint = new StackHintGeneratorForSymbol(Sym,
diff --git a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
index bc0835a..aad3b0f 100644
--- a/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp
@@ -20,7 +20,7 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "clang/AST/DeclObjC.h"
diff --git a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index b3b212f..efb7072 100644
--- a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -15,7 +15,7 @@
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "llvm/ADT/StringSwitch.h"
 #include <cstdarg>
diff --git a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
index 7b724d2..81e4f0d 100644
--- a/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/OSAtomicChecker.cpp
@@ -192,8 +192,7 @@
         QualType T = CE->getType();
         if (!T->isVoidType())
           Res = Eng.getSValBuilder().makeTruthVal(true, T);
-        B.generateNode(CE, predNew, stateNew->BindExpr(CE, LCtx, Res),
-                       false, this);
+        B.generateNode(CE, predNew, stateNew->BindExpr(CE, LCtx, Res), this);
       }
     }
 
@@ -205,8 +204,7 @@
       if (!T->isVoidType())
         Res = Eng.getSValBuilder().makeTruthVal(false, CE->getType());
       StmtNodeBuilder B(N, Dst, Eng.getBuilderContext());    
-      B.generateNode(CE, N, stateNotEqual->BindExpr(CE, LCtx, Res),
-                     false, this);
+      B.generateNode(CE, N, stateNotEqual->BindExpr(CE, LCtx, Res), this);
     }
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
index 777e9ea..4cc92ce 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp
@@ -50,8 +50,7 @@
                                   "for @synchronized"));
       BugReport *report =
         new BugReport(*BT_undef, BT_undef->getDescription(), N);
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
-                                                                      report));
+      bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, report);
       C.EmitReport(report);
     }
     return;
@@ -74,8 +73,7 @@
                                    "(no synchronization will occur)"));
         BugReport *report =
           new BugReport(*BT_null, BT_null->getDescription(), N);
-        report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
-                                                                        report));
+        bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, report);
 
         C.EmitReport(report);
         return;
diff --git a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
index 2bd3e9a..be45da1 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp
@@ -39,7 +39,7 @@
 #include "ClangSACheckers.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 4fe66f2..73b6b61 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -23,7 +23,7 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
@@ -40,24 +40,6 @@
 using namespace ento;
 using llvm::StrInStrNoCase;
 
-namespace {
-/// Wrapper around different kinds of node builder, so that helper functions
-/// can have a common interface.
-class GenericNodeBuilderRefCount {
-  CheckerContext *C;
-  const ProgramPointTag *tag;
-public:
-  GenericNodeBuilderRefCount(CheckerContext &c,
-                             const ProgramPointTag *t = 0)
-  : C(&c), tag(t){}
-
-  ExplodedNode *MakeNode(ProgramStateRef state, ExplodedNode *Pred,
-                         bool MarkAsSink = false) {
-    return C->addTransition(state, Pred, tag, MarkAsSink);
-  }
-};
-} // end anonymous namespace
-
 //===----------------------------------------------------------------------===//
 // Primitives used for constructing summaries for function/method calls.
 //===----------------------------------------------------------------------===//
@@ -352,6 +334,20 @@
 }
 }
 
+static inline const RefVal *getRefBinding(ProgramStateRef State,
+                                          SymbolRef Sym) {
+  return State->get<RefBindings>(Sym);
+}
+
+static inline ProgramStateRef setRefBinding(ProgramStateRef State,
+                                            SymbolRef Sym, RefVal Val) {
+  return State->set<RefBindings>(Sym, Val);
+}
+
+static ProgramStateRef removeRefBinding(ProgramStateRef State, SymbolRef Sym) {
+  return State->remove<RefBindings>(Sym);
+}
+
 //===----------------------------------------------------------------------===//
 // Function/Method behavior summaries.
 //===----------------------------------------------------------------------===//
@@ -981,6 +977,7 @@
 
   // No summary?  Generate one.
   const RetainSummary *S = 0;
+  bool AllowAnnotations = true;
 
   do {
     // We generate "stop" summaries for implicitly defined functions.
@@ -1018,6 +1015,9 @@
       S = (RetTy->isObjCIdType())
           ? getUnarySummary(FT, cfmakecollectable)
           : getPersistentStopSummary();
+      // The headers on OS X 10.8 use cf_consumed/ns_returns_retained,
+      // but we can fully model NSMakeCollectable ourselves.
+      AllowAnnotations = false;
     } else if (FName == "IOBSDNameMatching" ||
                FName == "IOServiceMatching" ||
                FName == "IOServiceNameMatching" ||
@@ -1089,18 +1089,6 @@
     if (S)
       break;
 
-    // Enable this code once the semantics of NSDeallocateObject are resolved
-    // for GC.  <rdar://problem/6619988>
-#if 0
-    // Handle: NSDeallocateObject(id anObject);
-    // This method does allow 'nil' (although we don't check it now).
-    if (strcmp(FName, "NSDeallocateObject") == 0) {
-      return RetTy == Ctx.VoidTy
-        ? getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, Dealloc)
-        : getPersistentStopSummary();
-    }
-#endif
-
     if (RetTy->isPointerType()) {
       // For CoreFoundation ('CF') types.
       if (cocoa::isRefType(RetTy, "CF", FName)) {
@@ -1178,7 +1166,8 @@
     S = getDefaultSummary();
 
   // Annotations override defaults.
-  updateSummaryFromAnnotations(S, FD);
+  if (AllowAnnotations)
+    updateSummaryFromAnnotations(S, FD);
 
   FuncSummaries[FD] = S;
   return S;
@@ -1460,7 +1449,7 @@
   // objects.
   SVal ReceiverV = Msg.getReceiverSVal();
   if (SymbolRef Sym = ReceiverV.getAsLocSymbol())
-    if (const RefVal *T = State->get<RefBindings>(Sym))
+    if (const RefVal *T = getRefBinding(State, Sym))
       if (const ObjCObjectPointerType *PT =
             T->getType()->getAs<ObjCObjectPointerType>())
         ReceiverClass = PT->getInterfaceDecl();
@@ -1572,28 +1561,12 @@
 
   addClassMethSummary("NSWindow", "alloc", NoTrackYet);
 
-#if 0
-  addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
-                     "styleMask", "backing", "defer", NULL);
-
-  addInstMethSummary("NSWindow", NoTrackYet, "initWithContentRect",
-                     "styleMask", "backing", "defer", "screen", NULL);
-#endif
-
   // For NSPanel (which subclasses NSWindow), allocated objects are not
   //  self-owned.
   // FIXME: For now we don't track NSPanels. object for the same reason
   //   as for NSWindow objects.
   addClassMethSummary("NSPanel", "alloc", NoTrackYet);
 
-#if 0
-  addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
-                     "styleMask", "backing", "defer", NULL);
-
-  addInstMethSummary("NSPanel", NoTrackYet, "initWithContentRect",
-                     "styleMask", "backing", "defer", "screen", NULL);
-#endif
-
   // Don't track allocated autorelease pools yet, as it is okay to prematurely
   // exit a method.
   addClassMethSummary("NSAutoreleasePool", "alloc", NoTrackYet);
@@ -1617,57 +1590,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// AutoreleaseBindings - State used to track objects in autorelease pools.
-//===----------------------------------------------------------------------===//
-
-typedef llvm::ImmutableMap<SymbolRef, unsigned> ARCounts;
-typedef llvm::ImmutableMap<SymbolRef, ARCounts> ARPoolContents;
-typedef llvm::ImmutableList<SymbolRef> ARStack;
-
-static int AutoRCIndex = 0;
-static int AutoRBIndex = 0;
-
-namespace { class AutoreleasePoolContents {}; }
-namespace { class AutoreleaseStack {}; }
-
-namespace clang {
-namespace ento {
-template<> struct ProgramStateTrait<AutoreleaseStack>
-  : public ProgramStatePartialTrait<ARStack> {
-  static inline void *GDMIndex() { return &AutoRBIndex; }
-};
-
-template<> struct ProgramStateTrait<AutoreleasePoolContents>
-  : public ProgramStatePartialTrait<ARPoolContents> {
-  static inline void *GDMIndex() { return &AutoRCIndex; }
-};
-} // end GR namespace
-} // end clang namespace
-
-static SymbolRef GetCurrentAutoreleasePool(ProgramStateRef state) {
-  ARStack stack = state->get<AutoreleaseStack>();
-  return stack.isEmpty() ? SymbolRef() : stack.getHead();
-}
-
-static ProgramStateRef 
-SendAutorelease(ProgramStateRef state,
-                ARCounts::Factory &F,
-                SymbolRef sym) {
-  SymbolRef pool = GetCurrentAutoreleasePool(state);
-  const ARCounts *cnts = state->get<AutoreleasePoolContents>(pool);
-  ARCounts newCnts(0);
-
-  if (cnts) {
-    const unsigned *cnt = (*cnts).lookup(sym);
-    newCnts = F.add(*cnts, sym, cnt ? *cnt  + 1 : 1);
-  }
-  else
-    newCnts = F.add(F.getEmptyMap(), sym, 1);
-
-  return state->set<AutoreleasePoolContents>(pool, newCnts);
-}
-
-//===----------------------------------------------------------------------===//
 // Error reporting.
 //===----------------------------------------------------------------------===//
 namespace {
@@ -1924,11 +1846,11 @@
   ProgramStateRef CurrSt = N->getState();
   const LocationContext *LCtx = N->getLocationContext();
 
-  const RefVal* CurrT = CurrSt->get<RefBindings>(Sym);
+  const RefVal* CurrT = getRefBinding(CurrSt, Sym);
   if (!CurrT) return NULL;
 
   const RefVal &CurrV = *CurrT;
-  const RefVal *PrevT = PrevSt->get<RefBindings>(Sym);
+  const RefVal *PrevT = getRefBinding(PrevSt, Sym);
 
   // Create a string buffer to constain all the useful things we want
   // to tell the user.
@@ -1975,8 +1897,11 @@
       }
       else {
         assert(isa<ObjCMessageExpr>(S));
-        ObjCMethodCall Call(cast<ObjCMessageExpr>(S), CurrSt, LCtx);
-        switch (Call.getMessageKind()) {
+        CallEventManager &Mgr = CurrSt->getStateManager().getCallEventManager();
+        CallEventRef<ObjCMethodCall> Call
+          = Mgr.getObjCMethodCall(cast<ObjCMessageExpr>(S), CurrSt, LCtx);
+
+        switch (Call->getMessageKind()) {
         case OCM_Message:
           os << "Method";
           break;
@@ -2213,9 +2138,8 @@
 
   while (N) {
     ProgramStateRef St = N->getState();
-    RefBindings B = St->get<RefBindings>();
 
-    if (!B.lookup(Sym))
+    if (!getRefBinding(St, Sym))
       break;
 
     StoreManager::FindUniqueBinding FB(Sym);
@@ -2286,7 +2210,7 @@
     os << "allocated object";
 
   // Get the retain count.
-  const RefVal* RV = EndN->getState()->get<RefBindings>(Sym);
+  const RefVal* RV = getRefBinding(EndN->getState(), Sym);
 
   if (RV->getKind() == RefVal::ErrorLeakReturned) {
     // FIXME: Per comments in rdar://6320065, "create" only applies to CF
@@ -2405,9 +2329,6 @@
 
   mutable OwningPtr<RetainSummaryManager> Summaries;
   mutable OwningPtr<RetainSummaryManager> SummariesGC;
-
-  mutable ARCounts::Factory ARCountFactory;
-
   mutable SummaryLogTy SummaryLog;
   mutable bool ShouldResetSummaryLog;
 
@@ -2572,17 +2493,16 @@
   const ProgramPointTag *getDeadSymbolTag(SymbolRef sym) const;
 
   ProgramStateRef handleSymbolDeath(ProgramStateRef state,
-                                        SymbolRef sid, RefVal V,
-                                      SmallVectorImpl<SymbolRef> &Leaked) const;
+                                    SymbolRef sid, RefVal V,
+                                    SmallVectorImpl<SymbolRef> &Leaked) const;
 
   std::pair<ExplodedNode *, ProgramStateRef >
-  handleAutoreleaseCounts(ProgramStateRef state, 
-                          GenericNodeBuilderRefCount Bd, ExplodedNode *Pred,
-                          CheckerContext &Ctx, SymbolRef Sym, RefVal V) const;
+  handleAutoreleaseCounts(ProgramStateRef state, ExplodedNode *Pred,
+                          const ProgramPointTag *Tag, CheckerContext &Ctx,
+                          SymbolRef Sym, RefVal V) const;
 
   ExplodedNode *processLeaks(ProgramStateRef state,
                              SmallVectorImpl<SymbolRef> &Leaked,
-                             GenericNodeBuilderRefCount &Builder,
                              CheckerContext &Ctx,
                              ExplodedNode *Pred = 0) const;
 };
@@ -2670,7 +2590,7 @@
   SymbolRef Sym = state->getSVal(CE, C.getLocationContext()).getAsLocSymbol();
   if (!Sym)
     return;
-  const RefVal* T = state->get<RefBindings>(Sym);
+  const RefVal* T = getRefBinding(state, Sym);
   if (!T)
     return;
 
@@ -2695,7 +2615,7 @@
     const Stmt *child = *it;
     SVal V = state->getSVal(child, pred->getLocationContext());
     if (SymbolRef sym = V.getAsSymbol())
-      if (const RefVal* T = state->get<RefBindings>(sym)) {
+      if (const RefVal* T = getRefBinding(state, sym)) {
         RefVal::Kind hasErr = (RefVal::Kind) 0;
         state = updateSymbol(state, sym, *T, MayEscape, hasErr, C);
         if (hasErr) {
@@ -2710,8 +2630,8 @@
   if (SymbolRef sym = 
         state->getSVal(Ex, pred->getLocationContext()).getAsSymbol()) {
     QualType ResultTy = Ex->getType();
-    state = state->set<RefBindings>(sym, RefVal::makeNotOwned(RetEffect::ObjC,
-                                                              ResultTy));
+    state = setRefBinding(state, sym,
+                          RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
   }
   
   C.addTransition(state);  
@@ -2737,8 +2657,8 @@
 
   if (SymbolRef Sym = State->getSVal(Ex, LCtx).getAsSymbol()) {
     QualType ResultTy = Ex->getType();
-    State = State->set<RefBindings>(Sym, RefVal::makeNotOwned(RetEffect::ObjC,
-                                                              ResultTy));
+    State = setRefBinding(State, Sym,
+                          RefVal::makeNotOwned(RetEffect::ObjC, ResultTy));
   }
 
   C.addTransition(State);
@@ -2796,7 +2716,7 @@
     SVal V = CallOrMsg.getArgSVal(idx);
 
     if (SymbolRef Sym = V.getAsLocSymbol()) {
-      if (RefBindings::data_type *T = state->get<RefBindings>(Sym)) {
+      if (const RefVal *T = getRefBinding(state, Sym)) {
         state = updateSymbol(state, Sym, *T, Summ.getArg(idx), hasErr, C);
         if (hasErr) {
           ErrorRange = CallOrMsg.getArgSourceRange(idx);
@@ -2813,7 +2733,7 @@
     const ObjCMethodCall *MsgInvocation = dyn_cast<ObjCMethodCall>(&CallOrMsg);
     if (MsgInvocation) {
       if (SymbolRef Sym = MsgInvocation->getReceiverSVal().getAsLocSymbol()) {
-        if (const RefVal *T = state->get<RefBindings>(Sym)) {
+        if (const RefVal *T = getRefBinding(state, Sym)) {
           ReceiverIsTracked = true;
           state = updateSymbol(state, Sym, *T, Summ.getReceiverEffect(),
                                hasErr, C);
@@ -2860,19 +2780,11 @@
       // Use the result type from the CallEvent as it automatically adjusts
       // for methods/functions that return references.
       QualType ResultTy = CallOrMsg.getResultType();
-      state = state->set<RefBindings>(Sym, RefVal::makeOwned(RE.getObjKind(),
-                                                             ResultTy));
+      state = setRefBinding(state, Sym, RefVal::makeOwned(RE.getObjKind(),
+                                                          ResultTy));
 
       // FIXME: Add a flag to the checker where allocations are assumed to
-      // *not* fail. (The code below is out-of-date, though.)
-#if 0
-      if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) {
-        bool isFeasible;
-        state = state.assume(loc::SymbolVal(Sym), true, isFeasible);
-        assert(isFeasible && "Cannot assume fresh symbol is non-null.");
-      }
-#endif
-
+      // *not* fail.
       break;
     }
 
@@ -2886,8 +2798,8 @@
 
       // Use GetReturnType in order to give [NSFoo alloc] the type NSFoo *.
       QualType ResultTy = GetReturnType(Ex, C.getASTContext());
-      state = state->set<RefBindings>(Sym, RefVal::makeNotOwned(RE.getObjKind(),
-                                                                ResultTy));
+      state = setRefBinding(state, Sym, RefVal::makeNotOwned(RE.getObjKind(),
+                                                             ResultTy));
       break;
     }
   }
@@ -2948,7 +2860,7 @@
   if (!C.isObjCGCEnabled() && V.getKind() == RefVal::Released) {
     V = V ^ RefVal::ErrorUseAfterRelease;
     hasErr = V.getKind();
-    return state->set<RefBindings>(sym, V);
+    return setRefBinding(state, sym, V);
   }
 
   switch (E) {
@@ -2973,7 +2885,7 @@
           // The object immediately transitions to the released state.
           V = V ^ RefVal::Released;
           V.clearCounts();
-          return state->set<RefBindings>(sym, V);
+          return setRefBinding(state, sym, V);
         case RefVal::NotOwned:
           V = V ^ RefVal::ErrorDeallocNotOwned;
           hasErr = V.getKind();
@@ -2983,7 +2895,7 @@
 
     case NewAutoreleasePool:
       assert(!C.isObjCGCEnabled());
-      return state->add<AutoreleaseStack>(sym);
+      return state;
 
     case MayEscape:
       if (V.getKind() == RefVal::Owned) {
@@ -2999,14 +2911,12 @@
     case Autorelease:
       if (C.isObjCGCEnabled())
         return state;
-
       // Update the autorelease counts.
-      state = SendAutorelease(state, ARCountFactory, sym);
       V = V.autorelease();
       break;
 
     case StopTracking:
-      return state->remove<RefBindings>(sym);
+      return removeRefBinding(state, sym);
 
     case IncRef:
       switch (V.getKind()) {
@@ -3038,7 +2948,7 @@
             V = V ^ (E == DecRefBridgedTransfered ? 
                       RefVal::NotOwned : RefVal::Released);
           else if (E == DecRefAndStopTracking)
-            return state->remove<RefBindings>(sym);
+            return removeRefBinding(state, sym);
 
           V = V - 1;
           break;
@@ -3046,7 +2956,7 @@
         case RefVal::NotOwned:
           if (V.getCount() > 0) {
             if (E == DecRefAndStopTracking)
-              return state->remove<RefBindings>(sym);
+              return removeRefBinding(state, sym);
             V = V - 1;
           } else {
             V = V ^ RefVal::ErrorReleaseNotOwned;
@@ -3063,7 +2973,7 @@
       }
       break;
   }
-  return state->set<RefBindings>(sym, V);
+  return setRefBinding(state, sym, V);
 }
 
 void RetainCountChecker::processNonLeakError(ProgramStateRef St,
@@ -3171,9 +3081,9 @@
   if (const MemRegion *ArgRegion = RetVal.getAsRegion()) {
     // Save the refcount status of the argument.
     SymbolRef Sym = RetVal.getAsLocSymbol();
-    RefBindings::data_type *Binding = 0;
+    const RefVal *Binding = 0;
     if (Sym)
-      Binding = state->get<RefBindings>(Sym);
+      Binding = getRefBinding(state, Sym);
 
     // Invalidate the argument region.
     unsigned Count = C.getCurrentBlockCount();
@@ -3181,7 +3091,7 @@
 
     // Restore the refcount status of the argument.
     if (Binding)
-      state = state->set<RefBindings>(Sym, *Binding);
+      state = setRefBinding(state, Sym, *Binding);
   }
 
   C.addTransition(state);
@@ -3220,7 +3130,7 @@
     return;
 
   // Get the reference count binding (if any).
-  const RefVal *T = state->get<RefBindings>(Sym);
+  const RefVal *T = getRefBinding(state, Sym);
   if (!T)
     return;
 
@@ -3253,7 +3163,7 @@
   }
 
   // Update the binding.
-  state = state->set<RefBindings>(Sym, X);
+  state = setRefBinding(state, Sym, X);
   ExplodedNode *Pred = C.addTransition(state);
 
   // At this point we have updated the state properly.
@@ -3267,15 +3177,15 @@
   // Update the autorelease counts.
   static SimpleProgramPointTag
          AutoreleaseTag("RetainCountChecker : Autorelease");
-  GenericNodeBuilderRefCount Bd(C, &AutoreleaseTag);
-  llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, C, Sym, X);
+  llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Pred, &AutoreleaseTag,
+                                                   C, Sym, X);
 
   // Did we cache out?
   if (!Pred)
     return;
 
   // Get the updated binding.
-  T = state->get<RefBindings>(Sym);
+  T = getRefBinding(state, Sym);
   assert(T);
   X = *T;
 
@@ -3326,7 +3236,7 @@
 
       if (hasError) {
         // Generate an error node.
-        state = state->set<RefBindings>(Sym, X);
+        state = setRefBinding(state, Sym, X);
 
         static SimpleProgramPointTag
                ReturnOwnLeakTag("RetainCountChecker : ReturnsOwnLeak");
@@ -3346,7 +3256,7 @@
     if (RE.isOwned()) {
       // Trying to return a not owned object to a caller expecting an
       // owned object.
-      state = state->set<RefBindings>(Sym, X ^ RefVal::ErrorReturnedNotOwned);
+      state = setRefBinding(state, Sym, X ^ RefVal::ErrorReturnedNotOwned);
 
       static SimpleProgramPointTag
              ReturnNotOwnedTag("RetainCountChecker : ReturnNotOwnedForOwned");
@@ -3470,7 +3380,7 @@
     if (WhitelistedSymbols.count(sym))
       continue;
     // Remove any existing reference-count binding.
-    state = state->remove<RefBindings>(sym);
+    state = removeRefBinding(state, sym);
   }
   return state;
 }
@@ -3481,8 +3391,8 @@
 
 std::pair<ExplodedNode *, ProgramStateRef >
 RetainCountChecker::handleAutoreleaseCounts(ProgramStateRef state, 
-                                            GenericNodeBuilderRefCount Bd,
                                             ExplodedNode *Pred,
+                                            const ProgramPointTag *Tag,
                                             CheckerContext &Ctx,
                                             SymbolRef Sym, RefVal V) const {
   unsigned ACnt = V.getAutoreleaseCount();
@@ -3510,8 +3420,8 @@
       V.setCount(Cnt - ACnt);
       V.setAutoreleaseCount(0);
     }
-    state = state->set<RefBindings>(Sym, V);
-    ExplodedNode *N = Bd.MakeNode(state, Pred);
+    state = setRefBinding(state, Sym, V);
+    ExplodedNode *N = Ctx.addTransition(state, Pred, Tag);
     if (N == 0)
       state = 0;
     return std::make_pair(N, state);
@@ -3520,9 +3430,10 @@
   // Woah!  More autorelease counts then retain counts left.
   // Emit hard error.
   V = V ^ RefVal::ErrorOverAutorelease;
-  state = state->set<RefBindings>(Sym, V);
+  state = setRefBinding(state, Sym, V);
 
-  if (ExplodedNode *N = Bd.MakeNode(state, Pred, true)) {
+  ExplodedNode *N = Ctx.generateSink(state, Pred, Tag);
+  if (N) {
     SmallString<128> sbuf;
     llvm::raw_svector_ostream os(sbuf);
     os << "Object over-autoreleased: object was sent -autorelease ";
@@ -3554,23 +3465,22 @@
     hasLeak = (V.getCount() > 0);
 
   if (!hasLeak)
-    return state->remove<RefBindings>(sid);
+    return removeRefBinding(state, sid);
 
   Leaked.push_back(sid);
-  return state->set<RefBindings>(sid, V ^ RefVal::ErrorLeak);
+  return setRefBinding(state, sid, V ^ RefVal::ErrorLeak);
 }
 
 ExplodedNode *
 RetainCountChecker::processLeaks(ProgramStateRef state,
                                  SmallVectorImpl<SymbolRef> &Leaked,
-                                 GenericNodeBuilderRefCount &Builder,
                                  CheckerContext &Ctx,
                                  ExplodedNode *Pred) const {
   if (Leaked.empty())
     return Pred;
 
   // Generate an intermediate node representing the leak point.
-  ExplodedNode *N = Builder.MakeNode(state, Pred);
+  ExplodedNode *N = Ctx.addTransition(state, Pred);
 
   if (N) {
     for (SmallVectorImpl<SymbolRef>::iterator
@@ -3593,20 +3503,19 @@
 
 void RetainCountChecker::checkEndPath(CheckerContext &Ctx) const {
   ProgramStateRef state = Ctx.getState();
-  GenericNodeBuilderRefCount Bd(Ctx);
   RefBindings B = state->get<RefBindings>();
   ExplodedNode *Pred = Ctx.getPredecessor();
 
   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
-    llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, Ctx,
-                                                     I->first, I->second);
+    llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Pred, /*Tag=*/0,
+                                                     Ctx, I->first, I->second);
     if (!state)
       return;
   }
 
   // If the current LocationContext has a parent, don't check for leaks.
   // We will do that later.
-  // FIXME: we should instead check for imblances of the retain/releases,
+  // FIXME: we should instead check for imbalances of the retain/releases,
   // and suggest annotations.
   if (Ctx.getLocationContext()->getParent())
     return;
@@ -3617,7 +3526,7 @@
   for (RefBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
     state = handleSymbolDeath(state, I->first, I->second, Leaked);
 
-  processLeaks(state, Leaked, Bd, Ctx, Pred);
+  processLeaks(state, Leaked, Ctx, Pred);
 }
 
 const ProgramPointTag *
@@ -3647,8 +3556,8 @@
     if (const RefVal *T = B.lookup(Sym)){
       // Use the symbol as the tag.
       // FIXME: This might not be as unique as we would like.
-      GenericNodeBuilderRefCount Bd(C, getDeadSymbolTag(Sym));
-      llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Bd, Pred, C,
+      const ProgramPointTag *Tag = getDeadSymbolTag(Sym);
+      llvm::tie(Pred, state) = handleAutoreleaseCounts(state, Pred, Tag, C,
                                                        Sym, *T);
       if (!state)
         return;
@@ -3664,10 +3573,7 @@
       state = handleSymbolDeath(state, *I, *T, Leaked);
   }
 
-  {
-    GenericNodeBuilderRefCount Bd(C, this);
-    Pred = processLeaks(state, Leaked, Bd, C, Pred);
-  }
+  Pred = processLeaks(state, Leaked, C, Pred);
 
   // Did we cache out?
   if (!Pred)
@@ -3684,34 +3590,6 @@
   C.addTransition(state, Pred);
 }
 
-//===----------------------------------------------------------------------===//
-// Debug printing of refcount bindings and autorelease pools.
-//===----------------------------------------------------------------------===//
-
-static void PrintPool(raw_ostream &Out, SymbolRef Sym,
-                      ProgramStateRef State) {
-  Out << ' ';
-  if (Sym)
-    Sym->dumpToStream(Out);
-  else
-    Out << "<pool>";
-  Out << ":{";
-
-  // Get the contents of the pool.
-  if (const ARCounts *Cnts = State->get<AutoreleasePoolContents>(Sym))
-    for (ARCounts::iterator I = Cnts->begin(), E = Cnts->end(); I != E; ++I)
-      Out << '(' << I.getKey() << ',' << I.getData() << ')';
-
-  Out << '}';
-}
-
-static bool UsesAutorelease(ProgramStateRef state) {
-  // A state uses autorelease if it allocated an autorelease pool or if it has
-  // objects in the caller's autorelease pool.
-  return !state->get<AutoreleaseStack>().isEmpty() ||
-          state->get<AutoreleasePoolContents>(SymbolRef());
-}
-
 void RetainCountChecker::printState(raw_ostream &Out, ProgramStateRef State,
                                     const char *NL, const char *Sep) const {
 
@@ -3725,18 +3603,6 @@
     I->second.print(Out);
     Out << NL;
   }
-
-  // Print the autorelease stack.
-  if (UsesAutorelease(State)) {
-    Out << Sep << NL << "AR pool stack:";
-    ARStack Stack = State->get<AutoreleaseStack>();
-
-    PrintPool(Out, SymbolRef(), State);  // Print the caller's pool.
-    for (ARStack::iterator I = Stack.begin(), E = Stack.end(); I != E; ++I)
-      PrintPool(Out, *I, State);
-
-    Out << NL;
-  }
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
index 0851836..ca2a55d 100644
--- a/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp
@@ -55,8 +55,7 @@
 
   report->disablePathPruning();
   report->addRange(RetE->getSourceRange());
-  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, RetE,
-                                                                  report));
+  bugreporter::addTrackNullOrUndefValueVisitor(N, RetE, report);
 
   C.EmitReport(report);
 }
diff --git a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
index ed6187d..b97cd6c 100644
--- a/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
@@ -16,7 +16,7 @@
 #include "clang/AST/StmtObjC.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 
 using namespace clang;
diff --git a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
index 48b1941..70a33c7 100644
--- a/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp
@@ -99,7 +99,7 @@
 
       // Emit the bug report.
       BugReport *R = new BugReport(*BT, BT->getDescription(), N);
-      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex, R));
+      bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, R);
       R->addRange(Ex->getSourceRange());
       R->disablePathPruning();
 
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index a27fa1d..e220499 100644
--- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -76,12 +76,10 @@
     BugReport *report = new BugReport(*BT, OS.str(), N);
     if (Ex) {
       report->addRange(Ex->getSourceRange());
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Ex,
-                                                                      report));
+      bugreporter::addTrackNullOrUndefValueVisitor(N, Ex, report);
     }
     else
-      report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, B,
-                                                                      report));
+      bugreporter::addTrackNullOrUndefValueVisitor(N, B, report);
     
     report->disablePathPruning();
     C.EmitReport(report);
diff --git a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
index 0297c4e..6ae3c18 100644
--- a/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp
@@ -42,9 +42,7 @@
       // Generate a report for this bug.
       BugReport *R = new BugReport(*BT, BT->getName(), N);
       R->addRange(A->getIdx()->getSourceRange());
-      R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N,
-                                                                 A->getIdx(),
-                                                                 R));
+      bugreporter::addTrackNullOrUndefValueVisitor(N, A->getIdx(), R);
       C.EmitReport(R);
     }
   }
diff --git a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
index 7b1081f..14a884e 100644
--- a/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -78,7 +78,7 @@
   BugReport *R = new BugReport(*BT, str, N);
   if (ex) {
     R->addRange(ex->getSourceRange());
-    R->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, ex, R));
+    bugreporter::addTrackNullOrUndefValueVisitor(N, ex, R);
   }
   R->disablePathPruning();
   C.EmitReport(R);
diff --git a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index f173cde..d35455c 100644
--- a/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -224,8 +224,7 @@
   BugReport *report = new BugReport(*BT_mallocZero, os.str(), N);
 
   report->addRange(arg->getSourceRange());
-  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, arg,
-                                                                  report));
+  bugreporter::addTrackNullOrUndefValueVisitor(N, arg, report);
   C.EmitReport(report);
 
   return true;
diff --git a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
index 38c9cc1..fab4adf 100644
--- a/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -69,8 +69,7 @@
 
   BugReport *report = new BugReport(*BT, os.str(), N);
   report->addRange(SizeE->getSourceRange());
-  report->addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, SizeE,
-                                                                  report));
+  bugreporter::addTrackNullOrUndefValueVisitor(N, SizeE, report);
   C.EmitReport(report);
   return;
 }
diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 178df02..efeba17 100644
--- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -16,7 +16,7 @@
 
 AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
                                  const LangOptions &lang,
-                                 PathDiagnosticConsumer *pd,
+                                 const PathDiagnosticConsumers &PDC,
                                  StoreManagerCreator storemgr,
                                  ConstraintManagerCreator constraintmgr, 
                                  CheckerManager *checkerMgr,
@@ -25,15 +25,16 @@
                                  AnalysisPurgeMode purge,
                                  bool eager, bool trim,
                                  bool useUnoptimizedCFG,
-                                 bool addImplicitDtors, bool addInitializers,
+                                 bool addImplicitDtors,
                                  bool eagerlyTrimEGraph,
                                  AnalysisIPAMode ipa,
                                  unsigned inlineMaxStack,
                                  unsigned inlineMaxFunctionSize,
                                  AnalysisInliningMode IMode,
                                  bool NoRetry)
-  : AnaCtxMgr(useUnoptimizedCFG, addImplicitDtors, addInitializers),
-    Ctx(ctx), Diags(diags), LangOpts(lang), PD(pd),
+  : AnaCtxMgr(useUnoptimizedCFG, addImplicitDtors, /*addInitializers=*/true),
+    Ctx(ctx), Diags(diags), LangOpts(lang),
+    PathConsumers(PDC),
     CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
     CheckerMgr(checkerMgr), 
     MaxNodes(maxnodes), MaxVisit(maxvisit),
@@ -49,29 +50,19 @@
   AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd();
 }
 
-AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
-                                 AnalysisManager &ParentAM)
-  : AnaCtxMgr(ParentAM.AnaCtxMgr.getUseUnoptimizedCFG(),
-              ParentAM.AnaCtxMgr.getCFGBuildOptions().AddImplicitDtors,
-              ParentAM.AnaCtxMgr.getCFGBuildOptions().AddInitializers),
-    Ctx(ctx), Diags(diags),
-    LangOpts(ParentAM.LangOpts), PD(ParentAM.getPathDiagnosticConsumer()),
-    CreateStoreMgr(ParentAM.CreateStoreMgr),
-    CreateConstraintMgr(ParentAM.CreateConstraintMgr),
-    CheckerMgr(ParentAM.CheckerMgr),
-    MaxNodes(ParentAM.MaxNodes),
-    MaxVisit(ParentAM.MaxVisit),
-    VisualizeEGDot(ParentAM.VisualizeEGDot),
-    VisualizeEGUbi(ParentAM.VisualizeEGUbi),
-    PurgeDead(ParentAM.PurgeDead),
-    EagerlyAssume(ParentAM.EagerlyAssume),
-    TrimGraph(ParentAM.TrimGraph),
-    EagerlyTrimEGraph(ParentAM.EagerlyTrimEGraph),
-    IPAMode(ParentAM.IPAMode),
-    InlineMaxStackDepth(ParentAM.InlineMaxStackDepth),
-    InlineMaxFunctionSize(ParentAM.InlineMaxFunctionSize),
-    InliningMode(ParentAM.InliningMode),
-    NoRetryExhausted(ParentAM.NoRetryExhausted)
-{
-  AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd();
+AnalysisManager::~AnalysisManager() {
+  FlushDiagnostics();
+  for (PathDiagnosticConsumers::iterator I = PathConsumers.begin(),
+       E = PathConsumers.end(); I != E; ++I) {
+    delete *I;
+  }
+}
+
+void AnalysisManager::FlushDiagnostics() {
+  PathDiagnosticConsumer::FilesMade filesMade;
+  for (PathDiagnosticConsumers::iterator I = PathConsumers.begin(),
+       E = PathConsumers.end();
+       I != E; ++I) {
+    (*I)->FlushDiagnostics(&filesMade);
+  }
 }
diff --git a/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp b/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
index 8897756..9a3c5d1 100644
--- a/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/BasicConstraintManager.cpp
@@ -363,7 +363,6 @@
 bool BasicConstraintManager::isNotEqual(ProgramStateRef state,
                                         SymbolRef sym,
                                         const llvm::APSInt& V) const {
-
   // Retrieve the NE-set associated with the given symbol.
   const ConstNotEqTy::data_type* T = state->get<ConstNotEq>(sym);
 
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index 08588f6..571baec 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -441,21 +441,23 @@
     }
     
     if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+      // Flush all locations, and pop the active path.
+      bool VisitedEntireCall = PD.isWithinCall();
       PD.popActivePath();
-      // The current active path should never be empty.  Either we
-      // just added a bunch of stuff to the top-level path, or
-      // we have a previous CallExitEnd.  If the front of the active
-      // path is not a PathDiagnosticCallPiece, it means that the
+
+      // Either we just added a bunch of stuff to the top-level path, or
+      // we have a previous CallExitEnd.  If the former, it means that the
       // path terminated within a function call.  We must then take the
       // current contents of the active path and place it within
       // a new PathDiagnosticCallPiece.
-      assert(!PD.getActivePath().empty());
-      PathDiagnosticCallPiece *C = 
-        dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
-      if (!C) {
+      PathDiagnosticCallPiece *C;
+      if (VisitedEntireCall) {
+        C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
+      } else {
         const Decl *Caller = CE->getLocationContext()->getDecl();
         C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
       }
+
       C->setCallee(*CE, SMgr);
       if (!CallStack.empty()) {
         assert(CallStack.back().first == C);
@@ -868,6 +870,7 @@
   void rawAddEdge(PathDiagnosticLocation NewLoc);
 
   void addContext(const Stmt *S);
+  void addContext(const PathDiagnosticLocation &L);
   void addExtendedContext(const Stmt *S);
 };
 } // end anonymous namespace
@@ -1035,7 +1038,10 @@
     return;
 
   PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC);
+  addContext(L);
+}
 
+void EdgeBuilder::addContext(const PathDiagnosticLocation &L) {
   while (!CLocs.empty()) {
     const PathDiagnosticLocation &TopContextLoc = CLocs.back();
 
@@ -1151,25 +1157,22 @@
       }
       
       if (const CallExitEnd *CE = dyn_cast<CallExitEnd>(&P)) {
-        const StackFrameContext *LCtx =
-          CE->getLocationContext()->getCurrentStackFrame();
-        // FIXME: This needs to handle implicit calls.
-        if (const Stmt *S = CE->getCalleeContext()->getCallSite()) {
-          if (const Expr *Ex = dyn_cast<Expr>(S))
+        const Stmt *S = CE->getCalleeContext()->getCallSite();
+        if (const Expr *Ex = dyn_cast_or_null<Expr>(S)) {
             reversePropagateIntererstingSymbols(*PDB.getBugReport(), IE,
                                                 N->getState().getPtr(), Ex,
                                                 N->getLocationContext());
-          PathDiagnosticLocation Loc(S,
-                                     PDB.getSourceManager(),
-                                     LCtx);
-          EB.addEdge(Loc, true);
-          EB.flushLocations();
-          PathDiagnosticCallPiece *C =
-            PathDiagnosticCallPiece::construct(N, *CE, SM);
-          PD.getActivePath().push_front(C);
-          PD.pushActivePath(&C->path);
-          CallStack.push_back(StackDiagPair(C, N));
         }
+        
+        PathDiagnosticCallPiece *C =
+          PathDiagnosticCallPiece::construct(N, *CE, SM);
+
+        EB.addEdge(C->callReturn, true);
+        EB.flushLocations();
+
+        PD.getActivePath().push_front(C);
+        PD.pushActivePath(&C->path);
+        CallStack.push_back(StackDiagPair(C, N));
         break;
       }
       
@@ -1183,30 +1186,26 @@
         EB.addEdge(pos);
         
         // Flush all locations, and pop the active path.
+        bool VisitedEntireCall = PD.isWithinCall();
         EB.flushLocations();
         PD.popActivePath();
-        assert(!PD.getActivePath().empty());
         PDB.LC = N->getLocationContext();
 
-        // The current active path should never be empty.  Either we
-        // just added a bunch of stuff to the top-level path, or
-        // we have a previous CallExitEnd.  If the front of the active
-        // path is not a PathDiagnosticCallPiece, it means that the
+        // Either we just added a bunch of stuff to the top-level path, or
+        // we have a previous CallExitEnd.  If the former, it means that the
         // path terminated within a function call.  We must then take the
         // current contents of the active path and place it within
         // a new PathDiagnosticCallPiece.
-        PathDiagnosticCallPiece *C =
-          dyn_cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
-        if (!C) {
-          const Decl * Caller = CE->getLocationContext()->getDecl();
+        PathDiagnosticCallPiece *C;
+        if (VisitedEntireCall) {
+          C = cast<PathDiagnosticCallPiece>(PD.getActivePath().front());
+        } else {
+          const Decl *Caller = CE->getLocationContext()->getDecl();
           C = PathDiagnosticCallPiece::construct(PD.getActivePath(), Caller);
         }
 
-        // FIXME: We still need a location for implicit calls.
-        if (CE->getCallExpr()) {
-          C->setCallee(*CE, SM);
-          EB.addContext(CE->getCallExpr());
-        }
+        C->setCallee(*CE, SM);
+        EB.addContext(C->getLocation());
 
         if (!CallStack.empty()) {
           assert(CallStack.back().first == C);
@@ -1346,6 +1345,9 @@
   for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
     delete *I;
   }
+  while (!interestingSymbols.empty()) {
+    popInterestingSymbolsAndRegions();
+  }
 }
 
 const Decl *BugReport::getDeclWithIssue() const {
@@ -1387,11 +1389,11 @@
     return;
 
   // If the symbol wasn't already in our set, note a configuration change.
-  if (interestingSymbols.insert(sym).second)
+  if (getInterestingSymbols().insert(sym).second)
     ++ConfigurationChangeToken;
 
   if (const SymbolMetadata *meta = dyn_cast<SymbolMetadata>(sym))
-    interestingRegions.insert(meta->getRegion());
+    getInterestingRegions().insert(meta->getRegion());
 }
 
 void BugReport::markInteresting(const MemRegion *R) {
@@ -1400,11 +1402,11 @@
 
   // If the base region wasn't already in our set, note a configuration change.
   R = R->getBaseRegion();
-  if (interestingRegions.insert(R).second)
+  if (getInterestingRegions().insert(R).second)
     ++ConfigurationChangeToken;
 
   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
-    interestingSymbols.insert(SR->getSymbol());
+    getInterestingSymbols().insert(SR->getSymbol());
 }
 
 void BugReport::markInteresting(SVal V) {
@@ -1412,30 +1414,58 @@
   markInteresting(V.getAsSymbol());
 }
 
-bool BugReport::isInteresting(SVal V) const {
+bool BugReport::isInteresting(SVal V) {
   return isInteresting(V.getAsRegion()) || isInteresting(V.getAsSymbol());
 }
 
-bool BugReport::isInteresting(SymbolRef sym) const {
+bool BugReport::isInteresting(SymbolRef sym) {
   if (!sym)
     return false;
   // We don't currently consider metadata symbols to be interesting
   // even if we know their region is interesting. Is that correct behavior?
-  return interestingSymbols.count(sym);
+  return getInterestingSymbols().count(sym);
 }
 
-bool BugReport::isInteresting(const MemRegion *R) const {
+bool BugReport::isInteresting(const MemRegion *R) {
   if (!R)
     return false;
   R = R->getBaseRegion();
-  bool b = interestingRegions.count(R);
+  bool b = getInterestingRegions().count(R);
   if (b)
     return true;
   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
-    return interestingSymbols.count(SR->getSymbol());
+    return getInterestingSymbols().count(SR->getSymbol());
   return false;
 }
-  
+
+void BugReport::lazyInitializeInterestingSets() {
+  if (interestingSymbols.empty()) {
+    interestingSymbols.push_back(new Symbols());
+    interestingRegions.push_back(new Regions());
+  }
+}
+
+BugReport::Symbols &BugReport::getInterestingSymbols() {
+  lazyInitializeInterestingSets();
+  return *interestingSymbols.back();
+}
+
+BugReport::Regions &BugReport::getInterestingRegions() {
+  lazyInitializeInterestingSets();
+  return *interestingRegions.back();
+}
+
+void BugReport::pushInterestingSymbolsAndRegions() {
+  interestingSymbols.push_back(new Symbols(getInterestingSymbols()));
+  interestingRegions.push_back(new Regions(getInterestingRegions()));
+}
+
+void BugReport::popInterestingSymbolsAndRegions() {
+  delete interestingSymbols.back();
+  interestingSymbols.pop_back();
+  delete interestingRegions.back();
+  interestingRegions.pop_back();
+}
 
 const Stmt *BugReport::getStmt() const {
   if (!ErrorNode)
@@ -1537,9 +1567,12 @@
          I = bugTypes.begin(), E = bugTypes.end(); I != E; ++I)
     const_cast<BugType*>(*I)->FlushReports(*this);
 
-  typedef llvm::FoldingSet<BugReportEquivClass> SetTy;
-  for (SetTy::iterator EI=EQClasses.begin(), EE=EQClasses.end(); EI!=EE;++EI){
-    BugReportEquivClass& EQ = *EI;
+  // We need to flush reports in deterministic order to ensure the order
+  // of the reports is consistent between runs.
+  typedef std::vector<BugReportEquivClass *> ContVecTy;
+  for (ContVecTy::iterator EI=EQClassesVector.begin(), EE=EQClassesVector.end();
+       EI != EE; ++EI){
+    BugReportEquivClass& EQ = **EI;
     FlushReport(EQ);
   }
 
@@ -1791,12 +1824,13 @@
 }
 
 void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD,
-                        SmallVectorImpl<BugReport *> &bugReports) {
+                                           PathDiagnosticConsumer &PC,
+                                           ArrayRef<BugReport *> &bugReports) {
 
   assert(!bugReports.empty());
   SmallVector<const ExplodedNode *, 10> errorNodes;
-  for (SmallVectorImpl<BugReport*>::iterator I = bugReports.begin(),
-    E = bugReports.end(); I != E; ++I) {
+  for (ArrayRef<BugReport*>::iterator I = bugReports.begin(),
+                                      E = bugReports.end(); I != E; ++I) {
       errorNodes.push_back((*I)->getErrorNode());
   }
 
@@ -1816,8 +1850,7 @@
   const ExplodedNode *N = GPair.second.first;
 
   // Start building the path diagnostic...
-  PathDiagnosticBuilder PDB(*this, R, BackMap.get(),
-                            getPathDiagnosticConsumer());
+  PathDiagnosticBuilder PDB(*this, R, BackMap.get(), &PC);
 
   // Register additional node visitors.
   R->addVisitor(new NilReceiverBRVisitor());
@@ -1865,6 +1898,8 @@
     case PathDiagnosticConsumer::Minimal:
       GenerateMinimalPathDiagnostic(PD, PDB, N, visitors);
       break;
+    case PathDiagnosticConsumer::None:
+      llvm_unreachable("PathDiagnosticConsumer::None should never appear here");
     }
 
     // Clean up the visitors we used.
@@ -2020,53 +2055,21 @@
   return exampleReport;
 }
 
-//===----------------------------------------------------------------------===//
-// DiagnosticCache.  This is a hack to cache analyzer diagnostics.  It
-// uses global state, which eventually should go elsewhere.
-//===----------------------------------------------------------------------===//
-namespace {
-class DiagCacheItem : public llvm::FoldingSetNode {
-  llvm::FoldingSetNodeID ID;
-public:
-  DiagCacheItem(BugReport *R, PathDiagnostic *PD) {
-    R->Profile(ID);
-    PD->Profile(ID);
-  }
-  
-  void Profile(llvm::FoldingSetNodeID &id) {
-    id = ID;
-  }
-  
-  llvm::FoldingSetNodeID &getID() { return ID; }
-};
-}
-
-static bool IsCachedDiagnostic(BugReport *R, PathDiagnostic *PD) {
-  // FIXME: Eventually this diagnostic cache should reside in something
-  // like AnalysisManager instead of being a static variable.  This is
-  // really unsafe in the long term.
-  typedef llvm::FoldingSet<DiagCacheItem> DiagnosticCache;
-  static DiagnosticCache DC;
-  
-  void *InsertPos;
-  DiagCacheItem *Item = new DiagCacheItem(R, PD);
-  
-  if (DC.FindNodeOrInsertPos(Item->getID(), InsertPos)) {
-    delete Item;
-    return true;
-  }
-  
-  DC.InsertNode(Item, InsertPos);
-  return false;
-}
-
 void BugReporter::FlushReport(BugReportEquivClass& EQ) {
   SmallVector<BugReport*, 10> bugReports;
   BugReport *exampleReport = FindReportInEquivalenceClass(EQ, bugReports);
-  if (!exampleReport)
-    return;
-  
-  PathDiagnosticConsumer* PD = getPathDiagnosticConsumer();
+  if (exampleReport) {
+    const PathDiagnosticConsumers &C = getPathDiagnosticConsumers();
+    for (PathDiagnosticConsumers::const_iterator I=C.begin(),
+                                                 E=C.end(); I != E; ++I) {
+      FlushReport(exampleReport, **I, bugReports);
+    }
+  }
+}
+
+void BugReporter::FlushReport(BugReport *exampleReport,
+                              PathDiagnosticConsumer &PD,
+                              ArrayRef<BugReport*> bugReports) {
 
   // FIXME: Make sure we use the 'R' for the path that was actually used.
   // Probably doesn't make a difference in practice.
@@ -2075,65 +2078,39 @@
   OwningPtr<PathDiagnostic>
     D(new PathDiagnostic(exampleReport->getDeclWithIssue(),
                          exampleReport->getBugType().getName(),
-                         !PD || PD->useVerboseDescription()
+                         PD.useVerboseDescription()
                          ? exampleReport->getDescription() 
                          : exampleReport->getShortDescription(),
                          BT.getCategory()));
 
-  if (!bugReports.empty())
-    GeneratePathDiagnostic(*D.get(), bugReports);
-  
+  // Generate the full path diagnostic, using the generation scheme
+  // specified by the PathDiagnosticConsumer.
+  if (PD.getGenerationScheme() != PathDiagnosticConsumer::None) {
+    if (!bugReports.empty())
+      GeneratePathDiagnostic(*D.get(), PD, bugReports);
+  }
+
+  // If the path is empty, generate a single step path with the location
+  // of the issue.
+  if (D->path.empty()) {
+    PathDiagnosticLocation L = exampleReport->getLocation(getSourceManager());
+    PathDiagnosticPiece *piece =
+      new PathDiagnosticEventPiece(L, exampleReport->getDescription());
+    BugReport::ranges_iterator Beg, End;
+    llvm::tie(Beg, End) = exampleReport->getRanges();
+    for ( ; Beg != End; ++Beg)
+      piece->addRange(*Beg);
+    D->getActivePath().push_back(piece);
+  }
+
   // Get the meta data.
-  const BugReport::ExtraTextList &Meta =
-                                  exampleReport->getExtraText();
+  const BugReport::ExtraTextList &Meta = exampleReport->getExtraText();
   for (BugReport::ExtraTextList::const_iterator i = Meta.begin(),
                                                 e = Meta.end(); i != e; ++i) {
     D->addMeta(*i);
   }
 
-  // Emit a summary diagnostic to the regular Diagnostics engine.
-  BugReport::ranges_iterator Beg, End;
-  llvm::tie(Beg, End) = exampleReport->getRanges();
-  DiagnosticsEngine &Diag = getDiagnostic();
-  
-  if (!IsCachedDiagnostic(exampleReport, D.get())) {
-    // Search the description for '%', as that will be interpretted as a
-    // format character by FormatDiagnostics.
-    StringRef desc = exampleReport->getShortDescription();
-
-    SmallString<512> TmpStr;
-    llvm::raw_svector_ostream Out(TmpStr);
-    for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I) {
-      if (*I == '%')
-        Out << "%%";
-      else
-        Out << *I;
-    }
-    
-    Out.flush();
-    unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning, TmpStr);
-
-    DiagnosticBuilder diagBuilder = Diag.Report(
-      exampleReport->getLocation(getSourceManager()).asLocation(), ErrorDiag);
-    for (BugReport::ranges_iterator I = Beg; I != End; ++I)
-      diagBuilder << *I;
-  }
-
-  // Emit a full diagnostic for the path if we have a PathDiagnosticConsumer.
-  if (!PD)
-    return;
-
-  if (D->path.empty()) {
-    PathDiagnosticPiece *piece = new PathDiagnosticEventPiece(
-                                 exampleReport->getLocation(getSourceManager()),
-                                 exampleReport->getDescription());
-    for ( ; Beg != End; ++Beg)
-      piece->addRange(*Beg);
-
-    D->getActivePath().push_back(piece);
-  }
-
-  PD->HandlePathDiagnostic(D.take());
+  PD.HandlePathDiagnostic(D.take());
 }
 
 void BugReporter::EmitBasicReport(const Decl *DeclWithIssue,
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index 4afc874..e729587 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -63,14 +63,6 @@
   return NULL;
 }
 
-const Stmt *bugreporter::GetCalleeExpr(const ExplodedNode *N) {
-  // Callee is checked as a PreVisit to the CallExpr.
-  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
-  if (const CallExpr *CE = dyn_cast<CallExpr>(S))
-    return CE->getCallee();
-  return NULL;
-}
-
 const Stmt *bugreporter::GetRetValExpr(const ExplodedNode *N) {
   const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
   if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
@@ -127,10 +119,16 @@
     return NULL;
 
   if (!StoreSite) {
-    const ExplodedNode *Node = N, *Last = NULL;
+    // Make sure the region is actually bound to value V here.
+    // This is necessary because the region may not actually be live at the
+    // report's error node.
+    if (N->getState()->getSVal(R) != V)
+      return NULL;
 
+    const ExplodedNode *Node = N, *Last = N;
+
+    // Now look for the store of V.
     for ( ; Node ; Node = Node->getFirstPred()) {
-
       if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
         if (const PostStmt *P = Node->getLocationAs<PostStmt>())
           if (const DeclStmt *DS = P->getStmtAs<DeclStmt>())
@@ -145,9 +143,11 @@
       // looking for store sites.
       if (Node->getState()->getSVal(R) != V)
         break;
+
+      Last = Node;
     }
 
-    if (!Node || !Last) {
+    if (!Node) {
       satisfied = true;
       return NULL;
     }
@@ -197,6 +197,9 @@
             os << "declared without an initial value";
         }
       }
+      else {
+        os << "initialized here";
+      }
     }
   }
 
@@ -223,7 +226,7 @@
                << " is assigned to ";
     }
     else
-      return NULL;
+      os << "Value assigned to ";
 
     if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
       os << '\'' << *VR->getDecl() << '\'';
@@ -293,12 +296,11 @@
   return NULL;
 }
 
-BugReporterVisitor *
-bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
-                                             const Stmt *S,
-                                             BugReport *report) {
+void bugreporter::addTrackNullOrUndefValueVisitor(const ExplodedNode *N,
+                                                  const Stmt *S,
+                                                  BugReport *report) {
   if (!S || !N)
-    return 0;
+    return;
 
   ProgramStateManager &StateMgr = N->getState()->getStateManager();
 
@@ -314,14 +316,14 @@
   }
 
   if (!N)
-    return 0;
+    return;
   
   ProgramStateRef state = N->getState();
 
   // Walk through lvalue-to-rvalue conversions.
   const Expr *Ex = dyn_cast<Expr>(S);
   if (Ex) {
-    Ex = Ex->IgnoreParenLValueCasts();
+    Ex = Ex->IgnoreParenCasts();
     if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
       if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
         const VarRegion *R =
@@ -331,7 +333,15 @@
         SVal V = state->getRawSVal(loc::MemRegionVal(R));
         report->markInteresting(R);
         report->markInteresting(V);
-        return new FindLastStoreBRVisitor(V, R);
+
+        if (V.getAsLocSymbol()) {
+          BugReporterVisitor *ConstraintTracker
+            = new TrackConstraintBRVisitor(cast<loc::MemRegionVal>(V), false);
+          report->addVisitor(ConstraintTracker);
+        }
+
+        report->addVisitor(new FindLastStoreBRVisitor(V, R));
+        return;
       }
     }
   }
@@ -351,11 +361,10 @@
 
     if (R) {
       report->markInteresting(R);
-      return new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
+      report->addVisitor(new TrackConstraintBRVisitor(loc::MemRegionVal(R),
+                                                      false));
     }
   }
-
-  return 0;
 }
 
 BugReporterVisitor *
@@ -397,7 +406,7 @@
   // The receiver was nil, and hence the method was skipped.
   // Register a BugReporterVisitor to issue a message telling us how
   // the receiver was null.
-  BR.addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Receiver, &BR));
+  bugreporter::addTrackNullOrUndefValueVisitor(N, Receiver, &BR);
   // Issue a message saying that the method was skipped.
   PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
                                      N->getLocationContext());
@@ -707,6 +716,9 @@
                                            BugReporterContext &BRC,
                                            BugReport &report,
                                            const ExplodedNode *N) {
+  // FIXME: If there's already a constraint tracker for this variable,
+  // we shouldn't emit anything here (c.f. the double note in
+  // test/Analysis/inlining/path-notes.c)
   SmallString<256> buf;
   llvm::raw_svector_ostream Out(buf);
   Out << "Assuming " << LhsString << " is ";
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index bf5d1df..b16b233 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -8,7 +8,7 @@
   BlockCounter.cpp
   BugReporter.cpp
   BugReporterVisitors.cpp
-  Calls.cpp
+  CallEvent.cpp
   Checker.cpp
   CheckerContext.cpp
   CheckerHelpers.cpp
@@ -45,6 +45,7 @@
   ClangAttrList
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticCommon
   ClangStmtNodes
   )
 
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
new file mode 100644
index 0000000..5345bd5
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -0,0 +1,862 @@
+//===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file This file defines CallEvent and its subclasses, which represent path-
+/// sensitive instances of different kinds of function and method calls
+/// (C, C++, and Objective-C).
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/AST/ParentMap.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace clang;
+using namespace ento;
+
+QualType CallEvent::getResultType() const {
+  QualType ResultTy = getDeclaredResultType();
+
+  if (ResultTy.isNull())
+    ResultTy = getOriginExpr()->getType();
+
+  return ResultTy;
+}
+
+static bool isCallbackArg(SVal V, QualType T) {
+  // If the parameter is 0, it's harmless.
+  if (V.isZeroConstant())
+    return false;
+
+  // If a parameter is a block or a callback, assume it can modify pointer.
+  if (T->isBlockPointerType() ||
+      T->isFunctionPointerType() ||
+      T->isObjCSelType())
+    return true;
+
+  // Check if a callback is passed inside a struct (for both, struct passed by
+  // reference and by value). Dig just one level into the struct for now.
+
+  if (isa<PointerType>(T) || isa<ReferenceType>(T))
+    T = T->getPointeeType();
+
+  if (const RecordType *RT = T->getAsStructureType()) {
+    const RecordDecl *RD = RT->getDecl();
+    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+         I != E; ++I) {
+      QualType FieldT = I->getType();
+      if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
+        return true;
+    }
+  }
+
+  return false;
+}
+
+bool CallEvent::hasNonZeroCallbackArg() const {
+  unsigned NumOfArgs = getNumArgs();
+
+  // If calling using a function pointer, assume the function does not
+  // have a callback. TODO: We could check the types of the arguments here.
+  if (!getDecl())
+    return false;
+
+  unsigned Idx = 0;
+  for (CallEvent::param_type_iterator I = param_type_begin(),
+                                       E = param_type_end();
+       I != E && Idx < NumOfArgs; ++I, ++Idx) {
+    if (NumOfArgs <= Idx)
+      break;
+
+    if (isCallbackArg(getArgSVal(Idx), *I))
+      return true;
+  }
+  
+  return false;
+}
+
+/// \brief Returns true if a type is a pointer-to-const or reference-to-const
+/// with no further indirection.
+static bool isPointerToConst(QualType Ty) {
+  QualType PointeeTy = Ty->getPointeeType();
+  if (PointeeTy == QualType())
+    return false;
+  if (!PointeeTy.isConstQualified())
+    return false;
+  if (PointeeTy->isAnyPointerType())
+    return false;
+  return true;
+}
+
+// Try to retrieve the function declaration and find the function parameter
+// types which are pointers/references to a non-pointer const.
+// We will not invalidate the corresponding argument regions.
+static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
+                                 const CallEvent &Call) {
+  unsigned Idx = 0;
+  for (CallEvent::param_type_iterator I = Call.param_type_begin(),
+                                      E = Call.param_type_end();
+       I != E; ++I, ++Idx) {
+    if (isPointerToConst(*I))
+      PreserveArgs.insert(Idx);
+  }
+}
+
+ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
+                                              ProgramStateRef Orig) const {
+  ProgramStateRef Result = (Orig ? Orig : getState());
+
+  SmallVector<const MemRegion *, 8> RegionsToInvalidate;
+  getExtraInvalidatedRegions(RegionsToInvalidate);
+
+  // Indexes of arguments whose values will be preserved by the call.
+  llvm::SmallSet<unsigned, 1> PreserveArgs;
+  if (!argumentsMayEscape())
+    findPtrToConstParams(PreserveArgs, *this);
+
+  for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
+    if (PreserveArgs.count(Idx))
+      continue;
+
+    SVal V = getArgSVal(Idx);
+
+    // If we are passing a location wrapped as an integer, unwrap it and
+    // invalidate the values referred by the location.
+    if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
+      V = Wrapped->getLoc();
+    else if (!isa<Loc>(V))
+      continue;
+
+    if (const MemRegion *R = V.getAsRegion()) {
+      // Invalidate the value of the variable passed by reference.
+
+      // Are we dealing with an ElementRegion?  If the element type is
+      // a basic integer type (e.g., char, int) and the underlying region
+      // is a variable region then strip off the ElementRegion.
+      // FIXME: We really need to think about this for the general case
+      //   as sometimes we are reasoning about arrays and other times
+      //   about (char*), etc., is just a form of passing raw bytes.
+      //   e.g., void *p = alloca(); foo((char*)p);
+      if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+        // Checking for 'integral type' is probably too promiscuous, but
+        // we'll leave it in for now until we have a systematic way of
+        // handling all of these cases.  Eventually we need to come up
+        // with an interface to StoreManager so that this logic can be
+        // appropriately 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()->isIntegralOrEnumerationType()) {
+          const MemRegion *superReg = ER->getSuperRegion();
+          if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
+              isa<ObjCIvarRegion>(superReg))
+            R = cast<TypedRegion>(superReg);
+        }
+        // FIXME: What about layers of ElementRegions?
+      }
+
+      // Mark this region for invalidation.  We batch invalidate regions
+      // below for efficiency.
+      RegionsToInvalidate.push_back(R);
+    }
+  }
+
+  // Invalidate designated regions using the batch invalidation API.
+  // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
+  //  global variables.
+  return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(),
+                                   BlockCount, getLocationContext(),
+                                   /*Symbols=*/0, this);
+}
+
+ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
+                                        const ProgramPointTag *Tag) const {
+  if (const Expr *E = getOriginExpr()) {
+    if (IsPreVisit)
+      return PreStmt(E, getLocationContext(), Tag);
+    return PostStmt(E, getLocationContext(), Tag);
+  }
+
+  const Decl *D = getDecl();
+  assert(D && "Cannot get a program point without a statement or decl");  
+
+  SourceLocation Loc = getSourceRange().getBegin();
+  if (IsPreVisit)
+    return PreImplicitCall(D, Loc, getLocationContext(), Tag);
+  return PostImplicitCall(D, Loc, getLocationContext(), Tag);
+}
+
+SVal CallEvent::getArgSVal(unsigned Index) const {
+  const Expr *ArgE = getArgExpr(Index);
+  if (!ArgE)
+    return UnknownVal();
+  return getSVal(ArgE);
+}
+
+SourceRange CallEvent::getArgSourceRange(unsigned Index) const {
+  const Expr *ArgE = getArgExpr(Index);
+  if (!ArgE)
+    return SourceRange();
+  return ArgE->getSourceRange();
+}
+
+void CallEvent::dump() const {
+  dump(llvm::errs());
+}
+
+void CallEvent::dump(raw_ostream &Out) const {
+  ASTContext &Ctx = getState()->getStateManager().getContext();
+  if (const Expr *E = getOriginExpr()) {
+    E->printPretty(Out, 0, Ctx.getPrintingPolicy());
+    Out << "\n";
+    return;
+  }
+
+  if (const Decl *D = getDecl()) {
+    Out << "Call to ";
+    D->print(Out, Ctx.getPrintingPolicy());
+    return;
+  }
+
+  // FIXME: a string representation of the kind would be nice.
+  Out << "Unknown call (type " << getKind() << ")";
+}
+
+
+bool CallEvent::mayBeInlined(const Stmt *S) {
+  // FIXME: Kill this.
+  return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S)
+                          || isa<CXXConstructExpr>(S);
+}
+
+static void addParameterValuesToBindings(const StackFrameContext *CalleeCtx,
+                                         CallEvent::BindingsTy &Bindings,
+                                         SValBuilder &SVB,
+                                         const CallEvent &Call,
+                                         CallEvent::param_iterator I,
+                                         CallEvent::param_iterator E) {
+  MemRegionManager &MRMgr = SVB.getRegionManager();
+
+  unsigned Idx = 0;
+  for (; I != E; ++I, ++Idx) {
+    const ParmVarDecl *ParamDecl = *I;
+    assert(ParamDecl && "Formal parameter has no decl?");
+
+    SVal ArgVal = Call.getArgSVal(Idx);
+    if (!ArgVal.isUnknown()) {
+      Loc ParamLoc = SVB.makeLoc(MRMgr.getVarRegion(ParamDecl, CalleeCtx));
+      Bindings.push_back(std::make_pair(ParamLoc, ArgVal));
+    }
+  }
+
+  // FIXME: Variadic arguments are not handled at all right now.
+}
+
+
+CallEvent::param_iterator AnyFunctionCall::param_begin() const {
+  const FunctionDecl *D = getDecl();
+  if (!D)
+    return 0;
+
+  return D->param_begin();
+}
+
+CallEvent::param_iterator AnyFunctionCall::param_end() const {
+  const FunctionDecl *D = getDecl();
+  if (!D)
+    return 0;
+
+  return D->param_end();
+}
+
+void AnyFunctionCall::getInitialStackFrameContents(
+                                        const StackFrameContext *CalleeCtx,
+                                        BindingsTy &Bindings) const {
+  const FunctionDecl *D = cast<FunctionDecl>(CalleeCtx->getDecl());
+  SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
+  addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
+                               D->param_begin(), D->param_end());
+}
+
+QualType AnyFunctionCall::getDeclaredResultType() const {
+  const FunctionDecl *D = getDecl();
+  if (!D)
+    return QualType();
+
+  return D->getResultType();
+}
+
+bool AnyFunctionCall::argumentsMayEscape() const {
+  if (hasNonZeroCallbackArg())
+    return true;
+
+  const FunctionDecl *D = getDecl();
+  if (!D)
+    return true;
+
+  const IdentifierInfo *II = D->getIdentifier();
+  if (!II)
+    return true;
+
+  // This set of "escaping" APIs is 
+
+  // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
+  //   value into thread local storage. The value can later be retrieved with
+  //   'void *ptheread_getspecific(pthread_key)'. So even thought the
+  //   parameter is 'const void *', the region escapes through the call.
+  if (II->isStr("pthread_setspecific"))
+    return true;
+
+  // - xpc_connection_set_context stores a value which can be retrieved later
+  //   with xpc_connection_get_context.
+  if (II->isStr("xpc_connection_set_context"))
+    return true;
+
+  // - funopen - sets a buffer for future IO calls.
+  if (II->isStr("funopen"))
+    return true;
+
+  StringRef FName = II->getName();
+
+  // - CoreFoundation functions that end with "NoCopy" can free a passed-in
+  //   buffer even if it is const.
+  if (FName.endswith("NoCopy"))
+    return true;
+
+  // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
+  //   be deallocated by NSMapRemove.
+  if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
+    return true;
+
+  // - Many CF containers allow objects to escape through custom
+  //   allocators/deallocators upon container construction. (PR12101)
+  if (FName.startswith("CF") || FName.startswith("CG")) {
+    return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
+           StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
+           StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
+           StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
+           StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
+           StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
+  }
+
+  return false;
+}
+
+
+const FunctionDecl *SimpleCall::getDecl() const {
+  const FunctionDecl *D = getOriginExpr()->getDirectCallee();
+  if (D)
+    return D;
+
+  return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
+}
+
+
+const FunctionDecl *CXXInstanceCall::getDecl() const {
+  const CallExpr *CE = cast_or_null<CallExpr>(getOriginExpr());
+  if (!CE)
+    return AnyFunctionCall::getDecl();
+
+  const FunctionDecl *D = CE->getDirectCallee();
+  if (D)
+    return D;
+
+  return getSVal(CE->getCallee()).getAsFunctionDecl();
+}
+
+void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {
+  if (const MemRegion *R = getCXXThisVal().getAsRegion())
+    Regions.push_back(R);
+}
+
+
+RuntimeDefinition CXXInstanceCall::getRuntimeDefinition() const {
+  // Do we have a decl at all?
+  const Decl *D = getDecl();
+  if (!D)
+    return RuntimeDefinition();
+
+  // If the method is non-virtual, we know we can inline it.
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
+  if (!MD->isVirtual())
+    return AnyFunctionCall::getRuntimeDefinition();
+
+  // Do we know the implicit 'this' object being called?
+  const MemRegion *R = getCXXThisVal().getAsRegion();
+  if (!R)
+    return RuntimeDefinition();
+
+  // Do we know anything about the type of 'this'?
+  DynamicTypeInfo DynType = getState()->getDynamicTypeInfo(R);
+  if (!DynType.isValid())
+    return RuntimeDefinition();
+
+  // Is the type a C++ class? (This is mostly a defensive check.)
+  QualType RegionType = DynType.getType()->getPointeeType();
+  const CXXRecordDecl *RD = RegionType->getAsCXXRecordDecl();
+  if (!RD || !RD->hasDefinition())
+    return RuntimeDefinition();
+
+  // Find the decl for this method in that class.
+  const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD, true);
+  assert(Result && "At the very least the static decl should show up.");
+
+  // Does the decl that we found have an implementation?
+  const FunctionDecl *Definition;
+  if (!Result->hasBody(Definition))
+    return RuntimeDefinition();
+
+  // We found a definition. If we're not sure that this devirtualization is
+  // actually what will happen at runtime, make sure to provide the region so
+  // that ExprEngine can decide what to do with it.
+  if (DynType.canBeASubClass())
+    return RuntimeDefinition(Definition, R->StripCasts());
+  return RuntimeDefinition(Definition, /*DispatchRegion=*/0);
+}
+
+void CXXInstanceCall::getInitialStackFrameContents(
+                                            const StackFrameContext *CalleeCtx,
+                                            BindingsTy &Bindings) const {
+  AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
+
+  // Handle the binding of 'this' in the new stack frame.
+  SVal ThisVal = getCXXThisVal();
+  if (!ThisVal.isUnknown()) {
+    ProgramStateManager &StateMgr = getState()->getStateManager();
+    SValBuilder &SVB = StateMgr.getSValBuilder();
+
+    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+    Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
+
+    // If we devirtualized to a different member function, we need to make sure
+    // we have the proper layering of CXXBaseObjectRegions.
+    if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
+      ASTContext &Ctx = SVB.getContext();
+      const CXXRecordDecl *Class = MD->getParent();
+      QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));
+
+      // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
+      bool Failed;
+      ThisVal = StateMgr.getStoreManager().evalDynamicCast(ThisVal, Ty, Failed);
+      assert(!Failed && "Calling an incorrectly devirtualized method");
+    }
+
+    if (!ThisVal.isUnknown())
+      Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
+  }
+}
+
+
+
+const Expr *CXXMemberCall::getCXXThisExpr() const {
+  return getOriginExpr()->getImplicitObjectArgument();
+}
+
+
+const Expr *CXXMemberOperatorCall::getCXXThisExpr() const {
+  return getOriginExpr()->getArg(0);
+}
+
+
+const BlockDataRegion *BlockCall::getBlockRegion() const {
+  const Expr *Callee = getOriginExpr()->getCallee();
+  const MemRegion *DataReg = getSVal(Callee).getAsRegion();
+
+  return dyn_cast_or_null<BlockDataRegion>(DataReg);
+}
+
+CallEvent::param_iterator BlockCall::param_begin() const {
+  const BlockDecl *D = getBlockDecl();
+  if (!D)
+    return 0;
+  return D->param_begin();
+}
+
+CallEvent::param_iterator BlockCall::param_end() const {
+  const BlockDecl *D = getBlockDecl();
+  if (!D)
+    return 0;
+  return D->param_end();
+}
+
+void BlockCall::getExtraInvalidatedRegions(RegionList &Regions) const {
+  // FIXME: This also needs to invalidate captured globals.
+  if (const MemRegion *R = getBlockRegion())
+    Regions.push_back(R);
+}
+
+void BlockCall::getInitialStackFrameContents(const StackFrameContext *CalleeCtx,
+                                             BindingsTy &Bindings) const {
+  const BlockDecl *D = cast<BlockDecl>(CalleeCtx->getDecl());
+  SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
+  addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
+                               D->param_begin(), D->param_end());
+}
+
+
+QualType BlockCall::getDeclaredResultType() const {
+  const BlockDataRegion *BR = getBlockRegion();
+  if (!BR)
+    return QualType();
+  QualType BlockTy = BR->getCodeRegion()->getLocationType();
+  return cast<FunctionType>(BlockTy->getPointeeType())->getResultType();
+}
+
+
+SVal CXXConstructorCall::getCXXThisVal() const {
+  if (Data)
+    return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
+  return UnknownVal();
+}
+
+void CXXConstructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
+  if (Data)
+    Regions.push_back(static_cast<const MemRegion *>(Data));
+}
+
+void CXXConstructorCall::getInitialStackFrameContents(
+                                             const StackFrameContext *CalleeCtx,
+                                             BindingsTy &Bindings) const {
+  AnyFunctionCall::getInitialStackFrameContents(CalleeCtx, Bindings);
+
+  SVal ThisVal = getCXXThisVal();
+  if (!ThisVal.isUnknown()) {
+    SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
+    const CXXMethodDecl *MD = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+    Loc ThisLoc = SVB.getCXXThis(MD, CalleeCtx);
+    Bindings.push_back(std::make_pair(ThisLoc, ThisVal));
+  }
+}
+
+
+
+SVal CXXDestructorCall::getCXXThisVal() const {
+  if (Data)
+    return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
+  return UnknownVal();
+}
+
+
+CallEvent::param_iterator ObjCMethodCall::param_begin() const {
+  const ObjCMethodDecl *D = getDecl();
+  if (!D)
+    return 0;
+
+  return D->param_begin();
+}
+
+CallEvent::param_iterator ObjCMethodCall::param_end() const {
+  const ObjCMethodDecl *D = getDecl();
+  if (!D)
+    return 0;
+
+  return D->param_end();
+}
+
+void
+ObjCMethodCall::getExtraInvalidatedRegions(RegionList &Regions) const {
+  if (const MemRegion *R = getReceiverSVal().getAsRegion())
+    Regions.push_back(R);
+}
+
+QualType ObjCMethodCall::getDeclaredResultType() const {
+  const ObjCMethodDecl *D = getDecl();
+  if (!D)
+    return QualType();
+
+  return D->getResultType();
+}
+
+SVal ObjCMethodCall::getReceiverSVal() const {
+  // FIXME: Is this the best way to handle class receivers?
+  if (!isInstanceMessage())
+    return UnknownVal();
+    
+  if (const Expr *RecE = getOriginExpr()->getInstanceReceiver())
+    return getSVal(RecE);
+
+  // An instance message with no expression means we are sending to super.
+  // In this case the object reference is the same as 'self'.
+  const LocationContext *LCtx = getLocationContext();
+  const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
+  assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
+  return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
+}
+
+SourceRange ObjCMethodCall::getSourceRange() const {
+  switch (getMessageKind()) {
+  case OCM_Message:
+    return getOriginExpr()->getSourceRange();
+  case OCM_PropertyAccess:
+  case OCM_Subscript:
+    return getContainingPseudoObjectExpr()->getSourceRange();
+  }
+  llvm_unreachable("unknown message kind");
+}
+
+typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
+
+const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
+  assert(Data != 0 && "Lazy lookup not yet performed.");
+  assert(getMessageKind() != OCM_Message && "Explicit message send.");
+  return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
+}
+
+ObjCMessageKind ObjCMethodCall::getMessageKind() const {
+  if (Data == 0) {
+    ParentMap &PM = getLocationContext()->getParentMap();
+    const Stmt *S = PM.getParent(getOriginExpr());
+    if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
+      const Expr *Syntactic = POE->getSyntacticForm();
+
+      // This handles the funny case of assigning to the result of a getter.
+      // This can happen if the getter returns a non-const reference.
+      if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
+        Syntactic = BO->getLHS();
+
+      ObjCMessageKind K;
+      switch (Syntactic->getStmtClass()) {
+      case Stmt::ObjCPropertyRefExprClass:
+        K = OCM_PropertyAccess;
+        break;
+      case Stmt::ObjCSubscriptRefExprClass:
+        K = OCM_Subscript;
+        break;
+      default:
+        // FIXME: Can this ever happen?
+        K = OCM_Message;
+        break;
+      }
+
+      if (K != OCM_Message) {
+        const_cast<ObjCMethodCall *>(this)->Data
+          = ObjCMessageDataTy(POE, K).getOpaqueValue();
+        assert(getMessageKind() == K);
+        return K;
+      }
+    }
+    
+    const_cast<ObjCMethodCall *>(this)->Data
+      = ObjCMessageDataTy(0, 1).getOpaqueValue();
+    assert(getMessageKind() == OCM_Message);
+    return OCM_Message;
+  }
+
+  ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
+  if (!Info.getPointer())
+    return OCM_Message;
+  return static_cast<ObjCMessageKind>(Info.getInt());
+}
+
+
+bool ObjCMethodCall::canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl,
+                                             Selector Sel) const {
+  assert(IDecl);
+  const SourceManager &SM =
+    getState()->getStateManager().getContext().getSourceManager();
+
+  // If the class interface is declared inside the main file, assume it is not
+  // subcassed. 
+  // TODO: It could actually be subclassed if the subclass is private as well.
+  // This is probably very rare.
+  SourceLocation InterfLoc = IDecl->getEndOfDefinitionLoc();
+  if (InterfLoc.isValid() && SM.isFromMainFile(InterfLoc))
+    return false;
+
+  // Assume that property accessors are not overridden.
+  if (getMessageKind() == OCM_PropertyAccess)
+    return false;
+
+  // We assume that if the method is public (declared outside of main file) or
+  // has a parent which publicly declares the method, the method could be
+  // overridden in a subclass.
+
+  // Find the first declaration in the class hierarchy that declares
+  // the selector.
+  ObjCMethodDecl *D = 0;
+  while (true) {
+    D = IDecl->lookupMethod(Sel, true);
+
+    // Cannot find a public definition.
+    if (!D)
+      return false;
+
+    // If outside the main file,
+    if (D->getLocation().isValid() && !SM.isFromMainFile(D->getLocation()))
+      return true;
+
+    if (D->isOverriding()) {
+      // Search in the superclass on the next iteration.
+      IDecl = D->getClassInterface();
+      if (!IDecl)
+        return false;
+
+      IDecl = IDecl->getSuperClass();
+      if (!IDecl)
+        return false;
+
+      continue;
+    }
+
+    return false;
+  };
+
+  llvm_unreachable("The while loop should always terminate.");
+}
+
+RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
+  const ObjCMessageExpr *E = getOriginExpr();
+  assert(E);
+  Selector Sel = E->getSelector();
+
+  if (E->isInstanceMessage()) {
+
+    // Find the the receiver type.
+    const ObjCObjectPointerType *ReceiverT = 0;
+    bool CanBeSubClassed = false;
+    QualType SupersType = E->getSuperType();
+    const MemRegion *Receiver = 0;
+
+    if (!SupersType.isNull()) {
+      // Super always means the type of immediate predecessor to the method
+      // where the call occurs.
+      ReceiverT = cast<ObjCObjectPointerType>(SupersType);
+    } else {
+      Receiver = getReceiverSVal().getAsRegion();
+      if (!Receiver)
+        return RuntimeDefinition();
+
+      DynamicTypeInfo DTI = getState()->getDynamicTypeInfo(Receiver);
+      QualType DynType = DTI.getType();
+      CanBeSubClassed = DTI.canBeASubClass();
+      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
+
+      if (ReceiverT && CanBeSubClassed)
+        if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
+          if (!canBeOverridenInSubclass(IDecl, Sel))
+            CanBeSubClassed = false;
+    }
+
+    // Lookup the method implementation.
+    if (ReceiverT)
+      if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
+        const ObjCMethodDecl *MD = IDecl->lookupPrivateMethod(Sel);
+        if (CanBeSubClassed)
+          return RuntimeDefinition(MD, Receiver);
+        else
+          return RuntimeDefinition(MD, 0);
+      }
+
+  } else {
+    // This is a class method.
+    // If we have type info for the receiver class, we are calling via
+    // class name.
+    if (ObjCInterfaceDecl *IDecl = E->getReceiverInterface()) {
+      // Find/Return the method implementation.
+      return RuntimeDefinition(IDecl->lookupPrivateClassMethod(Sel));
+    }
+  }
+
+  return RuntimeDefinition();
+}
+
+void ObjCMethodCall::getInitialStackFrameContents(
+                                             const StackFrameContext *CalleeCtx,
+                                             BindingsTy &Bindings) const {
+  const ObjCMethodDecl *D = cast<ObjCMethodDecl>(CalleeCtx->getDecl());
+  SValBuilder &SVB = getState()->getStateManager().getSValBuilder();
+  addParameterValuesToBindings(CalleeCtx, Bindings, SVB, *this,
+                               D->param_begin(), D->param_end());
+
+  SVal SelfVal = getReceiverSVal();
+  if (!SelfVal.isUnknown()) {
+    const VarDecl *SelfD = CalleeCtx->getAnalysisDeclContext()->getSelfDecl();
+    MemRegionManager &MRMgr = SVB.getRegionManager();
+    Loc SelfLoc = SVB.makeLoc(MRMgr.getVarRegion(SelfD, CalleeCtx));
+    Bindings.push_back(std::make_pair(SelfLoc, SelfVal));
+  }
+}
+
+CallEventRef<>
+CallEventManager::getSimpleCall(const CallExpr *CE, ProgramStateRef State,
+                                const LocationContext *LCtx) {
+  if (const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE))
+    return create<CXXMemberCall>(MCE, State, LCtx);
+
+  if (const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
+    const FunctionDecl *DirectCallee = OpCE->getDirectCallee();
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
+      if (MD->isInstance())
+        return create<CXXMemberOperatorCall>(OpCE, State, LCtx);
+
+  } else if (CE->getCallee()->getType()->isBlockPointerType()) {
+    return create<BlockCall>(CE, State, LCtx);
+  }
+
+  // Otherwise, it's a normal function call, static member function call, or
+  // something we can't reason about.
+  return create<FunctionCall>(CE, State, LCtx);
+}
+
+
+CallEventRef<>
+CallEventManager::getCaller(const StackFrameContext *CalleeCtx,
+                            ProgramStateRef State) {
+  const LocationContext *ParentCtx = CalleeCtx->getParent();
+  const LocationContext *CallerCtx = ParentCtx->getCurrentStackFrame();
+  assert(CallerCtx && "This should not be used for top-level stack frames");
+
+  const Stmt *CallSite = CalleeCtx->getCallSite();
+
+  if (CallSite) {
+    if (const CallExpr *CE = dyn_cast<CallExpr>(CallSite))
+      return getSimpleCall(CE, State, CallerCtx);
+
+    switch (CallSite->getStmtClass()) {
+    case Stmt::CXXConstructExprClass: {
+      SValBuilder &SVB = State->getStateManager().getSValBuilder();
+      const CXXMethodDecl *Ctor = cast<CXXMethodDecl>(CalleeCtx->getDecl());
+      Loc ThisPtr = SVB.getCXXThis(Ctor, CalleeCtx);
+      SVal ThisVal = State->getSVal(ThisPtr);
+
+      return getCXXConstructorCall(cast<CXXConstructExpr>(CallSite),
+                                   ThisVal.getAsRegion(), State, CallerCtx);
+    }
+    case Stmt::CXXNewExprClass:
+      return getCXXAllocatorCall(cast<CXXNewExpr>(CallSite), State, CallerCtx);
+    case Stmt::ObjCMessageExprClass:
+      return getObjCMethodCall(cast<ObjCMessageExpr>(CallSite),
+                               State, CallerCtx);
+    default:
+      llvm_unreachable("This is not an inlineable statement.");
+    }
+  }
+
+  // Fall back to the CFG. The only thing we haven't handled yet is
+  // destructors, though this could change in the future.
+  const CFGBlock *B = CalleeCtx->getCallSiteBlock();
+  CFGElement E = (*B)[CalleeCtx->getIndex()];
+  assert(isa<CFGImplicitDtor>(E) && "All other CFG elements should have exprs");
+  assert(!isa<CFGTemporaryDtor>(E) && "We don't handle temporaries yet");
+
+  SValBuilder &SVB = State->getStateManager().getSValBuilder();
+  const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(CalleeCtx->getDecl());
+  Loc ThisPtr = SVB.getCXXThis(Dtor, CalleeCtx);
+  SVal ThisVal = State->getSVal(ThisPtr);
+
+  const Stmt *Trigger;
+  if (const CFGAutomaticObjDtor *AutoDtor = dyn_cast<CFGAutomaticObjDtor>(&E))
+    Trigger = AutoDtor->getTriggerStmt();
+  else
+    Trigger = Dtor->getBody();
+
+  return getCXXDestructorCall(Dtor, Trigger, ThisVal.getAsRegion(),
+                              State, CallerCtx);
+}
diff --git a/lib/StaticAnalyzer/Core/Calls.cpp b/lib/StaticAnalyzer/Core/Calls.cpp
deleted file mode 100644
index 22fea32..0000000
--- a/lib/StaticAnalyzer/Core/Calls.cpp
+++ /dev/null
@@ -1,595 +0,0 @@
-//===- Calls.cpp - Wrapper for all function and method calls ------*- C++ -*--//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file This file defines CallEvent and its subclasses, which represent path-
-/// sensitive instances of different kinds of function and method calls
-/// (C, C++, and Objective-C).
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
-#include "clang/Analysis/ProgramPoint.h"
-#include "clang/AST/ParentMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/StringExtras.h"
-
-using namespace clang;
-using namespace ento;
-
-QualType CallEvent::getResultType() const {
-  QualType ResultTy = getDeclaredResultType();
-
-  if (ResultTy.isNull())
-    ResultTy = getOriginExpr()->getType();
-
-  return ResultTy;
-}
-
-static bool isCallbackArg(SVal V, QualType T) {
-  // If the parameter is 0, it's harmless.
-  if (V.isZeroConstant())
-    return false;
-
-  // If a parameter is a block or a callback, assume it can modify pointer.
-  if (T->isBlockPointerType() ||
-      T->isFunctionPointerType() ||
-      T->isObjCSelType())
-    return true;
-
-  // Check if a callback is passed inside a struct (for both, struct passed by
-  // reference and by value). Dig just one level into the struct for now.
-
-  if (isa<PointerType>(T) || isa<ReferenceType>(T))
-    T = T->getPointeeType();
-
-  if (const RecordType *RT = T->getAsStructureType()) {
-    const RecordDecl *RD = RT->getDecl();
-    for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
-         I != E; ++I) {
-      QualType FieldT = I->getType();
-      if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
-        return true;
-    }
-  }
-
-  return false;
-}
-
-bool CallEvent::hasNonZeroCallbackArg() const {
-  unsigned NumOfArgs = getNumArgs();
-
-  // If calling using a function pointer, assume the function does not
-  // have a callback. TODO: We could check the types of the arguments here.
-  if (!getDecl())
-    return false;
-
-  unsigned Idx = 0;
-  for (CallEvent::param_type_iterator I = param_type_begin(),
-                                       E = param_type_end();
-       I != E && Idx < NumOfArgs; ++I, ++Idx) {
-    if (NumOfArgs <= Idx)
-      break;
-
-    if (isCallbackArg(getArgSVal(Idx), *I))
-      return true;
-  }
-  
-  return false;
-}
-
-/// \brief Returns true if a type is a pointer-to-const or reference-to-const
-/// with no further indirection.
-static bool isPointerToConst(QualType Ty) {
-  QualType PointeeTy = Ty->getPointeeType();
-  if (PointeeTy == QualType())
-    return false;
-  if (!PointeeTy.isConstQualified())
-    return false;
-  if (PointeeTy->isAnyPointerType())
-    return false;
-  return true;
-}
-
-// Try to retrieve the function declaration and find the function parameter
-// types which are pointers/references to a non-pointer const.
-// We will not invalidate the corresponding argument regions.
-static void findPtrToConstParams(llvm::SmallSet<unsigned, 1> &PreserveArgs,
-                                 const CallEvent &Call) {
-  unsigned Idx = 0;
-  for (CallEvent::param_type_iterator I = Call.param_type_begin(),
-                                      E = Call.param_type_end();
-       I != E; ++I, ++Idx) {
-    if (isPointerToConst(*I))
-      PreserveArgs.insert(Idx);
-  }
-}
-
-ProgramStateRef CallEvent::invalidateRegions(unsigned BlockCount,
-                                              ProgramStateRef Orig) const {
-  ProgramStateRef Result = (Orig ? Orig : getState());
-
-  SmallVector<const MemRegion *, 8> RegionsToInvalidate;
-  getExtraInvalidatedRegions(RegionsToInvalidate);
-
-  // Indexes of arguments whose values will be preserved by the call.
-  llvm::SmallSet<unsigned, 1> PreserveArgs;
-  if (!argumentsMayEscape())
-    findPtrToConstParams(PreserveArgs, *this);
-
-  for (unsigned Idx = 0, Count = getNumArgs(); Idx != Count; ++Idx) {
-    if (PreserveArgs.count(Idx))
-      continue;
-
-    SVal V = getArgSVal(Idx);
-
-    // If we are passing a location wrapped as an integer, unwrap it and
-    // invalidate the values referred by the location.
-    if (nonloc::LocAsInteger *Wrapped = dyn_cast<nonloc::LocAsInteger>(&V))
-      V = Wrapped->getLoc();
-    else if (!isa<Loc>(V))
-      continue;
-
-    if (const MemRegion *R = V.getAsRegion()) {
-      // Invalidate the value of the variable passed by reference.
-
-      // Are we dealing with an ElementRegion?  If the element type is
-      // a basic integer type (e.g., char, int) and the underlying region
-      // is a variable region then strip off the ElementRegion.
-      // FIXME: We really need to think about this for the general case
-      //   as sometimes we are reasoning about arrays and other times
-      //   about (char*), etc., is just a form of passing raw bytes.
-      //   e.g., void *p = alloca(); foo((char*)p);
-      if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
-        // Checking for 'integral type' is probably too promiscuous, but
-        // we'll leave it in for now until we have a systematic way of
-        // handling all of these cases.  Eventually we need to come up
-        // with an interface to StoreManager so that this logic can be
-        // appropriately 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()->isIntegralOrEnumerationType()) {
-          const MemRegion *superReg = ER->getSuperRegion();
-          if (isa<VarRegion>(superReg) || isa<FieldRegion>(superReg) ||
-              isa<ObjCIvarRegion>(superReg))
-            R = cast<TypedRegion>(superReg);
-        }
-        // FIXME: What about layers of ElementRegions?
-      }
-
-      // Mark this region for invalidation.  We batch invalidate regions
-      // below for efficiency.
-      RegionsToInvalidate.push_back(R);
-    }
-  }
-
-  // Invalidate designated regions using the batch invalidation API.
-  // NOTE: Even if RegionsToInvalidate is empty, we may still invalidate
-  //  global variables.
-  return Result->invalidateRegions(RegionsToInvalidate, getOriginExpr(),
-                                   BlockCount, getLocationContext(),
-                                   /*Symbols=*/0, this);
-}
-
-ProgramPoint CallEvent::getProgramPoint(bool IsPreVisit,
-                                        const ProgramPointTag *Tag) const {
-  if (const Expr *E = getOriginExpr()) {
-    if (IsPreVisit)
-      return PreStmt(E, getLocationContext(), Tag);
-    return PostStmt(E, getLocationContext(), Tag);
-  }
-
-  const Decl *D = getDecl();
-  assert(D && "Cannot get a program point without a statement or decl");  
-
-  SourceLocation Loc = getSourceRange().getBegin();
-  if (IsPreVisit)
-    return PreImplicitCall(D, Loc, getLocationContext(), Tag);
-  return PostImplicitCall(D, Loc, getLocationContext(), Tag);
-}
-
-
-bool CallEvent::mayBeInlined(const Stmt *S) {
-  return isa<CallExpr>(S);
-}
-
-
-CallEvent::param_iterator
-AnyFunctionCall::param_begin(bool UseDefinitionParams) const {
-  bool IgnoredDynamicDispatch;
-  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
-                                      : getDecl();
-  if (!D)
-    return 0;
-
-  return cast<FunctionDecl>(D)->param_begin();
-}
-
-CallEvent::param_iterator
-AnyFunctionCall::param_end(bool UseDefinitionParams) const {
-  bool IgnoredDynamicDispatch;
-  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
-                                      : getDecl();
-  if (!D)
-    return 0;
-
-  return cast<FunctionDecl>(D)->param_end();
-}
-
-QualType AnyFunctionCall::getDeclaredResultType() const {
-  const FunctionDecl *D = getDecl();
-  if (!D)
-    return QualType();
-
-  return D->getResultType();
-}
-
-bool AnyFunctionCall::argumentsMayEscape() const {
-  if (hasNonZeroCallbackArg())
-    return true;
-
-  const FunctionDecl *D = getDecl();
-  if (!D)
-    return true;
-
-  const IdentifierInfo *II = D->getIdentifier();
-  if (!II)
-    return true;
-
-  // This set of "escaping" APIs is 
-
-  // - 'int pthread_setspecific(ptheread_key k, const void *)' stores a
-  //   value into thread local storage. The value can later be retrieved with
-  //   'void *ptheread_getspecific(pthread_key)'. So even thought the
-  //   parameter is 'const void *', the region escapes through the call.
-  if (II->isStr("pthread_setspecific"))
-    return true;
-
-  // - xpc_connection_set_context stores a value which can be retrieved later
-  //   with xpc_connection_get_context.
-  if (II->isStr("xpc_connection_set_context"))
-    return true;
-
-  // - funopen - sets a buffer for future IO calls.
-  if (II->isStr("funopen"))
-    return true;
-
-  StringRef FName = II->getName();
-
-  // - CoreFoundation functions that end with "NoCopy" can free a passed-in
-  //   buffer even if it is const.
-  if (FName.endswith("NoCopy"))
-    return true;
-
-  // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
-  //   be deallocated by NSMapRemove.
-  if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
-    return true;
-
-  // - Many CF containers allow objects to escape through custom
-  //   allocators/deallocators upon container construction. (PR12101)
-  if (FName.startswith("CF") || FName.startswith("CG")) {
-    return StrInStrNoCase(FName, "InsertValue")  != StringRef::npos ||
-           StrInStrNoCase(FName, "AddValue")     != StringRef::npos ||
-           StrInStrNoCase(FName, "SetValue")     != StringRef::npos ||
-           StrInStrNoCase(FName, "WithData")     != StringRef::npos ||
-           StrInStrNoCase(FName, "AppendValue")  != StringRef::npos ||
-           StrInStrNoCase(FName, "SetAttribute") != StringRef::npos;
-  }
-
-  return false;
-}
-
-SVal AnyFunctionCall::getArgSVal(unsigned Index) const {
-  const Expr *ArgE = getArgExpr(Index);
-  if (!ArgE)
-    return UnknownVal();
-  return getSVal(ArgE);
-}
-
-SourceRange AnyFunctionCall::getArgSourceRange(unsigned Index) const {
-  const Expr *ArgE = getArgExpr(Index);
-  if (!ArgE)
-    return SourceRange();
-  return ArgE->getSourceRange();
-}
-
-
-const FunctionDecl *SimpleCall::getDecl() const {
-  const FunctionDecl *D = getOriginExpr()->getDirectCallee();
-  if (D)
-    return D;
-
-  return getSVal(getOriginExpr()->getCallee()).getAsFunctionDecl();
-}
-
-void CallEvent::dump(raw_ostream &Out) const {
-  ASTContext &Ctx = getState()->getStateManager().getContext();
-  if (const Expr *E = getOriginExpr()) {
-    E->printPretty(Out, Ctx, 0, Ctx.getLangOpts());
-    Out << "\n";
-    return;
-  }
-
-  if (const Decl *D = getDecl()) {
-    Out << "Call to ";
-    D->print(Out, Ctx.getLangOpts());
-    return;
-  }
-
-  // FIXME: a string representation of the kind would be nice.
-  Out << "Unknown call (type " << getKind() << ")";
-}
-
-
-void CXXInstanceCall::getExtraInvalidatedRegions(RegionList &Regions) const {
-  if (const MemRegion *R = getCXXThisVal().getAsRegion())
-    Regions.push_back(R);
-}
-
-static const CXXMethodDecl *devirtualize(const CXXMethodDecl *MD, SVal ThisVal){
-  const MemRegion *R = ThisVal.getAsRegion();
-  if (!R)
-    return 0;
-
-  const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R->StripCasts());
-  if (!TR)
-    return 0;
-
-  const CXXRecordDecl *RD = TR->getValueType()->getAsCXXRecordDecl();
-  if (!RD)
-    return 0;
-
-  const CXXMethodDecl *Result = MD->getCorrespondingMethodInClass(RD);
-  const FunctionDecl *Definition;
-  if (!Result->hasBody(Definition))
-    return 0;
-
-  return cast<CXXMethodDecl>(Definition);
-}
-
-
-const Decl *CXXInstanceCall::getDefinition(bool &IsDynamicDispatch) const {
-  const Decl *D = SimpleCall::getDefinition(IsDynamicDispatch);
-  if (!D)
-    return 0;
-
-  const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
-  if (!MD->isVirtual())
-    return MD;
-
-  // If the method is virtual, see if we can find the actual implementation
-  // based on context-sensitivity.
-  if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
-    return Devirtualized;
-
-  IsDynamicDispatch = true;
-  return MD;
-}
-
-
-SVal CXXMemberCall::getCXXThisVal() const {
-  const Expr *Base = getOriginExpr()->getImplicitObjectArgument();
-
-  // FIXME: Will eventually need to cope with member pointers.  This is
-  // a limitation in getImplicitObjectArgument().
-  if (!Base)
-    return UnknownVal();
-
-  return getSVal(Base);
-}
-
-
-SVal CXXMemberOperatorCall::getCXXThisVal() const {
-  const Expr *Base = getOriginExpr()->getArg(0);
-  return getSVal(Base);
-}
-
-
-const BlockDataRegion *BlockCall::getBlockRegion() const {
-  const Expr *Callee = getOriginExpr()->getCallee();
-  const MemRegion *DataReg = getSVal(Callee).getAsRegion();
-
-  return dyn_cast_or_null<BlockDataRegion>(DataReg);
-}
-
-CallEvent::param_iterator
-BlockCall::param_begin(bool UseDefinitionParams) const {
-  // Blocks don't have distinct declarations and definitions.
-  (void)UseDefinitionParams;
-
-  const BlockDecl *D = getBlockDecl();
-  if (!D)
-    return 0;
-  return D->param_begin();
-}
-
-CallEvent::param_iterator
-BlockCall::param_end(bool UseDefinitionParams) const {
-  // Blocks don't have distinct declarations and definitions.
-  (void)UseDefinitionParams;
-
-  const BlockDecl *D = getBlockDecl();
-  if (!D)
-    return 0;
-  return D->param_end();
-}
-
-void BlockCall::getExtraInvalidatedRegions(RegionList &Regions) const {
-  // FIXME: This also needs to invalidate captured globals.
-  if (const MemRegion *R = getBlockRegion())
-    Regions.push_back(R);
-}
-
-QualType BlockCall::getDeclaredResultType() const {
-  const BlockDataRegion *BR = getBlockRegion();
-  if (!BR)
-    return QualType();
-  QualType BlockTy = BR->getCodeRegion()->getLocationType();
-  return cast<FunctionType>(BlockTy->getPointeeType())->getResultType();
-}
-
-
-SVal CXXConstructorCall::getCXXThisVal() const {
-  if (Data)
-    return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
-  return UnknownVal();
-}
-
-void CXXConstructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
-  if (Data)
-    Regions.push_back(static_cast<const MemRegion *>(Data));
-}
-
-
-SVal CXXDestructorCall::getCXXThisVal() const {
-  if (Data)
-    return loc::MemRegionVal(static_cast<const MemRegion *>(Data));
-  return UnknownVal();
-}
-
-void CXXDestructorCall::getExtraInvalidatedRegions(RegionList &Regions) const {
-  if (Data)
-    Regions.push_back(static_cast<const MemRegion *>(Data));
-}
-
-const Decl *CXXDestructorCall::getDefinition(bool &IsDynamicDispatch) const {
-  const Decl *D = AnyFunctionCall::getDefinition(IsDynamicDispatch);
-  if (!D)
-    return 0;
-
-  const CXXMethodDecl *MD = cast<CXXMethodDecl>(D);
-  if (!MD->isVirtual())
-    return MD;
-
-  // If the method is virtual, see if we can find the actual implementation
-  // based on context-sensitivity.
-  if (const CXXMethodDecl *Devirtualized = devirtualize(MD, getCXXThisVal()))
-    return Devirtualized;
-
-  IsDynamicDispatch = true;
-  return MD;
-}
-
-
-CallEvent::param_iterator
-ObjCMethodCall::param_begin(bool UseDefinitionParams) const {
-  bool IgnoredDynamicDispatch;
-  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
-                                      : getDecl();
-  if (!D)
-    return 0;
-
-  return cast<ObjCMethodDecl>(D)->param_begin();
-}
-
-CallEvent::param_iterator
-ObjCMethodCall::param_end(bool UseDefinitionParams) const {
-  bool IgnoredDynamicDispatch;
-  const Decl *D = UseDefinitionParams ? getDefinition(IgnoredDynamicDispatch)
-                                      : getDecl();
-  if (!D)
-    return 0;
-
-  return cast<ObjCMethodDecl>(D)->param_end();
-}
-
-void
-ObjCMethodCall::getExtraInvalidatedRegions(RegionList &Regions) const {
-  if (const MemRegion *R = getReceiverSVal().getAsRegion())
-    Regions.push_back(R);
-}
-
-QualType ObjCMethodCall::getDeclaredResultType() const {
-  const ObjCMethodDecl *D = getDecl();
-  if (!D)
-    return QualType();
-
-  return D->getResultType();
-}
-
-SVal ObjCMethodCall::getReceiverSVal() const {
-  // FIXME: Is this the best way to handle class receivers?
-  if (!isInstanceMessage())
-    return UnknownVal();
-    
-  if (const Expr *Base = getOriginExpr()->getInstanceReceiver())
-    return getSVal(Base);
-
-  // An instance message with no expression means we are sending to super.
-  // In this case the object reference is the same as 'self'.
-  const LocationContext *LCtx = getLocationContext();
-  const ImplicitParamDecl *SelfDecl = LCtx->getSelfDecl();
-  assert(SelfDecl && "No message receiver Expr, but not in an ObjC method");
-  return getState()->getSVal(getState()->getRegion(SelfDecl, LCtx));
-}
-
-SourceRange ObjCMethodCall::getSourceRange() const {
-  switch (getMessageKind()) {
-  case OCM_Message:
-    return getOriginExpr()->getSourceRange();
-  case OCM_PropertyAccess:
-  case OCM_Subscript:
-    return getContainingPseudoObjectExpr()->getSourceRange();
-  }
-  llvm_unreachable("unknown message kind");
-}
-
-typedef llvm::PointerIntPair<const PseudoObjectExpr *, 2> ObjCMessageDataTy;
-
-const PseudoObjectExpr *ObjCMethodCall::getContainingPseudoObjectExpr() const {
-  assert(Data != 0 && "Lazy lookup not yet performed.");
-  assert(getMessageKind() != OCM_Message && "Explicit message send.");
-  return ObjCMessageDataTy::getFromOpaqueValue(Data).getPointer();
-}
-
-ObjCMessageKind ObjCMethodCall::getMessageKind() const {
-  if (Data == 0) {
-    ParentMap &PM = getLocationContext()->getParentMap();
-    const Stmt *S = PM.getParent(getOriginExpr());
-    if (const PseudoObjectExpr *POE = dyn_cast_or_null<PseudoObjectExpr>(S)) {
-      const Expr *Syntactic = POE->getSyntacticForm();
-
-      // This handles the funny case of assigning to the result of a getter.
-      // This can happen if the getter returns a non-const reference.
-      if (const BinaryOperator *BO = dyn_cast<BinaryOperator>(Syntactic))
-        Syntactic = BO->getLHS();
-
-      ObjCMessageKind K;
-      switch (Syntactic->getStmtClass()) {
-      case Stmt::ObjCPropertyRefExprClass:
-        K = OCM_PropertyAccess;
-        break;
-      case Stmt::ObjCSubscriptRefExprClass:
-        K = OCM_Subscript;
-        break;
-      default:
-        // FIXME: Can this ever happen?
-        K = OCM_Message;
-        break;
-      }
-
-      if (K != OCM_Message) {
-        const_cast<ObjCMethodCall *>(this)->Data
-          = ObjCMessageDataTy(POE, K).getOpaqueValue();
-        assert(getMessageKind() == K);
-        return K;
-      }
-    }
-    
-    const_cast<ObjCMethodCall *>(this)->Data
-      = ObjCMessageDataTy(0, 1).getOpaqueValue();
-    assert(getMessageKind() == OCM_Message);
-    return OCM_Message;
-  }
-
-  ObjCMessageDataTy Info = ObjCMessageDataTy::getFromOpaqueValue(Data);
-  if (!Info.getPointer())
-    return OCM_Message;
-  return static_cast<ObjCMessageKind>(Info.getInt());
-}
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 591609d..c786655 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -14,7 +14,7 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/AST/DeclBase.h"
 
@@ -140,7 +140,7 @@
     const CheckersTy &Checkers;
     const Stmt *S;
     ExprEngine &Eng;
-    bool wasInlined;
+    bool WasInlined;
 
     CheckersTy::const_iterator checkers_begin() { return Checkers.begin(); }
     CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
@@ -148,7 +148,7 @@
     CheckStmtContext(bool isPreVisit, const CheckersTy &checkers,
                      const Stmt *s, ExprEngine &eng, bool wasInlined = false)
       : IsPreVisit(isPreVisit), Checkers(checkers), S(s), Eng(eng),
-        wasInlined(wasInlined) {}
+        WasInlined(wasInlined) {}
 
     void runChecker(CheckerManager::CheckStmtFunc checkFn,
                     NodeBuilder &Bldr, ExplodedNode *Pred) {
@@ -157,7 +157,7 @@
                                            ProgramPoint::PostStmtKind;
       const ProgramPoint &L = ProgramPoint::getProgramPoint(S, K,
                                 Pred->getLocationContext(), checkFn.Checker);
-      CheckerContext C(Bldr, Eng, Pred, L, wasInlined);
+      CheckerContext C(Bldr, Eng, Pred, L, WasInlined);
       checkFn(S, C);
     }
   };
@@ -169,16 +169,16 @@
                                         const ExplodedNodeSet &Src,
                                         const Stmt *S,
                                         ExprEngine &Eng,
-                                        bool wasInlined) {
+                                        bool WasInlined) {
   CheckStmtContext C(isPreVisit, *getCachedStmtCheckersFor(S, isPreVisit),
-                     S, Eng, wasInlined);
+                     S, Eng, WasInlined);
   expandGraphWithCheckers(C, Dst, Src);
 }
 
 namespace {
   struct CheckObjCMessageContext {
     typedef std::vector<CheckerManager::CheckObjCMessageFunc> CheckersTy;
-    bool IsPreVisit;
+    bool IsPreVisit, WasInlined;
     const CheckersTy &Checkers;
     const ObjCMethodCall &Msg;
     ExprEngine &Eng;
@@ -187,20 +187,17 @@
     CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
 
     CheckObjCMessageContext(bool isPreVisit, const CheckersTy &checkers,
-                            const ObjCMethodCall &msg, ExprEngine &eng)
-      : IsPreVisit(isPreVisit), Checkers(checkers), Msg(msg), Eng(eng) { }
+                            const ObjCMethodCall &msg, ExprEngine &eng,
+                            bool wasInlined)
+      : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers),
+        Msg(msg), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckObjCMessageFunc checkFn,
                     NodeBuilder &Bldr, ExplodedNode *Pred) {
-      ProgramPoint::Kind K =  IsPreVisit ? ProgramPoint::PreStmtKind :
-                                           ProgramPoint::PostStmtKind;
-      const ProgramPoint &L =
-        ProgramPoint::getProgramPoint(Msg.getOriginExpr(),
-                                      K, Pred->getLocationContext(),
-                                      checkFn.Checker);
-      CheckerContext C(Bldr, Eng, Pred, L);
+      const ProgramPoint &L = Msg.getProgramPoint(IsPreVisit,checkFn.Checker);
+      CheckerContext C(Bldr, Eng, Pred, L, WasInlined);
 
-      checkFn(Msg, C);
+      checkFn(*Msg.cloneWithState<ObjCMethodCall>(Pred->getState()), C);
     }
   };
 }
@@ -210,11 +207,12 @@
                                                ExplodedNodeSet &Dst,
                                                const ExplodedNodeSet &Src,
                                                const ObjCMethodCall &msg,
-                                               ExprEngine &Eng) {
+                                               ExprEngine &Eng,
+                                               bool WasInlined) {
   CheckObjCMessageContext C(isPreVisit,
                             isPreVisit ? PreObjCMessageCheckers
                                        : PostObjCMessageCheckers,
-                            msg, Eng);
+                            msg, Eng, WasInlined);
   expandGraphWithCheckers(C, Dst, Src);
 }
 
@@ -223,7 +221,7 @@
   // Is there a way we can merge the two?
   struct CheckCallContext {
     typedef std::vector<CheckerManager::CheckCallFunc> CheckersTy;
-    bool IsPreVisit;
+    bool IsPreVisit, WasInlined;
     const CheckersTy &Checkers;
     const CallEvent &Call;
     ExprEngine &Eng;
@@ -232,15 +230,17 @@
     CheckersTy::const_iterator checkers_end() { return Checkers.end(); }
 
     CheckCallContext(bool isPreVisit, const CheckersTy &checkers,
-                     const CallEvent &call, ExprEngine &eng)
-    : IsPreVisit(isPreVisit), Checkers(checkers), Call(call), Eng(eng) { }
+                     const CallEvent &call, ExprEngine &eng,
+                     bool wasInlined)
+    : IsPreVisit(isPreVisit), WasInlined(wasInlined), Checkers(checkers),
+      Call(call), Eng(eng) { }
 
     void runChecker(CheckerManager::CheckCallFunc checkFn,
                     NodeBuilder &Bldr, ExplodedNode *Pred) {
-      const ProgramPoint &L = Call.getProgramPoint(IsPreVisit, checkFn.Checker);
-      CheckerContext C(Bldr, Eng, Pred, L);
+      const ProgramPoint &L = Call.getProgramPoint(IsPreVisit,checkFn.Checker);
+      CheckerContext C(Bldr, Eng, Pred, L, WasInlined);
 
-      checkFn(Call, C);
+      checkFn(*Call.cloneWithState(Pred->getState()), C);
     }
   };
 }
@@ -250,11 +250,12 @@
                                              ExplodedNodeSet &Dst,
                                              const ExplodedNodeSet &Src,
                                              const CallEvent &Call,
-                                             ExprEngine &Eng) {
+                                             ExprEngine &Eng,
+                                             bool WasInlined) {
   CheckCallContext C(isPreVisit,
                      isPreVisit ? PreCallCheckers
                                 : PostCallCheckers,
-                     Call, Eng);
+                     Call, Eng, WasInlined);
   expandGraphWithCheckers(C, Dst, Src);
 }
 
@@ -503,9 +504,9 @@
 /// Only one checker will evaluate the call.
 void CheckerManager::runCheckersForEvalCall(ExplodedNodeSet &Dst,
                                             const ExplodedNodeSet &Src,
-                                            const SimpleCall &Call,
+                                            const CallEvent &Call,
                                             ExprEngine &Eng) {
-  const CallExpr *CE = Call.getOriginExpr();
+  const CallExpr *CE = cast<CallExpr>(Call.getOriginExpr());
   for (ExplodedNodeSet::iterator
          NI = Src.begin(), NE = Src.end(); NI != NE; ++NI) {
 
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index c3be8c8..1f13742 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -266,6 +266,7 @@
     default:
       assert(isa<PostStmt>(Loc) ||
              isa<PostInitializer>(Loc) ||
+             isa<PostImplicitCall>(Loc) ||
              isa<CallExitEnd>(Loc));
       HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred);
       break;
@@ -507,7 +508,8 @@
   }
 
   // Do not create extra nodes. Move to the next CFG element.
-  if (isa<PostInitializer>(N->getLocation())) {
+  if (isa<PostInitializer>(N->getLocation()) ||
+      isa<PostImplicitCall>(N->getLocation())) {
     WList->enqueue(N, Block, Idx+1);
     return;
   }
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index 540eb88..52644f7 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -96,6 +96,9 @@
       case Stmt::CXXBindTemporaryExprClass:
         E = cast<CXXBindTemporaryExpr>(E)->getSubExpr();
         continue;
+      case Stmt::SubstNonTypeTemplateParmExprClass:
+        E = cast<SubstNonTypeTemplateParmExpr>(E)->getReplacement();
+        continue;
       case Stmt::ObjCStringLiteralClass: {
         MemRegionManager &MRMgr = svalBuilder.getRegionManager();
         const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(E);
@@ -230,13 +233,6 @@
       RSScaner.scan(X);
       continue;
     }
-
-    // Otherwise the expression is dead with a couple exceptions.
-    // Do not misclean LogicalExpr or ConditionalOperator.  It is dead at the
-    // beginning of itself, but we need its UndefinedVal to determine its
-    // SVal.
-    if (X.isUndef() && cast<UndefinedVal>(X).getData())
-      EBMapRef = EBMapRef.add(BlkExpr, X);
   }
   
   // Go through he deferred locations and add them to the new environment if
diff --git a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
index 5109912..9145565 100644
--- a/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
+++ b/lib/StaticAnalyzer/Core/ExplodedGraph.cpp
@@ -13,7 +13,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/ParentMap.h"
@@ -162,9 +162,18 @@
 // ExplodedNode.
 //===----------------------------------------------------------------------===//
 
-static inline BumpVector<ExplodedNode*>& getVector(void *P) {
-  return *reinterpret_cast<BumpVector<ExplodedNode*>*>(P);
-}
+// An NodeGroup's storage type is actually very much like a TinyPtrVector:
+// it can be either a pointer to a single ExplodedNode, or a pointer to a
+// BumpVector allocated with the ExplodedGraph's allocator. This allows the
+// common case of single-node NodeGroups to be implemented with no extra memory.
+//
+// Consequently, each of the NodeGroup methods have up to four cases to handle:
+// 1. The flag is set and this group does not actually contain any nodes.
+// 2. The group is empty, in which case the storage value is null.
+// 3. The group contains a single node.
+// 4. The group contains more than one node.
+typedef BumpVector<ExplodedNode *> ExplodedNodeVector;
+typedef llvm::PointerUnion<ExplodedNode *, ExplodedNodeVector *> GroupStorage;
 
 void ExplodedNode::addPredecessor(ExplodedNode *V, ExplodedGraph &G) {
   assert (!V->isSink());
@@ -176,71 +185,77 @@
 }
 
 void ExplodedNode::NodeGroup::replaceNode(ExplodedNode *node) {
-  assert(getKind() == Size1);
-  P = reinterpret_cast<uintptr_t>(node);
-  assert(getKind() == Size1);
+  assert(!getFlag());
+
+  GroupStorage &Storage = reinterpret_cast<GroupStorage&>(P);
+  assert(Storage.is<ExplodedNode *>());
+  Storage = node;
+  assert(Storage.is<ExplodedNode *>());
 }
 
 void ExplodedNode::NodeGroup::addNode(ExplodedNode *N, ExplodedGraph &G) {
-  assert((reinterpret_cast<uintptr_t>(N) & Mask) == 0x0);
   assert(!getFlag());
 
-  if (getKind() == Size1) {
-    if (ExplodedNode *NOld = getNode()) {
-      BumpVectorContext &Ctx = G.getNodeAllocator();
-      BumpVector<ExplodedNode*> *V = 
-        G.getAllocator().Allocate<BumpVector<ExplodedNode*> >();
-      new (V) BumpVector<ExplodedNode*>(Ctx, 4);
-      
-      assert((reinterpret_cast<uintptr_t>(V) & Mask) == 0x0);
-      V->push_back(NOld, Ctx);
-      V->push_back(N, Ctx);
-      P = reinterpret_cast<uintptr_t>(V) | SizeOther;
-      assert(getPtr() == (void*) V);
-      assert(getKind() == SizeOther);
-    }
-    else {
-      P = reinterpret_cast<uintptr_t>(N);
-      assert(getKind() == Size1);
-    }
+  GroupStorage &Storage = reinterpret_cast<GroupStorage&>(P);
+  if (Storage.isNull()) {
+    Storage = N;
+    assert(Storage.is<ExplodedNode *>());
+    return;
   }
-  else {
-    assert(getKind() == SizeOther);
-    getVector(getPtr()).push_back(N, G.getNodeAllocator());
+
+  ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>();
+
+  if (!V) {
+    // Switch from single-node to multi-node representation.
+    ExplodedNode *Old = Storage.get<ExplodedNode *>();
+
+    BumpVectorContext &Ctx = G.getNodeAllocator();
+    V = G.getAllocator().Allocate<ExplodedNodeVector>();
+    new (V) ExplodedNodeVector(Ctx, 4);
+    V->push_back(Old, Ctx);
+
+    Storage = V;
+    assert(!getFlag());
+    assert(Storage.is<ExplodedNodeVector *>());
   }
+
+  V->push_back(N, G.getNodeAllocator());
 }
 
 unsigned ExplodedNode::NodeGroup::size() const {
   if (getFlag())
     return 0;
 
-  if (getKind() == Size1)
-    return getNode() ? 1 : 0;
-  else
-    return getVector(getPtr()).size();
+  const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
+  if (Storage.isNull())
+    return 0;
+  if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
+    return V->size();
+  return 1;
 }
 
-ExplodedNode **ExplodedNode::NodeGroup::begin() const {
+ExplodedNode * const *ExplodedNode::NodeGroup::begin() const {
   if (getFlag())
-    return NULL;
+    return 0;
 
-  if (getKind() == Size1)
-    return (ExplodedNode**) (getPtr() ? &P : NULL);
-  else
-    return const_cast<ExplodedNode**>(&*(getVector(getPtr()).begin()));
+  const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
+  if (Storage.isNull())
+    return 0;
+  if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
+    return V->begin();
+  return Storage.getAddrOfPtr1();
 }
 
-ExplodedNode** ExplodedNode::NodeGroup::end() const {
+ExplodedNode * const *ExplodedNode::NodeGroup::end() const {
   if (getFlag())
-    return NULL;
+    return 0;
 
-  if (getKind() == Size1)
-    return (ExplodedNode**) (getPtr() ? &P+1 : NULL);
-  else {
-    // Dereferencing end() is undefined behaviour. The vector is not empty, so
-    // we can dereference the last elem and then add 1 to the result.
-    return const_cast<ExplodedNode**>(getVector(getPtr()).end());
-  }
+  const GroupStorage &Storage = reinterpret_cast<const GroupStorage &>(P);
+  if (Storage.isNull())
+    return 0;
+  if (ExplodedNodeVector *V = Storage.dyn_cast<ExplodedNodeVector *>())
+    return V->end();
+  return Storage.getAddrOfPtr1() + 1;
 }
 
 ExplodedNode *ExplodedGraph::getNode(const ProgramPoint &L,
@@ -338,7 +353,8 @@
     }
 
     // Visit our predecessors and enqueue them.
-    for (ExplodedNode** I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I)
+    for (ExplodedNode::pred_iterator I = N->Preds.begin(), E = N->Preds.end();
+         I != E; ++I)
       WL1.push_back(*I);
   }
 
@@ -375,7 +391,8 @@
 
     // Walk through the predecessors of 'N' and hook up their corresponding
     // nodes in the new graph (if any) to the freshly created node.
-    for (ExplodedNode **I=N->Preds.begin(), **E=N->Preds.end(); I!=E; ++I) {
+    for (ExplodedNode::pred_iterator I = N->Preds.begin(), E = N->Preds.end();
+         I != E; ++I) {
       Pass2Ty::iterator PI = Pass2.find(*I);
       if (PI == Pass2.end())
         continue;
@@ -387,7 +404,8 @@
     // been created, we should hook them up as successors.  Otherwise, enqueue
     // the new nodes from the original graph that should have nodes created
     // in the new graph.
-    for (ExplodedNode **I=N->Succs.begin(), **E=N->Succs.end(); I!=E; ++I) {
+    for (ExplodedNode::succ_iterator I = N->Succs.begin(), E = N->Succs.end();
+         I != E; ++I) {
       Pass2Ty::iterator PI = Pass2.find(*I);
       if (PI != Pass2.end()) {
         PI->second->addPredecessor(NewN, *G);
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 895e20e..d766682 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -18,13 +18,12 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/AST/DeclCXX.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/PrettyStackTrace.h"
@@ -278,7 +277,7 @@
     // up. Since no symbols are dead, we can optimize and not clean out
     // the constraint manager.
     StmtNodeBuilder Bldr(Pred, Out, *currentBuilderContext);
-    Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, false, &cleanupTag,K);
+    Bldr.generateNode(DiagnosticStmt, Pred, CleanedState, &cleanupTag, K);
 
   } else {
     // Call checkers with the non-cleaned state so that they could query the
@@ -310,8 +309,7 @@
       // generate a transition to that state.
       ProgramStateRef CleanedCheckerSt =
         StateMgr.getPersistentStateWithGDM(CleanedState, CheckerState);
-      Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, false,
-                        &cleanupTag, K);
+      Bldr.generateNode(DiagnosticStmt, *I, CleanedCheckerSt, &cleanupTag, K);
     }
   }
 }
@@ -357,49 +355,49 @@
 void ExprEngine::ProcessInitializer(const CFGInitializer Init,
                                     ExplodedNode *Pred) {
   ExplodedNodeSet Dst;
+  NodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
+
+  ProgramStateRef State = Pred->getState();
+
+  const CXXCtorInitializer *BMI = Init.getInitializer();
+
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                BMI->getSourceLocation(),
+                                "Error evaluating initializer");
 
   // We don't set EntryNode and currentStmt. And we don't clean up state.
-  const CXXCtorInitializer *BMI = Init.getInitializer();
   const StackFrameContext *stackFrame =
                            cast<StackFrameContext>(Pred->getLocationContext());
   const CXXConstructorDecl *decl =
                            cast<CXXConstructorDecl>(stackFrame->getDecl());
-  SVal thisVal = Pred->getState()->getSVal(svalBuilder.getCXXThis(decl,
-                                                                  stackFrame));
+  SVal thisVal = State->getSVal(svalBuilder.getCXXThis(decl, stackFrame));
 
+  // Evaluate the initializer, if necessary
   if (BMI->isAnyMemberInitializer()) {
-    // Evaluate the initializer.
+    // Constructors build the object directly in the field,
+    // but non-objects must be copied in from the initializer.
+    if (!isa<CXXConstructExpr>(BMI->getInit())) {
+      SVal FieldLoc;
+      if (BMI->isIndirectMemberInitializer())
+        FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal);
+      else
+        FieldLoc = State->getLValue(BMI->getMember(), thisVal);
 
-    StmtNodeBuilder Bldr(Pred, Dst, *currentBuilderContext);
-    ProgramStateRef state = Pred->getState();
-
-    const FieldDecl *FD = BMI->getAnyMember();
-
-    // FIXME: This does not work for initializers that call constructors.
-    SVal FieldLoc = state->getLValue(FD, thisVal);
-    SVal InitVal = state->getSVal(BMI->getInit(), Pred->getLocationContext());
-    state = state->bindLoc(FieldLoc, InitVal);
-
-    // Use a custom node building process.
-    PostInitializer PP(BMI, stackFrame);
-    // Builder automatically add the generated node to the deferred set,
-    // which are processed in the builder's dtor.
-    Bldr.generateNode(PP, Pred, state);
+      SVal InitVal = State->getSVal(BMI->getInit(), stackFrame);
+      State = State->bindLoc(FieldLoc, InitVal);
+    }
   } else {
-    assert(BMI->isBaseInitializer());
-
-    // Get the base class declaration.
-    const CXXConstructExpr *ctorExpr = cast<CXXConstructExpr>(BMI->getInit());
-
-    // Create the base object region.
-    SVal baseVal =
-        getStoreManager().evalDerivedToBase(thisVal, ctorExpr->getType());
-    const MemRegion *baseReg = baseVal.getAsRegion();
-    assert(baseReg);
-
-    VisitCXXConstructExpr(ctorExpr, baseReg, Pred, Dst);
+    assert(BMI->isBaseInitializer() || BMI->isDelegatingInitializer());
+    // We already did all the work when visiting the CXXConstructExpr.
   }
 
+  // Construct a PostInitializer node whether the state changed or not,
+  // so that the diagnostics don't get confused.
+  PostInitializer PP(BMI, stackFrame);
+  // Builder automatically add the generated node to the deferred set,
+  // which are processed in the builder's dtor.
+  Bldr.generateNode(PP, State, Pred);
+
   // Enqueue the new nodes onto the work list.
   Engine.enqueue(Dst, currentBuilderContext->getBlock(), currentStmtIdx);
 }
@@ -439,46 +437,50 @@
   if (const ReferenceType *refType = varType->getAs<ReferenceType>())
     varType = refType->getPointeeType();
 
-  const CXXRecordDecl *recordDecl = varType->getAsCXXRecordDecl();
-  assert(recordDecl && "get CXXRecordDecl fail");
-  const CXXDestructorDecl *dtorDecl = recordDecl->getDestructor();
-
   Loc dest = state->getLValue(varDecl, Pred->getLocationContext());
 
-  VisitCXXDestructor(dtorDecl, cast<loc::MemRegionVal>(dest).getRegion(),
+  VisitCXXDestructor(varType, cast<loc::MemRegionVal>(dest).getRegion(),
                      Dtor.getTriggerStmt(), Pred, Dst);
 }
 
 void ExprEngine::ProcessBaseDtor(const CFGBaseDtor D,
-                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {}
+                                 ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+  const LocationContext *LCtx = Pred->getLocationContext();
+  ProgramStateRef State = Pred->getState();
+
+  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
+  Loc ThisPtr = getSValBuilder().getCXXThis(CurDtor,
+                                            LCtx->getCurrentStackFrame());
+  SVal ThisVal = Pred->getState()->getSVal(ThisPtr);
+
+  // Create the base object region.
+  QualType BaseTy = D.getBaseSpecifier()->getType();
+  SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
+
+  VisitCXXDestructor(BaseTy, cast<loc::MemRegionVal>(BaseVal).getRegion(),
+                     CurDtor->getBody(), Pred, Dst);
+}
 
 void ExprEngine::ProcessMemberDtor(const CFGMemberDtor D,
-                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {}
+                                   ExplodedNode *Pred, ExplodedNodeSet &Dst) {
+  const FieldDecl *Member = D.getFieldDecl();
+  ProgramStateRef State = Pred->getState();
+  const LocationContext *LCtx = Pred->getLocationContext();
+
+  const CXXDestructorDecl *CurDtor = cast<CXXDestructorDecl>(LCtx->getDecl());
+  Loc ThisVal = getSValBuilder().getCXXThis(CurDtor,
+                                            LCtx->getCurrentStackFrame());
+  SVal FieldVal = State->getLValue(Member, cast<Loc>(State->getSVal(ThisVal)));
+
+  VisitCXXDestructor(Member->getType(),
+                     cast<loc::MemRegionVal>(FieldVal).getRegion(),
+                     CurDtor->getBody(), Pred, Dst);
+}
 
 void ExprEngine::ProcessTemporaryDtor(const CFGTemporaryDtor D,
                                       ExplodedNode *Pred,
                                       ExplodedNodeSet &Dst) {}
 
-static const VarDecl *findDirectConstruction(const DeclStmt *DS,
-                                             const Expr *Init) {
-  for (DeclStmt::const_decl_iterator I = DS->decl_begin(), E = DS->decl_end();
-       I != E; ++I) {
-    const VarDecl *Var = dyn_cast<VarDecl>(*I);
-    if (!Var)
-      continue;
-    if (Var->getInit() != Init)
-      continue;
-    // FIXME: We need to decide how copy-elision should work here.
-    if (!Var->isDirectInit())
-      break;
-    if (Var->getType()->isReferenceType())
-      break;
-    return Var;
-  }
-
-  return 0;
-}
-
 void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
                        ExplodedNodeSet &DstTop) {
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
@@ -522,15 +524,13 @@
     case Stmt::SEHExceptStmtClass:
     case Stmt::LambdaExprClass:
     case Stmt::SEHFinallyStmtClass: {
-      const ExplodedNode *node = Bldr.generateNode(S, Pred, Pred->getState(),
-                                                   /* sink */ true);
+      const ExplodedNode *node = Bldr.generateSink(S, Pred, Pred->getState());
       Engine.addAbortedBlock(node, currentBuilderContext->getBlock());
       break;
     }
     
     // We don't handle default arguments either yet, but we can fake it
     // for now by just skipping them.
-    case Stmt::SubstNonTypeTemplateParmExprClass:
     case Stmt::CXXDefaultArgExprClass:
       break;
 
@@ -605,11 +605,6 @@
     case Stmt::AtomicExprClass:
       // Fall through.
 
-    // Currently all handling of 'throw' just falls to the CFG.  We
-    // can consider doing more if necessary.
-    case Stmt::CXXThrowExprClass:
-      // Fall through.
-      
     // Cases we intentionally don't evaluate, since they don't need
     // to be explicitly evaluated.
     case Stmt::AddrLabelExprClass:
@@ -624,6 +619,7 @@
     case Stmt::StringLiteralClass:
     case Stmt::ObjCStringLiteralClass:
     case Stmt::CXXBindTemporaryExprClass:
+    case Stmt::SubstNonTypeTemplateParmExprClass:
     case Stmt::CXXNullPtrLiteralExprClass: {
       Bldr.takeNodes(Pred);
       ExplodedNodeSet preVisit;
@@ -739,20 +735,9 @@
     }
 
     case Stmt::CXXTemporaryObjectExprClass:
-    case Stmt::CXXConstructExprClass: {
-      const CXXConstructExpr *C = cast<CXXConstructExpr>(S);
-      const MemRegion *Target = 0;
-
-      const LocationContext *LCtx = Pred->getLocationContext();
-      const ParentMap &PM = LCtx->getParentMap();
-      if (const DeclStmt *DS = dyn_cast_or_null<DeclStmt>(PM.getParent(C)))
-        if (const VarDecl *Var = findDirectConstruction(DS, C))
-          Target = Pred->getState()->getLValue(Var, LCtx).getAsRegion();
-      // If we don't have a destination region, VisitCXXConstructExpr() will
-      // create one.
-      
+    case Stmt::CXXConstructExprClass: {      
       Bldr.takeNodes(Pred);
-      VisitCXXConstructExpr(C, Target, Pred, Dst);
+      VisitCXXConstructExpr(cast<CXXConstructExpr>(S), Pred, Dst);
       Bldr.addNodes(Dst);
       break;
     }
@@ -888,22 +873,18 @@
       Bldr.addNodes(Dst);
       break;
 
-    case Stmt::ObjCMessageExprClass: {
+    case Stmt::ObjCMessageExprClass:
       Bldr.takeNodes(Pred);
-      VisitObjCMessage(ObjCMethodCall(cast<ObjCMessageExpr>(S),
-                                      Pred->getState(),
-                                      Pred->getLocationContext()),
-                       Pred, Dst);
+      VisitObjCMessage(cast<ObjCMessageExpr>(S), Pred, Dst);
       Bldr.addNodes(Dst);
       break;
-    }
 
-    case Stmt::ObjCAtThrowStmtClass: {
+    case Stmt::ObjCAtThrowStmtClass:
+    case Stmt::CXXThrowExprClass:
       // FIXME: This is not complete.  We basically treat @throw as
       // an abort.
-      Bldr.generateNode(S, Pred, Pred->getState());
+      Bldr.generateSink(S, Pred, Pred->getState());
       break;
-    }
 
     case Stmt::ReturnStmtClass:
       Bldr.takeNodes(Pred);
@@ -1050,7 +1031,7 @@
   if (nodeBuilder.getContext().getCurrentBlockCount() >= AMgr.getMaxVisit()) {
     static SimpleProgramPointTag tag("ExprEngine : Block count exceeded");
     const ExplodedNode *Sink =
-                   nodeBuilder.generateNode(pred->getState(), pred, &tag, true);
+                   nodeBuilder.generateSink(pred->getState(), pred, &tag);
 
     // Check if we stopped at the top level function or not.
     // Root node should have the location context of the top most function.
@@ -1080,63 +1061,6 @@
 // Branch processing.
 //===----------------------------------------------------------------------===//
 
-ProgramStateRef ExprEngine::MarkBranch(ProgramStateRef state,
-                                           const Stmt *Terminator,
-                                           const LocationContext *LCtx,
-                                           bool branchTaken) {
-
-  switch (Terminator->getStmtClass()) {
-    default:
-      return state;
-
-    case Stmt::BinaryOperatorClass: { // '&&' and '||'
-
-      const BinaryOperator* B = cast<BinaryOperator>(Terminator);
-      BinaryOperator::Opcode Op = B->getOpcode();
-
-      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.
-      //
-      // For ||, if we take the false branch, then the value of the whole
-      // expression is that of the RHS expression.
-
-      const Expr *Ex = (Op == BO_LAnd && branchTaken) ||
-                       (Op == BO_LOr && !branchTaken)
-                       ? B->getRHS() : B->getLHS();
-
-      return state->BindExpr(B, LCtx, UndefinedVal(Ex));
-    }
-
-    case Stmt::BinaryConditionalOperatorClass:
-    case Stmt::ConditionalOperatorClass: { // ?:
-      const AbstractConditionalOperator* C
-        = cast<AbstractConditionalOperator>(Terminator);
-
-      // For ?, if branchTaken == true then the value is either the LHS or
-      // the condition itself. (GNU extension).
-
-      const Expr *Ex;
-
-      if (branchTaken)
-        Ex = C->getTrueExpr();
-      else
-        Ex = C->getFalseExpr();
-
-      return state->BindExpr(C, LCtx, UndefinedVal(Ex));
-    }
-
-    case Stmt::ChooseExprClass: { // ?:
-
-      const ChooseExpr *C = cast<ChooseExpr>(Terminator);
-
-      const Expr *Ex = branchTaken ? C->getLHS() : C->getRHS();
-      return state->BindExpr(C, LCtx, UndefinedVal(Ex));
-    }
-  }
-}
-
 /// RecoverCastedSymbol - A helper function for ProcessBranch that is used
 /// to try to recover some path-sensitivity for casts of symbolic
 /// integers that promote their values (which are currently not tracked well).
@@ -1282,14 +1206,10 @@
       }
     }
     
-    const LocationContext *LCtx = PredI->getLocationContext();
-
     // If the condition is still unknown, give up.
     if (X.isUnknownOrUndef()) {
-      builder.generateNode(MarkBranch(PrevState, Term, LCtx, true),
-                           true, PredI);
-      builder.generateNode(MarkBranch(PrevState, Term, LCtx, false),
-                           false, PredI);
+      builder.generateNode(PrevState, true, PredI);
+      builder.generateNode(PrevState, false, PredI);
       continue;
     }
 
@@ -1298,8 +1218,7 @@
     // Process the true branch.
     if (builder.isFeasible(true)) {
       if (ProgramStateRef state = PrevState->assume(V, true))
-        builder.generateNode(MarkBranch(state, Term, LCtx, true),
-                             true, PredI);
+        builder.generateNode(state, true, PredI);
       else
         builder.markInfeasible(true);
     }
@@ -1307,8 +1226,7 @@
     // Process the false branch.
     if (builder.isFeasible(false)) {
       if (ProgramStateRef state = PrevState->assume(V, false))
-        builder.generateNode(MarkBranch(state, Term, LCtx, false),
-                             false, PredI);
+        builder.generateNode(state, false, PredI);
       else
         builder.markInfeasible(false);
     }
@@ -1497,7 +1415,7 @@
         V = UnknownVal();
     }
 
-    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), false, 0,
+    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
                       ProgramPoint::PostLValueKind);
     return;
   }
@@ -1509,19 +1427,18 @@
   }
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     SVal V = svalBuilder.getFunctionPointer(FD);
-    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), false, 0,
+    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V), 0,
                       ProgramPoint::PostLValueKind);
     return;
   }
   if (isa<FieldDecl>(D)) {
-    // FIXME: Compute lvalue of fields.
-    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, UnknownVal()),
-		      false, 0, ProgramPoint::PostLValueKind);
+    // FIXME: Compute lvalue of field pointers-to-member.
+    Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, UnknownVal()), 0,
+		      ProgramPoint::PostLValueKind);
     return;
   }
 
-  assert (false &&
-          "ValueDecl support for this ValueDecl not implemented.");
+  llvm_unreachable("Support for this Decl not implemented.");
 }
 
 /// VisitArraySubscriptExpr - Transfer function for array accesses
@@ -1546,8 +1463,8 @@
                               state->getSVal(Idx, LCtx),
                               state->getSVal(Base, LCtx));
     assert(A->isGLValue());
-    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V),
-                      false, 0, ProgramPoint::PostLValueKind);
+    Bldr.generateNode(A, *it, state->BindExpr(A, LCtx, V), 0, 
+                      ProgramPoint::PostLValueKind);
   }
 }
 
@@ -1602,10 +1519,17 @@
 
   // For all other cases, compute an lvalue.    
   SVal L = state->getLValue(field, baseExprVal);
-  if (M->isGLValue())
-    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), false, 0,
+  if (M->isGLValue()) {
+    if (field->getType()->isReferenceType()) {
+      if (const MemRegion *R = L.getAsRegion())
+        L = state->getSVal(R);
+      else
+        L = UnknownVal();
+    }
+
+    Bldr.generateNode(M, Pred, state->BindExpr(M, LCtx, L), 0,
                       ProgramPoint::PostLValueKind);
-  else {
+  } else {
     Bldr.takeNodes(Pred);
     evalLoad(Dst, M, M, Pred, state, L);
     Bldr.addNodes(Dst);
@@ -1647,7 +1571,7 @@
       LocReg = LocRegVal->getRegion();
 
     const ProgramPoint L = PostStore(StoreE, LC, LocReg, 0);
-    Bldr.generateNode(L, PredI, state, false);
+    Bldr.generateNode(L, state, PredI);
   }
 
   Dst.insert(TmpDst);
@@ -1752,8 +1676,7 @@
       // This is important.  We must nuke the old binding.
       Bldr.generateNode(NodeEx, *NI,
                         state->BindExpr(BoundEx, LCtx, UnknownVal()),
-                        false, tag,
-                        ProgramPoint::PostLoadKind);
+                        tag, ProgramPoint::PostLoadKind);
     }
     else {
       if (LoadTy.isNull())
@@ -1761,7 +1684,7 @@
       SVal V = state->getSVal(cast<Loc>(location), LoadTy);
       Bldr.generateNode(NodeEx, *NI,
                         state->bindExprAndLocation(BoundEx, LCtx, location, V),
-                        false, tag, ProgramPoint::PostLoadKind);
+                        tag, ProgramPoint::PostLoadKind);
     }
   }
 }
@@ -1793,9 +1716,8 @@
     // instead "int *p" is noted as
     // "Variable 'p' initialized to a null pointer value"
     
-    // FIXME: why is 'tag' not used instead of etag?
-    static SimpleProgramPointTag etag("ExprEngine: Location");
-    Bldr.generateNode(NodeEx, Pred, state, false, &etag);
+    static SimpleProgramPointTag tag("ExprEngine: Location");
+    Bldr.generateNode(NodeEx, Pred, state, &tag);
   }
   ExplodedNodeSet Tmp;
   getCheckerManager().runCheckersForLocation(Tmp, Src, location, isLoad,
@@ -1836,14 +1758,14 @@
       if (ProgramStateRef StateTrue = state->assume(*SEV, true)) {
         SVal Val = svalBuilder.makeIntVal(1U, Ex->getType());        
         StateTrue = StateTrue->BindExpr(Ex, Pred->getLocationContext(), Val);
-        Bldr.generateNode(Ex, Pred, StateTrue, false, tags.first);
+        Bldr.generateNode(Ex, Pred, StateTrue, tags.first);
       }
 
       // Next, assume that the condition is false.
       if (ProgramStateRef StateFalse = state->assume(*SEV, false)) {
         SVal Val = svalBuilder.makeIntVal(0U, Ex->getType());
         StateFalse = StateFalse->BindExpr(Ex, Pred->getLocationContext(), Val);
-        Bldr.generateNode(Ex, Pred, StateFalse, false, tags.second);
+        Bldr.generateNode(Ex, Pred, StateFalse, tags.second);
       }
     }
   }
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 0254b75..2895e26 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -211,8 +211,7 @@
   StmtNodeBuilder Bldr(Pred, Tmp, *currentBuilderContext);
   Bldr.generateNode(BE, Pred,
                     State->BindExpr(BE, Pred->getLocationContext(), V),
-                    false, 0,
-                    ProgramPoint::PostLValueKind);
+                    0, ProgramPoint::PostLValueKind);
   
   // FIXME: Move all post/pre visits to ::Visit().
   getCheckerManager().runCheckersForPostStmt(Dst, Tmp, BE, *this);
@@ -318,7 +317,7 @@
         ProgramStateRef state = Pred->getState();
         const LocationContext *LCtx = Pred->getLocationContext();
         SVal val = state->getSVal(Ex, LCtx);
-        val = getStoreManager().evalDerivedToBase(val, T);
+        val = getStoreManager().evalDerivedToBase(val, CastE);
         state = state->BindExpr(CastE, LCtx, val);
         Bldr.generateNode(CastE, Pred, state);
         continue;
@@ -347,7 +346,7 @@
           if (T->isReferenceType()) {
             // A bad_cast exception is thrown if input value is a reference.
             // Currently, we model this, by generating a sink.
-            Bldr.generateNode(CastE, Pred, state, true);
+            Bldr.generateSink(CastE, Pred, state);
             continue;
           } else {
             // If the cast fails on a pointer, bind to 0.
@@ -453,16 +452,17 @@
     const LocationContext *LC = N->getLocationContext();
     
     if (const Expr *InitEx = VD->getInit()) {
-      SVal InitVal = state->getSVal(InitEx, Pred->getLocationContext());
+      SVal InitVal = state->getSVal(InitEx, LC);
 
-      if (InitVal == state->getLValue(VD, LC)) {
+      if (InitVal == state->getLValue(VD, LC) ||
+          (VD->getType()->isArrayType() &&
+           isa<CXXConstructExpr>(InitEx->IgnoreImplicit()))) {
         // We constructed the object directly in the variable.
         // No need to bind anything.
         B.generateNode(DS, N, state);
       } else {
         // We bound the temp obj region to the CXXConstructExpr. Now recover
         // the lazy compound value when the variable is not a reference.
-        // FIXME: This is probably not correct for most constructors!
         if (AMgr.getLangOpts().CPlusPlus && VD->getType()->isRecordType() && 
             !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
           InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
@@ -530,10 +530,28 @@
   else {
     // If there is no terminator, by construction the last statement
     // in SrcBlock is the value of the enclosing expression.
+    // However, we still need to constrain that value to be 0 or 1.
     assert(!SrcBlock->empty());
     CFGStmt Elem = cast<CFGStmt>(*SrcBlock->rbegin());
-    const Stmt *S = Elem.getStmt();
-    X = N->getState()->getSVal(S, Pred->getLocationContext());
+    const Expr *RHS = cast<Expr>(Elem.getStmt());
+    SVal RHSVal = N->getState()->getSVal(RHS, Pred->getLocationContext());
+
+    DefinedOrUnknownSVal DefinedRHS = cast<DefinedOrUnknownSVal>(RHSVal);
+    ProgramStateRef StTrue, StFalse;
+    llvm::tie(StTrue, StFalse) = N->getState()->assume(DefinedRHS);
+    if (StTrue) {
+      if (StFalse) {
+        // We can't constrain the value to 0 or 1; the best we can do is a cast.
+        X = getSValBuilder().evalCast(RHSVal, B->getType(), RHS->getType());
+      } else {
+        // The value is known to be true.
+        X = getSValBuilder().makeIntVal(1, B->getType());
+      }
+    } else {
+      // The value is known to be false.
+      assert(StFalse && "Infeasible path!");
+      X = getSValBuilder().makeIntVal(0, B->getType());
+    }
   }
 
   Bldr.generateNode(B, Pred, state->BindExpr(B, Pred->getLocationContext(), X));
@@ -590,17 +608,41 @@
                                   ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
   StmtNodeBuilder B(Pred, Dst, *currentBuilderContext);
-  
   ProgramStateRef state = Pred->getState();
   const LocationContext *LCtx = Pred->getLocationContext();
-  SVal X = state->getSVal(Ex, LCtx);  
-  assert (X.isUndef());  
-  const Expr *SE = (Expr*) cast<UndefinedVal>(X).getData();
-  assert(SE);
-  X = state->getSVal(SE, LCtx);
-  
-  // Make sure that we invalidate the previous binding.
-  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, X, true));
+  const CFGBlock *SrcBlock = 0;
+
+  for (const ExplodedNode *N = Pred ; N ; N = *N->pred_begin()) {
+    ProgramPoint PP = N->getLocation();
+    if (isa<PreStmtPurgeDeadSymbols>(PP) || isa<BlockEntrance>(PP)) {
+      assert(N->pred_size() == 1);
+      continue;
+    }
+    SrcBlock = cast<BlockEdge>(&PP)->getSrc();
+    break;
+  }
+
+  // Find the last expression in the predecessor block.  That is the
+  // expression that is used for the value of the ternary expression.
+  bool hasValue = false;
+  SVal V;
+
+  for (CFGBlock::const_reverse_iterator I = SrcBlock->rbegin(),
+                                        E = SrcBlock->rend(); I != E; ++I) {
+    CFGElement CE = *I;
+    if (CFGStmt *CS = dyn_cast<CFGStmt>(&CE)) {
+      const Expr *ValEx = cast<Expr>(CS->getStmt());
+      hasValue = true;
+      V = state->getSVal(ValEx, LCtx);
+      break;
+    }
+  }
+
+  assert(hasValue);
+  (void) hasValue;
+
+  // Generate a new node with the binding from the appropriate path.
+  B.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V, true));
 }
 
 void ExprEngine::
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 7c3000e..44a860f 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -14,9 +14,10 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/Basic/PrettyStackTrace.h"
 
 using namespace clang;
 using namespace ento;
@@ -41,51 +42,154 @@
 }
 
 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
-                                       const MemRegion *Dest,
                                        ExplodedNode *Pred,
                                        ExplodedNodeSet &destNodes) {
-  CXXConstructorCall Call(CE, Dest, Pred->getState(),
-                          Pred->getLocationContext());
+  const LocationContext *LCtx = Pred->getLocationContext();
+  ProgramStateRef State = Pred->getState();
+
+  const MemRegion *Target = 0;
+
+  switch (CE->getConstructionKind()) {
+  case CXXConstructExpr::CK_Complete: {
+    // See if we're constructing an existing region by looking at the next
+    // element in the CFG.
+    const CFGBlock *B = currentBuilderContext->getBlock();
+    if (currentStmtIdx + 1 < B->size()) {
+      CFGElement Next = (*B)[currentStmtIdx+1];
+
+      // Is this a constructor for a local variable?
+      if (const CFGStmt *StmtElem = dyn_cast<CFGStmt>(&Next)) {
+        if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
+          if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
+            if (Var->getInit()->IgnoreImplicit() == CE) {
+              QualType Ty = Var->getType();
+              if (const ArrayType *AT = getContext().getAsArrayType(Ty)) {
+                // FIXME: Handle arrays, which run the same constructor for
+                // every element. This workaround will just run the first
+                // constructor (which should still invalidate the entire array).
+                SVal Base = State->getLValue(Var, LCtx);
+                Target = State->getLValue(AT->getElementType(),
+                                          getSValBuilder().makeZeroArrayIndex(),
+                                          Base).getAsRegion();
+              } else {
+                Target = State->getLValue(Var, LCtx).getAsRegion();
+              }
+            }
+          }
+        }
+      }
+      
+      // Is this a constructor for a member?
+      if (const CFGInitializer *InitElem = dyn_cast<CFGInitializer>(&Next)) {
+        const CXXCtorInitializer *Init = InitElem->getInitializer();
+        assert(Init->isAnyMemberInitializer());
+
+        const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
+        Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
+                                                  LCtx->getCurrentStackFrame());
+        SVal ThisVal = State->getSVal(ThisPtr);
+
+        if (Init->isIndirectMemberInitializer()) {
+          SVal Field = State->getLValue(Init->getIndirectMember(), ThisVal);
+          Target = Field.getAsRegion();
+        } else {
+          SVal Field = State->getLValue(Init->getMember(), ThisVal);
+          Target = Field.getAsRegion();
+        }
+      }
+
+      // FIXME: This will eventually need to handle new-expressions as well.
+    }
+
+    // If we couldn't find an existing region to construct into, we'll just
+    // generate a symbolic region, which is fine.
+
+    break;
+  }
+  case CXXConstructExpr::CK_NonVirtualBase:
+  case CXXConstructExpr::CK_VirtualBase:
+  case CXXConstructExpr::CK_Delegating: {
+    const CXXMethodDecl *CurCtor = cast<CXXMethodDecl>(LCtx->getDecl());
+    Loc ThisPtr = getSValBuilder().getCXXThis(CurCtor,
+                                              LCtx->getCurrentStackFrame());
+    SVal ThisVal = State->getSVal(ThisPtr);
+
+    if (CE->getConstructionKind() == CXXConstructExpr::CK_Delegating) {
+      Target = ThisVal.getAsRegion();
+    } else {
+      // Cast to the base type.
+      QualType BaseTy = CE->getType();
+      SVal BaseVal = getStoreManager().evalDerivedToBase(ThisVal, BaseTy);
+      Target = BaseVal.getAsRegion();
+    }
+    break;
+  }
+  }
+
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<CXXConstructorCall> Call =
+    CEMgr.getCXXConstructorCall(CE, Target, State, LCtx);
 
   ExplodedNodeSet DstPreVisit;
   getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
   ExplodedNodeSet DstPreCall;
   getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit,
-                                            Call, *this);
+                                            *Call, *this);
 
   ExplodedNodeSet DstInvalidated;
   StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currentBuilderContext);
   for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
        I != E; ++I)
-    defaultEvalCall(Bldr, *I, Call);
+    defaultEvalCall(Bldr, *I, *Call);
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated,
-                                             Call, *this);
+                                             *Call, *this);
   getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
 }
 
-void ExprEngine::VisitCXXDestructor(const CXXDestructorDecl *DD,
-                                      const MemRegion *Dest,
-                                      const Stmt *S,
-                                      ExplodedNode *Pred, 
-                                      ExplodedNodeSet &Dst) {
-  CXXDestructorCall Call(DD, S, Dest, Pred->getState(),
-                         Pred->getLocationContext());
+void ExprEngine::VisitCXXDestructor(QualType ObjectType,
+                                    const MemRegion *Dest,
+                                    const Stmt *S,
+                                    ExplodedNode *Pred, 
+                                    ExplodedNodeSet &Dst) {
+  const LocationContext *LCtx = Pred->getLocationContext();
+  ProgramStateRef State = Pred->getState();
+
+  // FIXME: We need to run the same destructor on every element of the array.
+  // This workaround will just run the first destructor (which will still
+  // invalidate the entire array).
+  if (const ArrayType *AT = getContext().getAsArrayType(ObjectType)) {
+    ObjectType = AT->getElementType();
+    Dest = State->getLValue(ObjectType, getSValBuilder().makeZeroArrayIndex(),
+                            loc::MemRegionVal(Dest)).getAsRegion();
+  }
+
+  const CXXRecordDecl *RecordDecl = ObjectType->getAsCXXRecordDecl();
+  assert(RecordDecl && "Only CXXRecordDecls should have destructors");
+  const CXXDestructorDecl *DtorDecl = RecordDecl->getDestructor();
+
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<CXXDestructorCall> Call =
+    CEMgr.getCXXDestructorCall(DtorDecl, S, Dest, State, LCtx);
+
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                Call->getSourceRange().getBegin(),
+                                "Error evaluating destructor");
 
   ExplodedNodeSet DstPreCall;
   getCheckerManager().runCheckersForPreCall(DstPreCall, Pred,
-                                            Call, *this);
+                                            *Call, *this);
 
   ExplodedNodeSet DstInvalidated;
   StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currentBuilderContext);
   for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
        I != E; ++I)
-    defaultEvalCall(Bldr, *I, Call);
+    defaultEvalCall(Bldr, *I, *Call);
 
   ExplodedNodeSet DstPostCall;
   getCheckerManager().runCheckersForPostCall(Dst, DstInvalidated,
-                                             Call, *this);
+                                             *Call, *this);
 }
 
 void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
@@ -102,9 +206,14 @@
     svalBuilder.getConjuredSymbolVal(0, CNE, LCtx, CNE->getType(), blockCount);
   ProgramStateRef State = Pred->getState();
 
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<CXXAllocatorCall> Call =
+    CEMgr.getCXXAllocatorCall(CNE, State, LCtx);
+
   // Invalidate placement args.
-  CXXAllocatorCall Call(CNE, State, LCtx);
-  State = Call.invalidateRegions(blockCount);
+  // FIXME: Once we figure out how we want allocators to work,
+  // we should be using the usual pre-/(default-)eval-/post-call checks here.
+  State = Call->invalidateRegions(blockCount);
 
   if (CNE->isArray()) {
     // FIXME: allocating an array requires simulating the constructors.
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index cc257eb..c96df20 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -11,33 +11,22 @@
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "ExprEngine"
+
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/AST/DeclCXX.h"
 #include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/Statistic.h"
 #include "llvm/Support/SaveAndRestore.h"
 
 using namespace clang;
 using namespace ento;
 
-static CallEventKind classifyCallExpr(const CallExpr *CE) {
-  if (isa<CXXMemberCallExpr>(CE))
-    return CE_CXXMember;
-
-  const CXXOperatorCallExpr *OpCE = dyn_cast<CXXOperatorCallExpr>(CE);
-  if (OpCE) {
-    const FunctionDecl *DirectCallee = CE->getDirectCallee();
-    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DirectCallee))
-      if (MD->isInstance())
-        return CE_CXXMemberOperator;
-  } else if (CE->getCallee()->getType()->isBlockPointerType()) {
-    return CE_Block;
-  }
-
-  return CE_Function;
-}
+STATISTIC(NumOfDynamicDispatchPathSplits,
+  "The # of times we split the path due to imprecise dynamic dispatch info");
 
 void ExprEngine::processCallEnter(CallEnter CE, ExplodedNode *Pred) {
   // Get the entry block in the CFG of the callee.
@@ -70,37 +59,49 @@
 static std::pair<const Stmt*,
                  const CFGBlock*> getLastStmt(const ExplodedNode *Node) {
   const Stmt *S = 0;
-  const CFGBlock *Blk = 0;
   const StackFrameContext *SF =
           Node->getLocation().getLocationContext()->getCurrentStackFrame();
+
+  // Back up through the ExplodedGraph until we reach a statement node.
   while (Node) {
     const ProgramPoint &PP = Node->getLocation();
-    // Skip any BlockEdges, empty blocks, and the CallExitBegin node.
-    if (isa<BlockEdge>(PP) || isa<CallExitBegin>(PP) || isa<BlockEntrance>(PP)){
-      assert(Node->pred_size() == 1);
-      Node = *Node->pred_begin();
-      continue;
-    }
-    // If we reached the CallEnter, the function has no statements.
-    if (isa<CallEnter>(PP))
-      break;
+
     if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP)) {
       S = SP->getStmt();
-      // Now, get the enclosing basic block.
-      while (Node && Node->pred_size() >=1 ) {
-        const ProgramPoint &PP = Node->getLocation();
-        if (isa<BlockEdge>(PP) &&
-            (PP.getLocationContext()->getCurrentStackFrame() == SF)) {
-          BlockEdge &EPP = cast<BlockEdge>(PP);
-          Blk = EPP.getDst();
-          break;
-        }
-        Node = *Node->pred_begin();
-      }
       break;
+    } else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&PP)) {
+      S = CEE->getCalleeContext()->getCallSite();
+      if (S)
+        break;
+      // If we have an implicit call, we'll probably end up with a
+      // StmtPoint inside the callee, which is acceptable.
+      // (It's possible a function ONLY contains implicit calls -- such as an
+      // implicitly-generated destructor -- so we shouldn't just skip back to
+      // the CallEnter node and keep going.)
+    } else if (const CallEnter *CE = dyn_cast<CallEnter>(&PP)) {
+      // If we reached the CallEnter for this function, it has no statements.
+      if (CE->getCalleeContext() == SF)
+        break;
     }
-    break;
+
+    Node = *Node->pred_begin();
   }
+
+  const CFGBlock *Blk = 0;
+  if (S) {
+    // Now, get the enclosing basic block.
+    while (Node && Node->pred_size() >=1 ) {
+      const ProgramPoint &PP = Node->getLocation();
+      if (isa<BlockEdge>(PP) &&
+          (PP.getLocationContext()->getCurrentStackFrame() == SF)) {
+        BlockEdge &EPP = cast<BlockEdge>(PP);
+        Blk = EPP.getDst();
+        break;
+      }
+      Node = *Node->pred_begin();
+    }
+  }
+
   return std::pair<const Stmt*, const CFGBlock*>(S, Blk);
 }
 
@@ -137,7 +138,7 @@
     if (const ReturnStmt *RS = dyn_cast_or_null<ReturnStmt>(LastSt)) {
       const LocationContext *LCtx = CEBNode->getLocationContext();
       SVal V = state->getSVal(RS, LCtx);
-      state = state->BindExpr(CE, calleeCtx->getParent(), V);
+      state = state->BindExpr(CE, callerCtx, V);
     }
 
     // Bind the constructed object value to CXXConstructExpr.
@@ -147,10 +148,15 @@
       SVal ThisV = state->getSVal(This);
 
       // Always bind the region to the CXXConstructExpr.
-      state = state->BindExpr(CCE, calleeCtx->getParent(), ThisV);
+      state = state->BindExpr(CCE, callerCtx, ThisV);
     }
   }
 
+  // Generate a CallEvent /before/ cleaning the state, so that we can get the
+  // correct value for 'this' (if necessary).
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<> Call = CEMgr.getCaller(calleeCtx, state);
+
   // Step 3: BindedRetNode -> CleanedNodes
   // If we can find a statement and a block in the inlined function, run remove
   // dead bindings before returning from the call. This is important to ensure
@@ -195,19 +201,29 @@
     // Step 5: Perform the post-condition check of the CallExpr and enqueue the
     // result onto the work list.
     // CEENode -> Dst -> WorkList
-    ExplodedNodeSet Dst;
     NodeBuilderContext Ctx(Engine, calleeCtx->getCallSiteBlock(), CEENode);
     SaveAndRestore<const NodeBuilderContext*> NBCSave(currentBuilderContext,
         &Ctx);
     SaveAndRestore<unsigned> CBISave(currentStmtIdx, calleeCtx->getIndex());
 
-    // FIXME: This needs to call PostCall.
-    // FIXME: If/when we inline Objective-C messages, this also needs to call
-    // PostObjCMessage.
-    if (CE)
-      getCheckerManager().runCheckersForPostStmt(Dst, CEENode, CE, *this, true);
-    else
-      Dst.Add(CEENode);
+    CallEventRef<> UpdatedCall = Call.cloneWithState(CEEState);
+
+    ExplodedNodeSet DstPostCall;
+    getCheckerManager().runCheckersForPostCall(DstPostCall, CEENode,
+                                               *UpdatedCall, *this,
+                                               /*WasInlined=*/true);
+
+    ExplodedNodeSet Dst;
+    if (const ObjCMethodCall *Msg = dyn_cast<ObjCMethodCall>(Call)) {
+      getCheckerManager().runCheckersForPostObjCMessage(Dst, DstPostCall, *Msg,
+                                                        *this,
+                                                        /*WasInlined=*/true);
+    } else if (CE) {
+      getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE,
+                                                 *this, /*WasInlined=*/true);
+    } else {
+      Dst.insert(DstPostCall);
+    }
 
     // Enqueue the next element in the block.
     for (ExplodedNodeSet::iterator PSI = Dst.begin(), PSE = Dst.end();
@@ -266,32 +282,111 @@
   return true;
 }
 
-bool ExprEngine::inlineCall(const CallEvent &Call,
-                            ExplodedNode *Pred) {
-  if (!getAnalysisManager().shouldInlineCall())
-    return false;
+/// The GDM component containing the dynamic dispatch bifurcation info. When
+/// the exact type of the receiver is not known, we want to explore both paths -
+/// one on which we do inline it and the other one on which we don't. This is
+/// done to ensure we do not drop coverage.
+/// This is the map from the receiver region to a bool, specifying either we
+/// consider this region's information precise or not along the given path.
+namespace clang {
+namespace ento {
+enum DynamicDispatchMode { DynamicDispatchModeInlined = 1,
+                           DynamicDispatchModeConservative };
 
-  bool IsDynamicDispatch;
-  const Decl *D = Call.getDefinition(IsDynamicDispatch);
-  if (!D || IsDynamicDispatch)
+struct DynamicDispatchBifurcationMap {};
+typedef llvm::ImmutableMap<const MemRegion*,
+                           unsigned int> DynamicDispatchBifur;
+template<> struct ProgramStateTrait<DynamicDispatchBifurcationMap>
+    :  public ProgramStatePartialTrait<DynamicDispatchBifur> {
+  static void *GDMIndex() { static int index; return &index; }
+};
+
+}}
+
+static bool shouldInlineCXX(AnalysisManager &AMgr) {
+  switch (AMgr.IPAMode) {
+  case None:
+  case BasicInlining:
     return false;
+  case Inlining:
+  case DynamicDispatch:
+  case DynamicDispatchBifurcate:
+    return true;
+  case NumIPAModes:
+    llvm_unreachable("not actually a valid option");
+  }
+  llvm_unreachable("bogus IPAMode");
+}
+
+bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
+                            NodeBuilder &Bldr, ExplodedNode *Pred,
+                            ProgramStateRef State) {
+  assert(D);
 
   const LocationContext *CurLC = Pred->getLocationContext();
   const StackFrameContext *CallerSFC = CurLC->getCurrentStackFrame();
   const LocationContext *ParentOfCallee = 0;
 
+  // FIXME: Refactor this check into a hypothetical CallEvent::canInline.
   switch (Call.getKind()) {
   case CE_Function:
+    break;
   case CE_CXXMember:
   case CE_CXXMemberOperator:
-    // These are always at least possible to inline.
+    if (!shouldInlineCXX(getAnalysisManager()))
+      return false;
     break;
-  case CE_CXXConstructor:
-  case CE_CXXDestructor:
-    // Do not inline constructors until we can really model destructors.
-    // This is unfortunate, but basically necessary for smart pointers and such.
-    return false;
+  case CE_CXXConstructor: {
+    if (!shouldInlineCXX(getAnalysisManager()))
+      return false;
+
+    // Only inline constructors and destructors if we built the CFGs for them
+    // properly.
+    const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
+    if (!ADC->getCFGBuildOptions().AddImplicitDtors ||
+        !ADC->getCFGBuildOptions().AddInitializers)
+      return false;
+
+    const CXXConstructorCall &Ctor = cast<CXXConstructorCall>(Call);
+
+    // FIXME: We don't handle constructors or destructors for arrays properly.
+    const MemRegion *Target = Ctor.getCXXThisVal().getAsRegion();
+    if (Target && isa<ElementRegion>(Target))
+      return false;
+
+    // FIXME: This is a hack. We don't handle temporary destructors
+    // right now, so we shouldn't inline their constructors.
+    const CXXConstructExpr *CtorExpr = Ctor.getOriginExpr();
+    if (CtorExpr->getConstructionKind() == CXXConstructExpr::CK_Complete)
+      if (!Target || !isa<DeclRegion>(Target))
+        return false;
+
+    break;
+  }
+  case CE_CXXDestructor: {
+    if (!shouldInlineCXX(getAnalysisManager()))
+      return false;
+
+    // Only inline constructors and destructors if we built the CFGs for them
+    // properly.
+    const AnalysisDeclContext *ADC = CallerSFC->getAnalysisDeclContext();
+    if (!ADC->getCFGBuildOptions().AddImplicitDtors ||
+        !ADC->getCFGBuildOptions().AddInitializers)
+      return false;
+
+    const CXXDestructorCall &Dtor = cast<CXXDestructorCall>(Call);
+
+    // FIXME: We don't handle constructors or destructors for arrays properly.
+    const MemRegion *Target = Dtor.getCXXThisVal().getAsRegion();
+    if (Target && isa<ElementRegion>(Target))
+      return false;
+
+    break;
+  }
   case CE_CXXAllocator:
+    if (!shouldInlineCXX(getAnalysisManager()))
+      return false;
+
     // Do not inline allocators until we model deallocators.
     // This is unfortunate, but basically necessary for smart pointers and such.
     return false;
@@ -305,9 +400,10 @@
     break;
   }
   case CE_ObjCMessage:
-    // These always use dynamic dispatch; enabling inlining means assuming
-    // that a particular method will be called at runtime.
-    llvm_unreachable("Dynamic dispatch should be handled above.");
+    if (!(getAnalysisManager().IPAMode == DynamicDispatch ||
+          getAnalysisManager().IPAMode == DynamicDispatchBifurcate))
+      return false;
+    break;
   }
 
   if (!shouldInlineDecl(D, Pred))
@@ -330,7 +426,7 @@
 
   // Construct a new state which contains the mapping from actual to
   // formal arguments.
-  ProgramStateRef State = Pred->getState()->enterStackFrame(Call, CalleeSFC);
+  State = State->enterStackFrame(Call, CalleeSFC);
 
   bool isNew;
   if (ExplodedNode *N = G.getNode(Loc, State, false, &isNew)) {
@@ -338,6 +434,11 @@
     if (isNew)
       Engine.getWorkList()->enqueue(N);
   }
+
+  // If we decided to inline the call, the successor has been manually
+  // added onto the work list so remove it from the node builder.
+  Bldr.takeNodes(Pred);
+
   return true;
 }
 
@@ -359,37 +460,18 @@
   ExplodedNodeSet dstPreVisit;
   getCheckerManager().runCheckersForPreStmt(dstPreVisit, Pred, CE, *this);
 
-  // Get the callee kind.
-  CallEventKind K = classifyCallExpr(CE);
+  // Get the call in its initial state. We use this as a template to perform
+  // all the checks.
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<> CallTemplate
+    = CEMgr.getSimpleCall(CE, Pred->getState(), Pred->getLocationContext());
 
   // Evaluate the function call.  We try each of the checkers
   // to see if the can evaluate the function call.
   ExplodedNodeSet dstCallEvaluated;
   for (ExplodedNodeSet::iterator I = dstPreVisit.begin(), E = dstPreVisit.end();
        I != E; ++I) {
-    ProgramStateRef State = (*I)->getState();
-    const LocationContext *LCtx = (*I)->getLocationContext();
-
-    // Evaluate the call.
-    switch (K) {
-    case CE_Function:
-      evalCall(dstCallEvaluated, *I, FunctionCall(CE, State, LCtx));
-      break;
-    case CE_CXXMember:
-      evalCall(dstCallEvaluated, *I, CXXMemberCall(cast<CXXMemberCallExpr>(CE),
-                                                   State, LCtx));
-      break;
-    case CE_CXXMemberOperator:
-      evalCall(dstCallEvaluated, *I,
-               CXXMemberOperatorCall(cast<CXXOperatorCallExpr>(CE),
-                                     State, LCtx));
-      break;
-    case CE_Block:
-      evalCall(dstCallEvaluated, *I, BlockCall(CE, State, LCtx));
-      break;
-    default:
-      llvm_unreachable("Non-CallExpr CallEventKind");
-    }
+    evalCall(dstCallEvaluated, *I, *CallTemplate);
   }
 
   // Finally, perform the post-condition check of the CallExpr and store
@@ -401,7 +483,14 @@
 }
 
 void ExprEngine::evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred,
-                          const SimpleCall &Call) {
+                          const CallEvent &Call) {
+  // WARNING: At this time, the state attached to 'Call' may be older than the
+  // state in 'Pred'. This is a minor optimization since CheckerManager will
+  // use an updated CallEvent instance when calling checkers, but if 'Call' is
+  // ever used directly in this function all callers should be updated to pass
+  // the most recent state. (It is probably not worth doing the work here since
+  // for some callers this will not be necessary.)
+
   // Run any pre-call checks using the generic call interface.
   ExplodedNodeSet dstPreVisit;
   getCheckerManager().runCheckersForPreCall(dstPreVisit, Pred, Call, *this);
@@ -435,9 +524,10 @@
     case OMF_self: {
       // These methods return their receivers.
       return State->BindExpr(E, LCtx, Msg->getReceiverSVal());
-      break;
     }
     }
+  } else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
+    return State->BindExpr(E, LCtx, C->getCXXThisVal());
   }
 
   // Conjure a symbol if the return value is unknown.
@@ -448,41 +538,105 @@
   return State->BindExpr(E, LCtx, R);
 }
 
-void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
-                                 const CallEvent &Call) {
-  ProgramStateRef State = 0;
-  const Expr *E = Call.getOriginExpr();
-
-  // Try to inline the call.
-  // The origin expression here is just used as a kind of checksum;
-  // for CallEvents that do not have origin expressions, this should still be
-  // safe.
-  if (!isa<ObjCMethodCall>(Call)) {
-    State = getInlineFailedState(Pred->getState(), E);
-    if (State == 0 && inlineCall(Call, Pred)) {
-      // If we inlined the call, the successor has been manually added onto
-      // the work list and we should not consider it for subsequent call
-      // handling steps.
-      Bldr.takeNodes(Pred);
-      return;
-    }
-  }
-
-  // If we can't inline it, handle the return value and invalidate the regions.
-  if (State == 0)
-    State = Pred->getState();
-
-  // Invalidate any regions touched by the call.
+// Conservatively evaluate call by invalidating regions and binding
+// a conjured return value.
+void ExprEngine::conservativeEvalCall(const CallEvent &Call, NodeBuilder &Bldr,
+                                      ExplodedNode *Pred, ProgramStateRef State) {
   unsigned Count = currentBuilderContext->getCurrentBlockCount();
   State = Call.invalidateRegions(Count, State);
-
-  // Construct and bind the return value.
   State = bindReturnValue(Call, Pred->getLocationContext(), State);
 
   // And make the result node.
   Bldr.generateNode(Call.getProgramPoint(), State, Pred);
 }
 
+void ExprEngine::defaultEvalCall(NodeBuilder &Bldr, ExplodedNode *Pred,
+                                 const CallEvent &CallTemplate) {
+  // Make sure we have the most recent state attached to the call.
+  ProgramStateRef State = Pred->getState();
+  CallEventRef<> Call = CallTemplate.cloneWithState(State);
+
+  if (!getAnalysisManager().shouldInlineCall()) {
+    conservativeEvalCall(*Call, Bldr, Pred, State);
+    return;
+  }
+  // Try to inline the call.
+  // The origin expression here is just used as a kind of checksum;
+  // this should still be safe even for CallEvents that don't come from exprs.
+  const Expr *E = Call->getOriginExpr();
+  ProgramStateRef InlinedFailedState = getInlineFailedState(State, E);
+
+  if (InlinedFailedState) {
+    // If we already tried once and failed, make sure we don't retry later.
+    State = InlinedFailedState;
+  } else {
+    RuntimeDefinition RD = Call->getRuntimeDefinition();
+    const Decl *D = RD.getDecl();
+    if (D) {
+      if (RD.mayHaveOtherDefinitions()) {
+        // Explore with and without inlining the call.
+        if (getAnalysisManager().IPAMode == DynamicDispatchBifurcate) {
+          BifurcateCall(RD.getDispatchRegion(), *Call, D, Bldr, Pred);
+          return;
+        }
+
+        // Don't inline if we're not in any dynamic dispatch mode.
+        if (getAnalysisManager().IPAMode != DynamicDispatch) {
+          conservativeEvalCall(*Call, Bldr, Pred, State);
+          return;
+        }
+      }
+
+      // We are not bifurcating and we do have a Decl, so just inline.
+      if (inlineCall(*Call, D, Bldr, Pred, State))
+        return;
+    }
+  }
+
+  // If we can't inline it, handle the return value and invalidate the regions.
+  conservativeEvalCall(*Call, Bldr, Pred, State);
+}
+
+void ExprEngine::BifurcateCall(const MemRegion *BifurReg,
+                               const CallEvent &Call, const Decl *D,
+                               NodeBuilder &Bldr, ExplodedNode *Pred) {
+  assert(BifurReg);
+  BifurReg = BifurReg->StripCasts();
+
+  // Check if we've performed the split already - note, we only want
+  // to split the path once per memory region.
+  ProgramStateRef State = Pred->getState();
+  const unsigned int *BState =
+                        State->get<DynamicDispatchBifurcationMap>(BifurReg);
+  if (BState) {
+    // If we are on "inline path", keep inlining if possible.
+    if (*BState == DynamicDispatchModeInlined)
+      if (inlineCall(Call, D, Bldr, Pred, State))
+        return;
+    // If inline failed, or we are on the path where we assume we
+    // don't have enough info about the receiver to inline, conjure the
+    // return value and invalidate the regions.
+    conservativeEvalCall(Call, Bldr, Pred, State);
+    return;
+  }
+
+  // If we got here, this is the first time we process a message to this
+  // region, so split the path.
+  ProgramStateRef IState =
+      State->set<DynamicDispatchBifurcationMap>(BifurReg,
+                                               DynamicDispatchModeInlined);
+  inlineCall(Call, D, Bldr, Pred, IState);
+
+  ProgramStateRef NoIState =
+      State->set<DynamicDispatchBifurcationMap>(BifurReg,
+                                               DynamicDispatchModeConservative);
+  conservativeEvalCall(Call, Bldr, Pred, NoIState);
+
+  NumOfDynamicDispatchPathSplits++;
+  return;
+}
+
+
 void ExprEngine::VisitReturnStmt(const ReturnStmt *RS, ExplodedNode *Pred,
                                  ExplodedNodeSet &Dst) {
   
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index a8e0b3b..e261538 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/AST/StmtObjC.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 
 using namespace clang;
@@ -140,17 +140,20 @@
   return isSubclass(Class->getSuperClass(), II);
 }
 
-void ExprEngine::VisitObjCMessage(const ObjCMethodCall &msg,
+void ExprEngine::VisitObjCMessage(const ObjCMessageExpr *ME,
                                   ExplodedNode *Pred,
                                   ExplodedNodeSet &Dst) {
-  
+  CallEventManager &CEMgr = getStateManager().getCallEventManager();
+  CallEventRef<ObjCMethodCall> Msg =
+    CEMgr.getObjCMethodCall(ME, Pred->getState(), Pred->getLocationContext());
+
   // Handle the previsits checks.
   ExplodedNodeSet dstPrevisit;
   getCheckerManager().runCheckersForPreObjCMessage(dstPrevisit, Pred,
-                                                   msg, *this);
+                                                   *Msg, *this);
   ExplodedNodeSet dstGenericPrevisit;
   getCheckerManager().runCheckersForPreCall(dstGenericPrevisit, dstPrevisit,
-                                            msg, *this);
+                                            *Msg, *this);
 
   // Proceed with evaluate the message expression.
   ExplodedNodeSet dstEval;
@@ -159,16 +162,17 @@
   for (ExplodedNodeSet::iterator DI = dstGenericPrevisit.begin(),
        DE = dstGenericPrevisit.end(); DI != DE; ++DI) {
     ExplodedNode *Pred = *DI;
+    ProgramStateRef State = Pred->getState();
+    CallEventRef<ObjCMethodCall> UpdatedMsg = Msg.cloneWithState(State);
     
-    if (msg.isInstanceMessage()) {
-      SVal recVal = msg.getReceiverSVal();
+    if (UpdatedMsg->isInstanceMessage()) {
+      SVal recVal = UpdatedMsg->getReceiverSVal();
       if (!recVal.isUndef()) {
         // Bifurcate the state into nil and non-nil ones.
         DefinedOrUnknownSVal receiverVal = cast<DefinedOrUnknownSVal>(recVal);
         
-        ProgramStateRef state = Pred->getState();
         ProgramStateRef notNilState, nilState;
-        llvm::tie(notNilState, nilState) = state->assume(receiverVal);
+        llvm::tie(notNilState, nilState) = State->assume(receiverVal);
         
         // There are three cases: can be nil or non-nil, must be nil, must be
         // non-nil. We ignore must be nil, and merge the rest two into non-nil.
@@ -180,23 +184,20 @@
         
         // Check if the "raise" message was sent.
         assert(notNilState);
-        if (msg.getSelector() == RaiseSel) {
+        if (Msg->getSelector() == RaiseSel) {
           // If we raise an exception, for now treat it as a sink.
           // Eventually we will want to handle exceptions properly.
-          Bldr.generateNode(currentStmt, Pred, Pred->getState(), true);
+          Bldr.generateSink(currentStmt, Pred, State);
           continue;
         }
         
         // Generate a transition to non-Nil state.
-        if (notNilState != state)
+        if (notNilState != State)
           Pred = Bldr.generateNode(currentStmt, Pred, notNilState);
-
-        // Evaluate the call.
-        defaultEvalCall(Bldr, Pred, msg);
       }
     } else {
       // Check for special class methods.
-      if (const ObjCInterfaceDecl *Iface = msg.getReceiverInterface()) {
+      if (const ObjCInterfaceDecl *Iface = Msg->getReceiverInterface()) {
         if (!NSExceptionII) {
           ASTContext &Ctx = getContext();
           NSExceptionII = &Ctx.Idents.get("NSException");
@@ -225,7 +226,7 @@
               Ctx.Selectors.getSelector(II.size(), &II[0]);
           }
           
-          Selector S = msg.getSelector();
+          Selector S = Msg->getSelector();
           bool RaisesException = false;
           for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i) {
             if (S == NSExceptionInstanceRaiseSelectors[i]) {
@@ -236,23 +237,24 @@
           if (RaisesException) {
             // If we raise an exception, for now treat it as a sink.
             // Eventually we will want to handle exceptions properly.
-            Bldr.generateNode(currentStmt, Pred, Pred->getState(), true);
+            Bldr.generateSink(currentStmt, Pred, Pred->getState());
             continue;
           }
 
         }
       }
-
-      // Evaluate the call.
-      defaultEvalCall(Bldr, Pred, msg);
     }
+
+    // Evaluate the call.
+    defaultEvalCall(Bldr, Pred, *UpdatedMsg);
   }
   
   ExplodedNodeSet dstPostvisit;
-  getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval, msg, *this);
+  getCheckerManager().runCheckersForPostCall(dstPostvisit, dstEval,
+                                             *Msg, *this);
 
   // Finally, perform the post-condition check of the ObjCMessageExpr and store
   // the created nodes in 'Dst'.
   getCheckerManager().runCheckersForPostObjCMessage(Dst, dstPostvisit,
-                                                    msg, *this);
+                                                    *Msg, *this);
 }
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index f1ce878..982bcbf 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -45,7 +45,7 @@
   virtual ~HTMLDiagnostics() { FlushDiagnostics(NULL); }
 
   virtual void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                                    SmallVectorImpl<std::string> *FilesMade);
+                                    FilesMade *filesMade);
 
   virtual StringRef getName() const {
     return "HTMLDiagnostics";
@@ -63,7 +63,7 @@
                       const char *HighlightEnd = "</span>");
 
   void ReportDiag(const PathDiagnostic& D,
-                  SmallVectorImpl<std::string> *FilesMade);
+                  FilesMade *filesMade);
 };
 
 } // end anonymous namespace
@@ -76,10 +76,10 @@
   FilePrefix.appendComponent("report");
 }
 
-PathDiagnosticConsumer*
-ento::createHTMLDiagnosticConsumer(const std::string& prefix,
-                                 const Preprocessor &PP) {
-  return new HTMLDiagnostics(prefix, PP);
+void ento::createHTMLDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                        const std::string& prefix,
+                                        const Preprocessor &PP) {
+  C.push_back(new HTMLDiagnostics(prefix, PP));
 }
 
 //===----------------------------------------------------------------------===//
@@ -88,46 +88,15 @@
 
 void HTMLDiagnostics::FlushDiagnosticsImpl(
   std::vector<const PathDiagnostic *> &Diags,
-  SmallVectorImpl<std::string> *FilesMade) {
+  FilesMade *filesMade) {
   for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(),
        et = Diags.end(); it != et; ++it) {
-    ReportDiag(**it, FilesMade);
-  }
-}
-
-static void flattenPath(PathPieces &primaryPath, PathPieces &currentPath,
-                        const PathPieces &oldPath) {
-  for (PathPieces::const_iterator it = oldPath.begin(), et = oldPath.end();
-       it != et; ++it ) {
-    PathDiagnosticPiece *piece = it->getPtr();
-    if (const PathDiagnosticCallPiece *call =
-        dyn_cast<PathDiagnosticCallPiece>(piece)) {
-      IntrusiveRefCntPtr<PathDiagnosticEventPiece> callEnter =
-        call->getCallEnterEvent();
-      if (callEnter)
-        currentPath.push_back(callEnter);
-      flattenPath(primaryPath, primaryPath, call->path);
-      IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
-        call->getCallExitEvent();
-      if (callExit)
-        currentPath.push_back(callExit);
-      continue;
-    }
-    if (PathDiagnosticMacroPiece *macro =
-        dyn_cast<PathDiagnosticMacroPiece>(piece)) {
-      currentPath.push_back(piece);
-      PathPieces newPath;
-      flattenPath(primaryPath, newPath, macro->subPieces);
-      macro->subPieces = newPath;
-      continue;
-    }
-    
-    currentPath.push_back(piece);
+    ReportDiag(**it, filesMade);
   }
 }
 
 void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
-                                 SmallVectorImpl<std::string> *FilesMade) {
+                                 FilesMade *filesMade) {
     
   // Create the HTML directory if it is missing.
   if (!createdDir) {
@@ -152,8 +121,7 @@
     return;
 
   // First flatten out the entire path to make it easier to use.
-  PathPieces path;
-  flattenPath(path, path, D.path);
+  PathPieces path = D.path.flatten(/*ShouldFlattenMacros=*/false);
 
   // The path as already been prechecked that all parts of the path are
   // from the same file and that it is non-empty.
@@ -298,8 +266,10 @@
     return;
   }
 
-  if (FilesMade)
-    FilesMade->push_back(llvm::sys::path::filename(H.str()));
+  if (filesMade) {
+    filesMade->push_back(std::make_pair(StringRef(getName()),
+                                        llvm::sys::path::filename(H.str())));
+  }
 
   // Emit the HTML to disk.
   for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
@@ -428,6 +398,15 @@
     os << "<div class=\"PathIndex";
     if (Kind) os << " PathIndex" << Kind;
     os << "\">" << num << "</div>";
+
+    if (num > 1) {
+      os << "</td><td><div class=\"PathNav\"><a href=\"#Path"
+         << (num - 1)
+         << "\" title=\"Previous event ("
+         << (num - 1)
+         << ")\">&#x2190;</a></div></td>";
+    }
+
     os << "</td><td>";
   }
 
@@ -454,8 +433,21 @@
 
     os << "':\n";
 
-    if (max > 1)
-      os << "</td></tr></table>";
+    if (max > 1) {
+      os << "</td>";
+      if (num < max) {
+        os << "<td><div class=\"PathNav\"><a href=\"#";
+        if (num == max - 1)
+          os << "EndPath";
+        else
+          os << "Path" << (num + 1);
+        os << "\" title=\"Next event ("
+        << (num + 1)
+        << ")\">&#x2192;</a></div></td>";
+      }
+
+      os << "</tr></table>";
+    }
 
     // Within a macro piece.  Write out each event.
     ProcessMacroPiece(os, *MP, 0);
@@ -463,8 +455,21 @@
   else {
     os << html::EscapeText(P.getString());
 
-    if (max > 1)
-      os << "</td></tr></table>";
+    if (max > 1) {
+      os << "</td>";
+      if (num < max) {
+        os << "<td><div class=\"PathNav\"><a href=\"#";
+        if (num == max - 1)
+          os << "EndPath";
+        else
+          os << "Path" << (num + 1);
+        os << "\" title=\"Next event ("
+           << (num + 1)
+           << ")\">&#x2192;</a></div></td>";
+      }
+      
+      os << "</tr></table>";
+    }
   }
 
   os << "</div></td></tr>";
@@ -477,29 +482,11 @@
   R.InsertTextBefore(Loc, os.str());
 
   // Now highlight the ranges.
-  for (const SourceRange *I = P.ranges_begin(), *E = P.ranges_end();
-        I != E; ++I)
+  ArrayRef<SourceRange> Ranges = P.getRanges();
+  for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
+                                       E = 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(raw_ostream &os, unsigned n) {
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index 5409078..62e602a 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -179,7 +179,7 @@
 // Region extents.
 //===----------------------------------------------------------------------===//
 
-DefinedOrUnknownSVal DeclRegion::getExtent(SValBuilder &svalBuilder) const {
+DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const {
   ASTContext &Ctx = svalBuilder.getContext();
   QualType T = getDesugaredValueType(Ctx);
 
@@ -470,7 +470,7 @@
 }
 
 void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {
-  os << "base " << decl->getName();
+  os << "base{" << superRegion << ',' << decl->getName() << '}';
 }
 
 void CXXThisRegion::dumpToStream(raw_ostream &os) const {
@@ -546,17 +546,29 @@
   os << "StackLocalsSpaceRegion";
 }
 
-void MemRegion::dumpPretty(raw_ostream &os) const {
+bool MemRegion::canPrintPretty() const {
+  return false;
+}
+
+void MemRegion::printPretty(raw_ostream &os) const {
   return;
 }
 
-void VarRegion::dumpPretty(raw_ostream &os) const {
+bool VarRegion::canPrintPretty() const {
+  return true;
+}
+
+void VarRegion::printPretty(raw_ostream &os) const {
   os << getDecl()->getName();
 }
 
-void FieldRegion::dumpPretty(raw_ostream &os) const {
-  superRegion->dumpPretty(os);
-  os << "->" << getDecl();
+bool FieldRegion::canPrintPretty() const {
+  return superRegion->canPrintPretty();
+}
+
+void FieldRegion::printPretty(raw_ostream &os) const {
+  superRegion->printPretty(os);
+  os << "." << getDecl()->getName();
 }
 
 //===----------------------------------------------------------------------===//
@@ -876,6 +888,37 @@
 const CXXBaseObjectRegion *
 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *decl,
                                          const MemRegion *superRegion) {
+  // Check that the base class is actually a direct base of this region.
+  if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(superRegion)) {
+    if (const CXXRecordDecl *Class = TVR->getValueType()->getAsCXXRecordDecl()){
+      if (Class->isVirtuallyDerivedFrom(decl)) {
+        // Virtual base regions should not be layered, since the layout rules
+        // are different.
+        while (const CXXBaseObjectRegion *Base =
+                 dyn_cast<CXXBaseObjectRegion>(superRegion)) {
+          superRegion = Base->getSuperRegion();
+        }
+        assert(superRegion && !isa<MemSpaceRegion>(superRegion));
+
+      } else {
+        // Non-virtual bases should always be direct bases.
+#ifndef NDEBUG
+        bool FoundBase = false;
+        for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(),
+                                                      E = Class->bases_end();
+             I != E; ++I) {
+          if (I->getType()->getAsCXXRecordDecl() == decl) {
+            FoundBase = true;
+            break;
+          }
+        }
+
+        assert(FoundBase && "Not a direct base class of this region");
+#endif
+      }
+    }
+  }
+
   return getSubRegion<CXXBaseObjectRegion>(decl, superRegion);
 }
 
@@ -951,7 +994,7 @@
 // View handling.
 //===----------------------------------------------------------------------===//
 
-const MemRegion *MemRegion::StripCasts() const {
+const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const {
   const MemRegion *R = this;
   while (true) {
     switch (R->getKind()) {
@@ -963,6 +1006,8 @@
       break;
     }
     case CXXBaseObjectRegionKind:
+      if (!StripBaseCasts)
+        return R;
       R = cast<CXXBaseObjectRegion>(R)->getSuperRegion();
       break;
     default:
@@ -1026,12 +1071,14 @@
 
 RegionOffset MemRegion::getAsOffset() const {
   const MemRegion *R = this;
+  const MemRegion *SymbolicOffsetBase = 0;
   int64_t Offset = 0;
 
   while (1) {
     switch (R->getKind()) {
     default:
-      return RegionOffset(0);
+      return RegionOffset(R, RegionOffset::Symbolic);
+
     case SymbolicRegionKind:
     case AllocaRegionKind:
     case CompoundLiteralRegionKind:
@@ -1040,31 +1087,95 @@
     case VarRegionKind:
     case CXXTempObjectRegionKind:
       goto Finish;
+
+    case ObjCIvarRegionKind:
+      // This is a little strange, but it's a compromise between
+      // ObjCIvarRegions having unknown compile-time offsets (when using the
+      // non-fragile runtime) and yet still being distinct, non-overlapping
+      // regions. Thus we treat them as "like" base regions for the purposes
+      // of computing offsets.
+      goto Finish;
+
+    case CXXBaseObjectRegionKind: {
+      const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R);
+      R = BOR->getSuperRegion();
+
+      QualType Ty;
+      if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) {
+        Ty = TVR->getDesugaredValueType(getContext());
+      } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
+        // If our base region is symbolic, we don't know what type it really is.
+        // Pretend the type of the symbol is the true dynamic type.
+        // (This will at least be self-consistent for the life of the symbol.)
+        Ty = SR->getSymbol()->getType(getContext())->getPointeeType();
+      }
+      
+      const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl();
+      if (!Child) {
+        // We cannot compute the offset of the base class.
+        SymbolicOffsetBase = R;
+      }
+
+      // Don't bother calculating precise offsets if we already have a
+      // symbolic offset somewhere in the chain.
+      if (SymbolicOffsetBase)
+        continue;
+
+      const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child);
+
+      CharUnits BaseOffset;
+      const CXXRecordDecl *Base = BOR->getDecl();
+      if (Child->isVirtuallyDerivedFrom(Base))
+        BaseOffset = Layout.getVBaseClassOffset(Base);
+      else
+        BaseOffset = Layout.getBaseClassOffset(Base);
+
+      // The base offset is in chars, not in bits.
+      Offset += BaseOffset.getQuantity() * getContext().getCharWidth();
+      break;
+    }
     case ElementRegionKind: {
       const ElementRegion *ER = cast<ElementRegion>(R);
-      QualType EleTy = ER->getValueType();
+      R = ER->getSuperRegion();
 
-      if (!IsCompleteType(getContext(), EleTy))
-        return RegionOffset(0);
+      QualType EleTy = ER->getValueType();
+      if (!IsCompleteType(getContext(), EleTy)) {
+        // We cannot compute the offset of the base class.
+        SymbolicOffsetBase = R;
+        continue;
+      }
 
       SVal Index = ER->getIndex();
       if (const nonloc::ConcreteInt *CI=dyn_cast<nonloc::ConcreteInt>(&Index)) {
+        // Don't bother calculating precise offsets if we already have a
+        // symbolic offset somewhere in the chain. 
+        if (SymbolicOffsetBase)
+          continue;
+
         int64_t i = CI->getValue().getSExtValue();
-        CharUnits Size = getContext().getTypeSizeInChars(EleTy);
-        Offset += i * Size.getQuantity() * 8;
+        // This type size is in bits.
+        Offset += i * getContext().getTypeSize(EleTy);
       } else {
         // We cannot compute offset for non-concrete index.
-        return RegionOffset(0);
+        SymbolicOffsetBase = R;
       }
-      R = ER->getSuperRegion();
       break;
     }
     case FieldRegionKind: {
       const FieldRegion *FR = cast<FieldRegion>(R);
+      R = FR->getSuperRegion();
+
       const RecordDecl *RD = FR->getDecl()->getParent();
-      if (!RD->isCompleteDefinition())
+      if (!RD->isCompleteDefinition()) {
         // We cannot compute offset for incomplete type.
-        return RegionOffset(0);
+        SymbolicOffsetBase = R;
+      }
+
+      // Don't bother calculating precise offsets if we already have a
+      // symbolic offset somewhere in the chain.
+      if (SymbolicOffsetBase)
+        continue;
+
       // Get the field number.
       unsigned idx = 0;
       for (RecordDecl::field_iterator FI = RD->field_begin(), 
@@ -1075,13 +1186,14 @@
       const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
       // This is offset in bits.
       Offset += Layout.getFieldOffset(idx);
-      R = FR->getSuperRegion();
       break;
     }
     }
   }
 
  Finish:
+  if (SymbolicOffsetBase)
+    return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic);
   return RegionOffset(R, Offset);
 }
 
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index bfb8bf6..c849778 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtCXX.h"
@@ -58,6 +59,48 @@
 
 
 PathPieces::~PathPieces() {}
+
+void PathPieces::flattenTo(PathPieces &Primary, PathPieces &Current,
+                           bool ShouldFlattenMacros) const {
+  for (PathPieces::const_iterator I = begin(), E = end(); I != E; ++I) {
+    PathDiagnosticPiece *Piece = I->getPtr();
+
+    switch (Piece->getKind()) {
+    case PathDiagnosticPiece::Call: {
+      PathDiagnosticCallPiece *Call = cast<PathDiagnosticCallPiece>(Piece);
+      IntrusiveRefCntPtr<PathDiagnosticEventPiece> CallEnter =
+        Call->getCallEnterEvent();
+      if (CallEnter)
+        Current.push_back(CallEnter);
+      Call->path.flattenTo(Primary, Primary, ShouldFlattenMacros);
+      IntrusiveRefCntPtr<PathDiagnosticEventPiece> callExit =
+        Call->getCallExitEvent();
+      if (callExit)
+        Current.push_back(callExit);
+      break;
+    }
+    case PathDiagnosticPiece::Macro: {
+      PathDiagnosticMacroPiece *Macro = cast<PathDiagnosticMacroPiece>(Piece);
+      if (ShouldFlattenMacros) {
+        Macro->subPieces.flattenTo(Primary, Primary, ShouldFlattenMacros);
+      } else {
+        Current.push_back(Piece);
+        PathPieces NewPath;
+        Macro->subPieces.flattenTo(Primary, NewPath, ShouldFlattenMacros);
+        // FIXME: This probably shouldn't mutate the original path piece.
+        Macro->subPieces = NewPath;
+      }
+      break;
+    }
+    case PathDiagnosticPiece::Event:
+    case PathDiagnosticPiece::ControlFlow:
+      Current.push_back(Piece);
+      break;
+    }
+  }
+}
+
+
 PathDiagnostic::~PathDiagnostic() {}
 
 PathDiagnostic::PathDiagnostic(const Decl *declWithIssue,
@@ -114,13 +157,13 @@
           return; // FIXME: Emit a warning?
       
         // Check the source ranges.
-        for (PathDiagnosticPiece::range_iterator RI = piece->ranges_begin(),
-             RE = piece->ranges_end();
-             RI != RE; ++RI) {
-          SourceLocation L = SMgr.getExpansionLoc(RI->getBegin());
+        ArrayRef<SourceRange> Ranges = piece->getRanges();
+        for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
+                                             E = Ranges.end(); I != E; ++I) {
+          SourceLocation L = SMgr.getExpansionLoc(I->getBegin());
           if (!L.isFileID() || SMgr.getFileID(L) != FID)
             return; // FIXME: Emit a warning?
-          L = SMgr.getExpansionLoc(RI->getEnd());
+          L = SMgr.getExpansionLoc(I->getEnd());
           if (!L.isFileID() || SMgr.getFileID(L) != FID)
             return; // FIXME: Emit a warning?
         }
@@ -147,23 +190,14 @@
 
   if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
     // Keep the PathDiagnostic with the shorter path.
+    // Note, the enclosing routine is called in deterministic order, so the
+    // results will be consistent between runs (no reason to break ties if the
+    // size is the same).
     const unsigned orig_size = orig->full_size();
     const unsigned new_size = D->full_size();
-    
-    if (orig_size <= new_size) {
-      bool shouldKeepOriginal = true;
-      if (orig_size == new_size) {
-        // Here we break ties in a fairly arbitrary, but deterministic, way.
-        llvm::FoldingSetNodeID fullProfile, fullProfileOrig;
-        D->FullProfile(fullProfile);
-        orig->FullProfile(fullProfileOrig);
-        if (fullProfile.ComputeHash() < fullProfileOrig.ComputeHash())
-          shouldKeepOriginal = false;
-      }
+    if (orig_size <= new_size)
+      return;
 
-      if (shouldKeepOriginal)
-        return;
-    }
     Diags.RemoveNode(orig);
     delete orig;
   }
@@ -206,8 +240,8 @@
 };  
 }
 
-void
-PathDiagnosticConsumer::FlushDiagnostics(SmallVectorImpl<std::string> *Files) {
+void PathDiagnosticConsumer::FlushDiagnostics(
+                                     PathDiagnosticConsumer::FilesMade *Files) {
   if (flushed)
     return;
   
@@ -242,30 +276,86 @@
 //===----------------------------------------------------------------------===//
 
 static SourceLocation getValidSourceLocation(const Stmt* S,
-                                             LocationOrAnalysisDeclContext LAC) {
-  SourceLocation L = S->getLocStart();
+                                             LocationOrAnalysisDeclContext LAC,
+                                             bool UseEnd = false) {
+  SourceLocation L = UseEnd ? S->getLocEnd() : S->getLocStart();
   assert(!LAC.isNull() && "A valid LocationContext or AnalysisDeclContext should "
                           "be passed to PathDiagnosticLocation upon creation.");
 
   // S might be a temporary statement that does not have a location in the
-  // source code, so find an enclosing statement and use it's location.
+  // source code, so find an enclosing statement and use its location.
   if (!L.isValid()) {
 
-    ParentMap *PM = 0;
+    AnalysisDeclContext *ADC;
     if (LAC.is<const LocationContext*>())
-      PM = &LAC.get<const LocationContext*>()->getParentMap();
+      ADC = LAC.get<const LocationContext*>()->getAnalysisDeclContext();
     else
-      PM = &LAC.get<AnalysisDeclContext*>()->getParentMap();
+      ADC = LAC.get<AnalysisDeclContext*>();
 
-    while (!L.isValid()) {
-      S = PM->getParent(S);
-      L = S->getLocStart();
-    }
+    ParentMap &PM = ADC->getParentMap();
+
+    const Stmt *Parent = S;
+    do {
+      Parent = PM.getParent(Parent);
+
+      // In rare cases, we have implicit top-level expressions,
+      // such as arguments for implicit member initializers.
+      // In this case, fall back to the start of the body (even if we were
+      // asked for the statement end location).
+      if (!Parent) {
+        const Stmt *Body = ADC->getBody();
+        if (Body)
+          L = Body->getLocStart();
+        else
+          L = ADC->getDecl()->getLocEnd();
+        break;
+      }
+
+      L = UseEnd ? Parent->getLocEnd() : Parent->getLocStart();
+    } while (!L.isValid());
   }
 
   return L;
 }
 
+static PathDiagnosticLocation
+getLocationForCaller(const StackFrameContext *SFC,
+                     const LocationContext *CallerCtx,
+                     const SourceManager &SM) {
+  const CFGBlock &Block = *SFC->getCallSiteBlock();
+  CFGElement Source = Block[SFC->getIndex()];
+
+  switch (Source.getKind()) {
+  case CFGElement::Invalid:
+    llvm_unreachable("Invalid CFGElement");
+  case CFGElement::Statement:
+    return PathDiagnosticLocation(cast<CFGStmt>(Source).getStmt(),
+                                  SM, CallerCtx);
+  case CFGElement::Initializer: {
+    const CFGInitializer &Init = cast<CFGInitializer>(Source);
+    return PathDiagnosticLocation(Init.getInitializer()->getInit(),
+                                  SM, CallerCtx);
+  }
+  case CFGElement::AutomaticObjectDtor: {
+    const CFGAutomaticObjDtor &Dtor = cast<CFGAutomaticObjDtor>(Source);
+    return PathDiagnosticLocation::createEnd(Dtor.getTriggerStmt(),
+                                             SM, CallerCtx);
+  }
+  case CFGElement::BaseDtor:
+  case CFGElement::MemberDtor: {
+    const AnalysisDeclContext *CallerInfo = CallerCtx->getAnalysisDeclContext();
+    if (const Stmt *CallerBody = CallerInfo->getBody())
+      return PathDiagnosticLocation::createEnd(CallerBody, SM, CallerCtx);
+    return PathDiagnosticLocation::create(CallerInfo->getDecl(), SM);
+  }
+  case CFGElement::TemporaryDtor:
+    llvm_unreachable("not yet implemented!");
+  }
+
+  llvm_unreachable("Unknown CFGElement kind");
+}
+
+
 PathDiagnosticLocation
   PathDiagnosticLocation::createBegin(const Decl *D,
                                       const SourceManager &SM) {
@@ -280,6 +370,17 @@
                                 SM, SingleLocK);
 }
 
+
+PathDiagnosticLocation
+PathDiagnosticLocation::createEnd(const Stmt *S,
+                                  const SourceManager &SM,
+                                  LocationOrAnalysisDeclContext LAC) {
+  if (const CompoundStmt *CS = dyn_cast<CompoundStmt>(S))
+    return createEndBrace(CS, SM);
+  return PathDiagnosticLocation(getValidSourceLocation(S, LAC, /*End=*/true),
+                                SM, SingleLocK);
+}
+
 PathDiagnosticLocation
   PathDiagnosticLocation::createOperatorLoc(const BinaryOperator *BO,
                                             const SourceManager &SM) {
@@ -339,8 +440,18 @@
   else if (const PostStmt *PS = dyn_cast<PostStmt>(&P)) {
     S = PS->getStmt();
   }
+  else if (const PostImplicitCall *PIE = dyn_cast<PostImplicitCall>(&P)) {
+    return PathDiagnosticLocation(PIE->getLocation(), SMng);
+  }
+  else if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) {
+    return getLocationForCaller(CE->getCalleeContext(),
+                                CE->getLocationContext(),
+                                SMng);
+  }
   else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&P)) {
-    S = CEE->getCalleeContext()->getCallSite();
+    return getLocationForCaller(CEE->getCalleeContext(),
+                                CEE->getLocationContext(),
+                                SMng);
   }
 
   return PathDiagnosticLocation(S, SMng, P.getLocationContext());
@@ -498,29 +609,14 @@
 // Manipulation of PathDiagnosticCallPieces.
 //===----------------------------------------------------------------------===//
 
-static PathDiagnosticLocation getLastStmtLoc(const ExplodedNode *N,
-                                             const SourceManager &SM) {
-  while (N) {
-    ProgramPoint PP = N->getLocation();
-    if (const StmtPoint *SP = dyn_cast<StmtPoint>(&PP))
-      return PathDiagnosticLocation(SP->getStmt(), SM, PP.getLocationContext());
-    // FIXME: Handle implicit calls.
-    if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&PP))
-      if (const Stmt *CallSite = CEE->getCalleeContext()->getCallSite())
-        return PathDiagnosticLocation(CallSite, SM, PP.getLocationContext());
-    if (N->pred_empty())
-      break;
-    N = *N->pred_begin();
-  }
-  return PathDiagnosticLocation();
-}
-
 PathDiagnosticCallPiece *
 PathDiagnosticCallPiece::construct(const ExplodedNode *N,
                                    const CallExitEnd &CE,
                                    const SourceManager &SM) {
   const Decl *caller = CE.getLocationContext()->getDecl();
-  PathDiagnosticLocation pos = getLastStmtLoc(N, SM);
+  PathDiagnosticLocation pos = getLocationForCaller(CE.getCalleeContext(),
+                                                    CE.getLocationContext(),
+                                                    SM);
   return new PathDiagnosticCallPiece(caller, pos);
 }
 
@@ -535,11 +631,11 @@
 
 void PathDiagnosticCallPiece::setCallee(const CallEnter &CE,
                                         const SourceManager &SM) {
-  const Decl *D = CE.getCalleeContext()->getDecl();
-  Callee = D;
-  callEnter = PathDiagnosticLocation(CE.getCallExpr(), SM,
-                                     CE.getLocationContext());
-  callEnterWithin = PathDiagnosticLocation::createBegin(D, SM);
+  const StackFrameContext *CalleeCtx = CE.getCalleeContext();
+  Callee = CalleeCtx->getDecl();
+
+  callEnterWithin = PathDiagnosticLocation::createBegin(Callee, SM);
+  callEnter = getLocationForCaller(CalleeCtx, CE.getLocationContext(), SM);
 }
 
 IntrusiveRefCntPtr<PathDiagnosticEventPiece>
@@ -622,7 +718,9 @@
   ID.AddString(str);
   // FIXME: Add profiling support for code hints.
   ID.AddInteger((unsigned) getDisplayHint());
-  for (range_iterator I = ranges_begin(), E = ranges_end(); I != E; ++I) {
+  ArrayRef<SourceRange> Ranges = getRanges();
+  for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
+                                        I != E; ++I) {
     ID.AddInteger(I->getBegin().getRawEncoding());
     ID.AddInteger(I->getEnd().getRawEncoding());
   }  
@@ -677,6 +775,7 @@
   const CallExitEnd *CExit = dyn_cast<CallExitEnd>(&P);
   assert(CExit && "Stack Hints should be constructed at CallExitEnd points.");
 
+  // FIXME: Use CallEvent to abstract this over all calls.
   const Stmt *CallSite = CExit->getCalleeContext()->getCallSite();
   const CallExpr *CE = dyn_cast_or_null<CallExpr>(CallSite);
   if (!CE)
diff --git a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index 58a4bba..d5fdd9d 100644
--- a/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -30,23 +30,21 @@
   class PlistDiagnostics : public PathDiagnosticConsumer {
     const std::string OutputFile;
     const LangOptions &LangOpts;
-    OwningPtr<PathDiagnosticConsumer> SubPD;
     const bool SupportsCrossFileDiagnostics;
   public:
     PlistDiagnostics(const std::string& prefix, const LangOptions &LangOpts,
-                     bool supportsMultipleFiles,
-                     PathDiagnosticConsumer *subPD);
+                     bool supportsMultipleFiles);
 
     virtual ~PlistDiagnostics() {}
 
     void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                              SmallVectorImpl<std::string> *FilesMade);
+                              FilesMade *filesMade);
     
     virtual StringRef getName() const {
       return "PlistDiagnostics";
     }
 
-    PathGenerationScheme getGenerationScheme() const;
+    PathGenerationScheme getGenerationScheme() const { return Extensive; }
     bool supportsLogicalOpControlFlow() const { return true; }
     bool supportsAllBlockEdges() const { return true; }
     virtual bool useVerboseDescription() const { return false; }
@@ -58,29 +56,20 @@
 
 PlistDiagnostics::PlistDiagnostics(const std::string& output,
                                    const LangOptions &LO,
-                                   bool supportsMultipleFiles,
-                                   PathDiagnosticConsumer *subPD)
-  : OutputFile(output), LangOpts(LO), SubPD(subPD),
+                                   bool supportsMultipleFiles)
+  : OutputFile(output), LangOpts(LO),
     SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
 
-PathDiagnosticConsumer*
-ento::createPlistDiagnosticConsumer(const std::string& s, const Preprocessor &PP,
-                                  PathDiagnosticConsumer *subPD) {
-  return new PlistDiagnostics(s, PP.getLangOpts(), false, subPD);
+void ento::createPlistDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                         const std::string& s,
+                                         const Preprocessor &PP) {
+  C.push_back(new PlistDiagnostics(s, PP.getLangOpts(), false));
 }
 
-PathDiagnosticConsumer*
-ento::createPlistMultiFileDiagnosticConsumer(const std::string &s,
-                                              const Preprocessor &PP) {
-  return new PlistDiagnostics(s, PP.getLangOpts(), true, 0);
-}
-
-PathDiagnosticConsumer::PathGenerationScheme
-PlistDiagnostics::getGenerationScheme() const {
-  if (const PathDiagnosticConsumer *PD = SubPD.get())
-    return PD->getGenerationScheme();
-
-  return Extensive;
+void ento::createPlistMultiFileDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                                  const std::string &s,
+                                                  const Preprocessor &PP) {
+  C.push_back(new PlistDiagnostics(s, PP.getLangOpts(), true));
 }
 
 static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
@@ -231,15 +220,16 @@
   EmitLocation(o, SM, LangOpts, L, FM, indent);
 
   // Output the ranges (if any).
-  PathDiagnosticPiece::range_iterator RI = P.ranges_begin(),
-  RE = P.ranges_end();
+  ArrayRef<SourceRange> Ranges = P.getRanges();
 
-  if (RI != RE) {
+  if (!Ranges.empty()) {
     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);
+    for (ArrayRef<SourceRange>::iterator I = Ranges.begin(), E = Ranges.end();
+         I != E; ++I) {
+      EmitRange(o, SM, LangOpts, *I, FM, indent+1);
+    }
     --indent;
     Indent(o, indent) << "</array>\n";
   }
@@ -353,7 +343,7 @@
 
 void PlistDiagnostics::FlushDiagnosticsImpl(
                                     std::vector<const PathDiagnostic *> &Diags,
-                                    SmallVectorImpl<std::string> *FilesMade) {
+                                    FilesMade *filesMade) {
   // Build up a set of FIDs that we use by scanning the locations and
   // ranges of the diagnostics.
   FIDMap FM;
@@ -380,11 +370,11 @@
            I!=E; ++I) {
         const PathDiagnosticPiece *piece = I->getPtr();
         AddFID(FM, Fids, SM, piece->getLocation().asLocation());
-
-        for (PathDiagnosticPiece::range_iterator RI = piece->ranges_begin(),
-             RE= piece->ranges_end(); RI != RE; ++RI) {
-          AddFID(FM, Fids, SM, RI->getBegin());
-          AddFID(FM, Fids, SM, RI->getEnd());
+        ArrayRef<SourceRange> Ranges = piece->getRanges();
+        for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
+                                             E = Ranges.end(); I != E; ++I) {
+          AddFID(FM, Fids, SM, I->getBegin());
+          AddFID(FM, Fids, SM, I->getEnd());
         }
 
         if (const PathDiagnosticCallPiece *call =
@@ -507,19 +497,21 @@
     EmitLocation(o, *SM, LangOpts, D->getLocation(), FM, 2);
 
     // Output the diagnostic to the sub-diagnostic client, if any.
-    if (SubPD) {
-      std::vector<const PathDiagnostic *> SubDiags;
-      SubDiags.push_back(D);
-      SmallVector<std::string, 1> SubFilesMade;
-      SubPD->FlushDiagnosticsImpl(SubDiags, &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";
+    if (!filesMade->empty()) {
+      StringRef lastName;
+      for (FilesMade::iterator I = filesMade->begin(), E = filesMade->end();
+           I != E; ++I) {
+        StringRef newName = I->first;
+        if (newName != lastName) {
+          if (!lastName.empty())
+            o << "  </array>\n";
+          lastName = newName;
+          o <<  "  <key>" << lastName << "_files</key>\n";
+          o << "  <array>\n";
+        }
+        o << "   <string>" << I->second << "</string>\n";
       }
+      o << "  </array>\n";
     }
 
     // Close up the entry.
@@ -531,6 +523,8 @@
   // Finish.
   o << "</dict>\n</plist>";
   
-  if (FilesMade)
-    FilesMade->push_back(OutputFile);
+  if (filesMade) {
+    StringRef Name(getName());
+    filesMade->push_back(std::make_pair(Name, OutputFile));
+  }
 }
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 529be0a..2000338 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Analysis/CFG.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
@@ -70,6 +71,19 @@
     stateMgr->getStoreManager().decrementReferenceCount(store);
 }
 
+ProgramStateManager::ProgramStateManager(ASTContext &Ctx,
+                                         StoreManagerCreator CreateSMgr,
+                                         ConstraintManagerCreator CreateCMgr,
+                                         llvm::BumpPtrAllocator &alloc,
+                                         SubEngine &SubEng)
+  : Eng(&SubEng), EnvMgr(alloc), GDMFactory(alloc),
+    svalBuilder(createSimpleSValBuilder(alloc, Ctx, *this)),
+    CallEventMgr(new CallEventManager(alloc)), Alloc(alloc) {
+  StoreMgr.reset((*CreateSMgr)(*this));
+  ConstraintMgr.reset((*CreateCMgr)(*this, SubEng));
+}
+
+
 ProgramStateManager::~ProgramStateManager() {
   for (GDMContextsTy::iterator I=GDMContexts.begin(), E=GDMContexts.end();
        I!=E; ++I)
@@ -485,8 +499,6 @@
   return getPersistentState(NewState);
 }
 
-void ScanReachableSymbols::anchor() { }
-
 bool ScanReachableSymbols::scan(nonloc::CompoundVal val) {
   for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I)
     if (!scan(*I))
@@ -530,6 +542,9 @@
   if (loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(&val))
     return scan(X->getRegion());
 
+  if (nonloc::LazyCompoundVal *X = dyn_cast<nonloc::LazyCompoundVal>(&val))
+    return scan(X->getRegion());
+
   if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&val))
     return scan(X->getLoc());
 
@@ -564,10 +579,19 @@
       return false;
 
   // If this is a subregion, also visit the parent regions.
-  if (const SubRegion *SR = dyn_cast<SubRegion>(R))
-    if (!scan(SR->getSuperRegion()))
+  if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+    const MemRegion *Super = SR->getSuperRegion();
+    if (!scan(Super))
       return false;
 
+    // When we reach the topmost region, scan all symbols in it.
+    if (isa<MemSpaceRegion>(Super)) {
+      StoreManager &StoreMgr = state->getStateManager().getStoreManager();
+      if (!StoreMgr.scanReachableSymbols(state->getStore(), SR, *this))
+        return false;
+    }
+  }
+
   // Regions captured by a block are also implicitly reachable.
   if (const BlockDataRegion *BDR = dyn_cast<BlockDataRegion>(R)) {
     BlockDataRegion::referenced_vars_iterator I = BDR->referenced_vars_begin(),
@@ -578,16 +602,7 @@
     }
   }
 
-  // Now look at the binding to this region (if any).
-  if (!scan(state->getSValAsScalarOrLoc(R)))
-    return false;
-
-  // Now look at the subregions.
-  if (!SRM.get())
-    SRM.reset(state->getStateManager().getStoreManager().
-                                           getSubRegionMap(state->getStore()));
-
-  return SRM->iterSubRegions(R, *this);
+  return true;
 }
 
 bool ProgramState::scanReachableSymbols(SVal val, SymbolVisitor& visitor) const {
@@ -717,3 +732,42 @@
   
   return Tainted;
 }
+
+/// The GDM component containing the dynamic type info. This is a map from a
+/// symbol to it's most likely type.
+namespace clang {
+namespace ento {
+typedef llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo> DynamicTypeMap;
+template<> struct ProgramStateTrait<DynamicTypeMap>
+    : public ProgramStatePartialTrait<DynamicTypeMap> {
+  static void *GDMIndex() { static int index; return &index; }
+};
+}}
+
+DynamicTypeInfo ProgramState::getDynamicTypeInfo(const MemRegion *Reg) const {
+  Reg = Reg->StripCasts();
+
+  // Look up the dynamic type in the GDM.
+  const DynamicTypeInfo *GDMType = get<DynamicTypeMap>(Reg);
+  if (GDMType)
+    return *GDMType;
+
+  // Otherwise, fall back to what we know about the region.
+  if (const TypedRegion *TR = dyn_cast<TypedRegion>(Reg))
+    return DynamicTypeInfo(TR->getLocationType(), /*CanBeSubclass=*/false);
+
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) {
+    SymbolRef Sym = SR->getSymbol();
+    return DynamicTypeInfo(Sym->getType(getStateManager().getContext()));
+  }
+
+  return DynamicTypeInfo();
+}
+
+ProgramStateRef ProgramState::setDynamicTypeInfo(const MemRegion *Reg,
+                                                 DynamicTypeInfo NewTy) const {
+  Reg = Reg->StripCasts();
+  ProgramStateRef NewState = set<DynamicTypeMap>(Reg, NewTy);
+  assert(NewState);
+  return NewState;
+}
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 3dc7f7f..bc4e4bb 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -17,10 +17,11 @@
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/CXXInheritance.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
@@ -40,23 +41,49 @@
 namespace {
 class BindingKey {
 public:
-  enum Kind { Direct = 0x0, Default = 0x1 };
+  enum Kind { Default = 0x0, Direct = 0x1 };
 private:
-  llvm ::PointerIntPair<const MemRegion*, 1> P;
-  uint64_t Offset;
+  enum { Symbolic = 0x2 };
 
+  llvm::PointerIntPair<const MemRegion *, 2> P;
+  uint64_t Data;
+
+  explicit BindingKey(const MemRegion *r, const MemRegion *Base, Kind k)
+    : P(r, k | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) {
+    assert(r && Base && "Must have known regions.");
+    assert(getConcreteOffsetRegion() == Base && "Failed to store base region");
+  }
   explicit BindingKey(const MemRegion *r, uint64_t offset, Kind k)
-    : P(r, (unsigned) k), Offset(offset) {}
+    : P(r, k), Data(offset) {
+    assert(r && "Must have known regions.");
+    assert(getOffset() == offset && "Failed to store offset");
+    assert((r == r->getBaseRegion() || isa<ObjCIvarRegion>(r)) && "Not a base");
+  }
 public:
 
-  bool isDirect() const { return P.getInt() == Direct; }
+  bool isDirect() const { return P.getInt() & Direct; }
+  bool hasSymbolicOffset() const { return P.getInt() & Symbolic; }
 
   const MemRegion *getRegion() const { return P.getPointer(); }
-  uint64_t getOffset() const { return Offset; }
+  uint64_t getOffset() const {
+    assert(!hasSymbolicOffset());
+    return Data;
+  }
+
+  const MemRegion *getConcreteOffsetRegion() const {
+    assert(hasSymbolicOffset());
+    return reinterpret_cast<const MemRegion *>(static_cast<uintptr_t>(Data));
+  }
+
+  const MemRegion *getBaseRegion() const {
+    if (hasSymbolicOffset())
+      return getConcreteOffsetRegion()->getBaseRegion();
+    return getRegion()->getBaseRegion();
+  }
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
     ID.AddPointer(P.getOpaqueValue());
-    ID.AddInteger(Offset);
+    ID.AddInteger(Data);
   }
 
   static BindingKey Make(const MemRegion *R, Kind k);
@@ -66,43 +93,48 @@
       return true;
     if (P.getOpaqueValue() > X.P.getOpaqueValue())
       return false;
-    return Offset < X.Offset;
+    return Data < X.Data;
   }
 
   bool operator==(const BindingKey &X) const {
     return P.getOpaqueValue() == X.P.getOpaqueValue() &&
-           Offset == X.Offset;
+           Data == X.Data;
   }
 
-  bool isValid() const {
-    return getRegion() != NULL;
-  }
+  LLVM_ATTRIBUTE_USED void dump() const;
 };
 } // end anonymous namespace
 
 BindingKey BindingKey::Make(const MemRegion *R, Kind k) {
   const RegionOffset &RO = R->getAsOffset();
-  if (RO.getRegion())
-    return BindingKey(RO.getRegion(), RO.getOffset(), k);
+  if (RO.hasSymbolicOffset())
+    return BindingKey(R, RO.getRegion(), k);
 
-  return BindingKey(R, 0, k);
+  return BindingKey(RO.getRegion(), RO.getOffset(), k);
 }
 
 namespace llvm {
   static inline
   raw_ostream &operator<<(raw_ostream &os, BindingKey K) {
-    os << '(' << K.getRegion() << ',' << K.getOffset()
-       << ',' << (K.isDirect() ? "direct" : "default")
+    os << '(' << K.getRegion();
+    if (!K.hasSymbolicOffset())
+      os << ',' << K.getOffset();
+    os << ',' << (K.isDirect() ? "direct" : "default")
        << ')';
     return os;
   }
 } // end llvm namespace
 
+void BindingKey::dump() const {
+  llvm::errs() << *this;
+}
+
 //===----------------------------------------------------------------------===//
 // Actual Store type.
 //===----------------------------------------------------------------------===//
 
-typedef llvm::ImmutableMap<BindingKey, SVal> RegionBindings;
+typedef llvm::ImmutableMap<BindingKey, SVal> ClusterBindings;
+typedef llvm::ImmutableMap<const MemRegion *, ClusterBindings> RegionBindings;
 
 //===----------------------------------------------------------------------===//
 // Fine-grained control of RegionStoreManager.
@@ -133,75 +165,15 @@
 
 namespace {
 
-class RegionStoreSubRegionMap : public SubRegionMap {
-public:
-  typedef llvm::ImmutableSet<const MemRegion*> Set;
-  typedef llvm::DenseMap<const MemRegion*, Set> Map;
-private:
-  Set::Factory F;
-  Map M;
-public:
-  bool add(const MemRegion* Parent, const MemRegion* SubRegion) {
-    Map::iterator I = M.find(Parent);
-
-    if (I == M.end()) {
-      M.insert(std::make_pair(Parent, F.add(F.getEmptySet(), SubRegion)));
-      return true;
-    }
-
-    I->second = F.add(I->second, SubRegion);
-    return false;
-  }
-
-  void process(SmallVectorImpl<const SubRegion*> &WL, const SubRegion *R);
-
-  ~RegionStoreSubRegionMap() {}
-
-  const Set *getSubRegions(const MemRegion *Parent) const {
-    Map::const_iterator I = M.find(Parent);
-    return I == M.end() ? NULL : &I->second;
-  }
-
-  bool iterSubRegions(const MemRegion* Parent, Visitor& V) const {
-    Map::const_iterator I = M.find(Parent);
-
-    if (I == M.end())
-      return true;
-
-    Set S = I->second;
-    for (Set::iterator SI=S.begin(),SE=S.end(); SI != SE; ++SI) {
-      if (!V.Visit(Parent, *SI))
-        return false;
-    }
-
-    return true;
-  }
-};
-
-void
-RegionStoreSubRegionMap::process(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;
   RegionBindings::Factory RBFactory;
+  ClusterBindings::Factory CBFactory;
 
 public:
   RegionStoreManager(ProgramStateManager& mgr, const RegionStoreFeatures &f)
-    : StoreManager(mgr),
-      Features(f),
-      RBFactory(mgr.getAllocator()) {}
-
-  SubRegionMap *getSubRegionMap(Store store) {
-    return getRegionStoreSubRegionMap(store);
-  }
-
-  RegionStoreSubRegionMap *getRegionStoreSubRegionMap(Store store);
+    : StoreManager(mgr), Features(f),
+      RBFactory(mgr.getAllocator()), CBFactory(mgr.getAllocator()) {}
 
   Optional<SVal> getDirectBinding(RegionBindings B, const MemRegion *R);
   /// getDefaultBinding - Returns an SVal* representing an optional default
@@ -255,10 +227,12 @@
                              const CallEvent *Call,
                              InvalidatedRegions *Invalidated);
 
+  bool scanReachableSymbols(Store S, const MemRegion *R,
+                            ScanReachableSymbols &Callbacks);
+
 public:   // Made public for helper classes.
 
-  void RemoveSubRegionBindings(RegionBindings &B, const MemRegion *R,
-                               RegionStoreSubRegionMap &M);
+  RegionBindings removeSubRegionBindings(RegionBindings B, const SubRegion *R);
 
   RegionBindings addBinding(RegionBindings B, BindingKey K, SVal V);
 
@@ -277,6 +251,8 @@
                         BindingKey::Default);
   }
 
+  RegionBindings removeCluster(RegionBindings B, const MemRegion *R);
+
 public: // Part of public interface to class.
 
   StoreRef Bind(Store store, Loc LV, SVal V);
@@ -307,8 +283,9 @@
 
   StoreRef BindArray(Store store, const TypedValueRegion* R, SVal V);
 
-  /// KillStruct - Set the entire struct to unknown.
-  StoreRef KillStruct(Store store, const TypedRegion* R, SVal DefaultVal);
+  /// Clears out all bindings in the given region and assigns a new value
+  /// as a Default binding.
+  StoreRef BindAggregate(Store store, const TypedRegion *R, SVal DefaultVal);
 
   StoreRef Remove(Store store, Loc LV);
 
@@ -378,9 +355,6 @@
                  const MemRegion *originalRegion,
                  bool includeSuffix = false);
 
-  StoreRef CopyLazyBindings(nonloc::LazyCompoundVal V, Store store,
-                            const TypedRegion *R);
-
   //===------------------------------------------------------------------===//
   // State pruning.
   //===------------------------------------------------------------------===//
@@ -411,14 +385,18 @@
 
   void iterBindings(Store store, BindingsHandler& f) {
     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;
+    for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+      const ClusterBindings &Cluster = I.getData();
+      for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
+           CI != CE; ++CI) {
+        const BindingKey &K = CI.getKey();
+        if (!K.isDirect())
+          continue;
+        if (const SubRegion *R = dyn_cast<SubRegion>(K.getRegion())) {
+          // FIXME: Possibly incorporate the offset?
+          if (!f.HandleBinding(*this, store, R, CI.getData()))
+            return;
+        }
       }
     }
   }
@@ -443,28 +421,6 @@
 }
 
 
-RegionStoreSubRegionMap*
-RegionStoreManager::getRegionStoreSubRegionMap(Store store) {
-  RegionBindings B = GetRegionBindings(store);
-  RegionStoreSubRegionMap *M = new RegionStoreSubRegionMap();
-
-  SmallVector<const SubRegion*, 10> WL;
-
-  for (RegionBindings::iterator I=B.begin(), E=B.end(); I!=E; ++I)
-    if (const SubRegion *R = dyn_cast<SubRegion>(I.getKey().getRegion()))
-      M->process(WL, R);
-
-  // We also need to record in the subregion map "intermediate" regions that
-  // don't have direct bindings but are super regions of those that do.
-  while (!WL.empty()) {
-    const SubRegion *R = WL.back();
-    WL.pop_back();
-    M->process(WL, R);
-  }
-
-  return M;
-}
-
 //===----------------------------------------------------------------------===//
 // Region Cluster analysis.
 //===----------------------------------------------------------------------===//
@@ -473,14 +429,11 @@
 template <typename DERIVED>
 class ClusterAnalysis  {
 protected:
-  typedef BumpVector<BindingKey> RegionCluster;
-  typedef llvm::DenseMap<const MemRegion *, RegionCluster *> ClusterMap;
-  llvm::DenseMap<const RegionCluster*, unsigned> Visited;
-  typedef SmallVector<std::pair<const MemRegion *, RegionCluster*>, 10>
-    WorkList;
+  typedef llvm::DenseMap<const MemRegion *, const ClusterBindings *> ClusterMap;
+  typedef SmallVector<const MemRegion *, 10> WorkList;
 
-  BumpVectorContext BVC;
-  ClusterMap ClusterM;
+  llvm::SmallPtrSet<const ClusterBindings *, 16> Visited;
+
   WorkList WL;
 
   RegionStoreManager &RM;
@@ -491,6 +444,10 @@
   
   const bool includeGlobals;
 
+  const ClusterBindings *getCluster(const MemRegion *R) {
+    return B.lookup(R);
+  }
+
 public:
   ClusterAnalysis(RegionStoreManager &rm, ProgramStateManager &StateMgr,
                   RegionBindings b, const bool includeGlobals)
@@ -500,59 +457,36 @@
 
   RegionBindings getRegionBindings() const { return B; }
 
-  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) {
-    return (bool) Visited[&getCluster(R->getBaseRegion())];
-  }
-
-  RegionCluster& getCluster(const MemRegion *R) {
-    RegionCluster *&CRef = ClusterM[R];
-    if (!CRef) {
-      void *Mem = BVC.getAllocator().template Allocate<RegionCluster>();
-      CRef = new (Mem) RegionCluster(BVC, 10);
-    }
-    return *CRef;
+    return Visited.count(getCluster(R));
   }
 
   void GenerateClusters() {
-      // Scan the entire set of bindings and make the region clusters.
+    // Scan the entire set of bindings and record the region clusters.
     for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
-      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);
-      }
+      const MemRegion *Base = RI.getKey();
+
+      const ClusterBindings &Cluster = RI.getData();
+      assert(!Cluster.isEmpty() && "Empty clusters should be removed");
+      static_cast<DERIVED*>(this)->VisitAddedToCluster(Base, Cluster);
+
+      if (includeGlobals)
+        if (isa<NonStaticGlobalSpaceRegion>(Base->getMemorySpace()))
+          AddToWorkList(Base, &Cluster);
     }
   }
 
-  bool AddToWorkList(const MemRegion *R, RegionCluster &C) {
-    if (unsigned &visited = Visited[&C])
-      return false;
-    else
-      visited = 1;
+  bool AddToWorkList(const MemRegion *R, const ClusterBindings *C) {
+    if (C) {
+      if (Visited.count(C))
+        return false;
+      Visited.insert(C);
+    }
 
-    WL.push_back(std::make_pair(R, &C));
+    WL.push_back(R);
     return true;
   }
 
-  bool AddToWorkList(BindingKey K) {
-    return AddToWorkList(K.getRegion());
-  }
-
   bool AddToWorkList(const MemRegion *R) {
     const MemRegion *baseR = R->getBaseRegion();
     return AddToWorkList(baseR, getCluster(baseR));
@@ -560,22 +494,20 @@
 
   void RunWorkList() {
     while (!WL.empty()) {
-      const MemRegion *baseR;
-      RegionCluster *C;
-      llvm::tie(baseR, C) = WL.back();
-      WL.pop_back();
+      const MemRegion *baseR = WL.pop_back_val();
 
-        // First visit the cluster.
-      static_cast<DERIVED*>(this)->VisitCluster(baseR, C->begin(), C->end());
+      // First visit the cluster.
+      if (const ClusterBindings *Cluster = getCluster(baseR))
+        static_cast<DERIVED*>(this)->VisitCluster(baseR, *Cluster);
 
-        // Next, visit the base region.
+      // Next, visit the base region.
       static_cast<DERIVED*>(this)->VisitBaseRegion(baseR);
     }
   }
 
 public:
-  void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C) {}
-  void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E) {}
+  void VisitAddedToCluster(const MemRegion *baseR, const ClusterBindings &C) {}
+  void VisitCluster(const MemRegion *baseR, const ClusterBindings &C) {}
   void VisitBaseRegion(const MemRegion *baseR) {}
 };
 }
@@ -584,16 +516,99 @@
 // Binding invalidation.
 //===----------------------------------------------------------------------===//
 
-void RegionStoreManager::RemoveSubRegionBindings(RegionBindings &B,
-                                                 const MemRegion *R,
-                                                 RegionStoreSubRegionMap &M) {
+bool RegionStoreManager::scanReachableSymbols(Store S, const MemRegion *R,
+                                              ScanReachableSymbols &Callbacks) {
+  assert(R == R->getBaseRegion() && "Should only be called for base regions");
+  RegionBindings B = GetRegionBindings(S);
+  const ClusterBindings *Cluster = B.lookup(R);
 
-  if (const RegionStoreSubRegionMap::Set *S = M.getSubRegions(R))
-    for (RegionStoreSubRegionMap::Set::iterator I = S->begin(), E = S->end();
-         I != E; ++I)
-      RemoveSubRegionBindings(B, *I, M);
+  if (!Cluster)
+    return true;
 
-  B = removeBinding(B, R);
+  for (ClusterBindings::iterator RI = Cluster->begin(), RE = Cluster->end();
+       RI != RE; ++RI) {
+    if (!Callbacks.scan(RI.getData()))
+      return false;
+  }
+
+  return true;
+}
+
+RegionBindings RegionStoreManager::removeSubRegionBindings(RegionBindings B,
+                                                           const SubRegion *R) {
+  BindingKey SRKey = BindingKey::Make(R, BindingKey::Default);
+  const MemRegion *ClusterHead = SRKey.getBaseRegion();
+  if (R == ClusterHead) {
+    // We can remove an entire cluster's bindings all in one go.
+    return RBFactory.remove(B, R);
+  }
+
+  if (SRKey.hasSymbolicOffset()) {
+    const SubRegion *Base = cast<SubRegion>(SRKey.getConcreteOffsetRegion());
+    B = removeSubRegionBindings(B, Base);
+    return addBinding(B, Base, BindingKey::Default, UnknownVal());
+  }
+
+  // This assumes the region being invalidated is char-aligned. This isn't
+  // true for bitfields, but since bitfields have no subregions they shouldn't
+  // be using this function anyway.
+  uint64_t Length = UINT64_MAX;
+
+  SVal Extent = R->getExtent(svalBuilder);
+  if (nonloc::ConcreteInt *ExtentCI = dyn_cast<nonloc::ConcreteInt>(&Extent)) {
+    const llvm::APSInt &ExtentInt = ExtentCI->getValue();
+    assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
+    // Extents are in bytes but region offsets are in bits. Be careful!
+    Length = ExtentInt.getLimitedValue() * Ctx.getCharWidth();
+  }
+
+  const ClusterBindings *Cluster = B.lookup(ClusterHead);
+  if (!Cluster)
+    return B;
+
+  ClusterBindings Result = *Cluster;
+
+  // It is safe to iterate over the bindings as they are being changed
+  // because they are in an ImmutableMap.
+  for (ClusterBindings::iterator I = Cluster->begin(), E = Cluster->end();
+       I != E; ++I) {
+    BindingKey NextKey = I.getKey();
+    if (NextKey.getRegion() == SRKey.getRegion()) {
+      if (NextKey.getOffset() > SRKey.getOffset() &&
+          NextKey.getOffset() - SRKey.getOffset() < Length) {
+        // Case 1: The next binding is inside the region we're invalidating.
+        // Remove it.
+        Result = CBFactory.remove(Result, NextKey);
+      } else if (NextKey.getOffset() == SRKey.getOffset()) {
+        // Case 2: The next binding is at the same offset as the region we're
+        // invalidating. In this case, we need to leave default bindings alone,
+        // since they may be providing a default value for a regions beyond what
+        // we're invalidating.
+        // FIXME: This is probably incorrect; consider invalidating an outer
+        // struct whose first field is bound to a LazyCompoundVal.
+        if (NextKey.isDirect())
+          Result = CBFactory.remove(Result, NextKey);
+      }
+    } else if (NextKey.hasSymbolicOffset()) {
+      const MemRegion *Base = NextKey.getConcreteOffsetRegion();
+      if (R->isSubRegionOf(Base)) {
+        // Case 3: The next key is symbolic and we just changed something within
+        // its concrete region. We don't know if the binding is still valid, so
+        // we'll be conservative and remove it.
+        if (NextKey.isDirect())
+          Result = CBFactory.remove(Result, NextKey);
+      } else if (const SubRegion *BaseSR = dyn_cast<SubRegion>(Base)) {
+        // Case 4: The next key is symbolic, but we changed a known
+        // super-region. In this case the binding is certainly no longer valid.
+        if (R == Base || BaseSR->isSubRegionOf(R))
+          Result = CBFactory.remove(Result, NextKey);
+      }
+    }
+  }
+
+  if (Result.isEmpty())
+    return RBFactory.remove(B, ClusterHead);
+  return RBFactory.add(B, ClusterHead, Result);
 }
 
 namespace {
@@ -616,7 +631,7 @@
     : ClusterAnalysis<invalidateRegionsWorker>(rm, stateMgr, b, includeGlobals),
       Ex(ex), Count(count), LCtx(lctx), IS(is), Regions(r) {}
 
-  void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
+  void VisitCluster(const MemRegion *baseR, const ClusterBindings &C);
   void VisitBaseRegion(const MemRegion *baseR);
 
 private:
@@ -641,26 +656,31 @@
     const MemRegion *LazyR = LCS->getRegion();
     RegionBindings B = RegionStoreManager::GetRegionBindings(LCS->getStore());
 
+    // FIXME: This should not have to walk all bindings in the old store.
     for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
-      const SubRegion *baseR = dyn_cast<SubRegion>(RI.getKey().getRegion());
-      if (baseR && (baseR == LazyR || baseR->isSubRegionOf(LazyR)))
-        VisitBinding(RI.getData());
+      const ClusterBindings &Cluster = RI.getData();
+      for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
+           CI != CE; ++CI) {
+        BindingKey K = CI.getKey();
+        if (const SubRegion *BaseR = dyn_cast<SubRegion>(K.getRegion())) {
+          if (BaseR == LazyR)
+            VisitBinding(CI.getData());
+          else if (K.hasSymbolicOffset() && BaseR->isSubRegionOf(LazyR))
+            VisitBinding(CI.getData());
+        }
+      }
     }
 
     return;
   }
 }
 
-void invalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
-                                           BindingKey *I, BindingKey *E) {
-  for ( ; I != E; ++I) {
-    // Get the old binding.  Is it a region?  If so, add it to the worklist.
-    const BindingKey &K = *I;
-    if (const SVal *V = RM.lookup(B, K))
-      VisitBinding(*V);
+void invalidateRegionsWorker::VisitCluster(const MemRegion *BaseR,
+                                           const ClusterBindings &C) {
+  for (ClusterBindings::iterator I = C.begin(), E = C.end(); I != E; ++I)
+    VisitBinding(I.getData());
 
-    B = RM.removeBinding(B, K);
-  }
+  B = RM.removeCluster(B, BaseR);
 }
 
 void invalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
@@ -915,7 +935,7 @@
   loc::MemRegionVal *baseRegVal = dyn_cast<loc::MemRegionVal>(&base);
   if (!baseRegVal)
     return UnknownVal();
-  const MemRegion *BaseRegion = baseRegVal->stripCasts();
+  const MemRegion *BaseRegion = baseRegVal->stripCasts(/*StripBases=*/false);
 
   // Assume the derived class is a pointer or a reference to a CXX record.
   derivedType = derivedType->getPointeeType();
@@ -938,23 +958,20 @@
     if (SRDecl == DerivedDecl)
       return loc::MemRegionVal(TSR);
 
-    // If the region type is a subclass of the derived type.
-    if (!derivedType->isVoidType() && SRDecl->isDerivedFrom(DerivedDecl)) {
-      // This occurs in two cases.
-      // 1) We are processing an upcast.
-      // 2) We are processing a downcast but we jumped directly from the
-      // ancestor to a child of the cast value, so conjure the
-      // appropriate region to represent value (the intermediate node).
-      return loc::MemRegionVal(MRMgr.getCXXBaseObjectRegion(DerivedDecl,
-                                                            BaseRegion));
-    }
-
-    // If super region is not a parent of derived class, the cast definitely
-    // fails.
-    if (!derivedType->isVoidType() &&
-        DerivedDecl->isProvablyNotDerivedFrom(SRDecl)) {
-      Failed = true;
-      return UnknownVal();
+    if (!derivedType->isVoidType()) {
+      // Static upcasts are marked as DerivedToBase casts by Sema, so this will
+      // only happen when multiple or virtual inheritance is involved.
+      CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
+                         /*DetectVirtual=*/false);
+      if (SRDecl->isDerivedFrom(DerivedDecl, Paths)) {
+        SVal Result = loc::MemRegionVal(TSR);
+        const CXXBasePath &Path = *Paths.begin();
+        for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end();
+             I != E; ++I) {
+          Result = evalDerivedToBase(Result, I->Base->getType());
+        }
+        return Result;
+      }
     }
 
     if (const CXXBaseObjectRegion *R = dyn_cast<CXXBaseObjectRegion>(TSR))
@@ -1499,16 +1516,23 @@
                                             const MemRegion *region) const {
   RegionBindings B = GetRegionBindings(store);
   region = region->getBaseRegion();
-  
-  for (RegionBindings::iterator it = B.begin(), ei = B.end(); it != ei; ++it) {
-    const BindingKey &K = it.getKey();
-    if (region == K.getRegion())
-      return true;
-    const SVal &D = it.getData();
-    if (const MemRegion *r = D.getAsRegion())
-      if (r == region)
-        return true;
+
+  // Quick path: if the base is the head of a cluster, the region is live.
+  if (B.lookup(region))
+    return true;
+
+  // Slow path: if the region is the VALUE of any binding, it is live.
+  for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
+    const ClusterBindings &Cluster = RI.getData();
+    for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
+         CI != CE; ++CI) {
+      const SVal &D = CI.getData();
+      if (const MemRegion *R = D.getAsRegion())
+        if (R->getBaseRegion() == region)
+          return true;
+    }
   }
+
   return false;
 }
 
@@ -1542,20 +1566,7 @@
       return BindVector(store, TR, V);
   }
 
-  if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
-    if (ER->getIndex().isZeroConstant()) {
-      if (const TypedValueRegion *superR =
-            dyn_cast<TypedValueRegion>(ER->getSuperRegion())) {
-        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->isStructureOrClassType())
-          return KillStruct(store, superR, UnknownVal());
-      }
-    }
-  }
-  else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
+  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(Ctx);
@@ -1569,10 +1580,13 @@
     R = GetElementZeroRegion(SR, T);
   }
 
+  // Clear out bindings that may overlap with this binding.
+
   // Perform the binding.
   RegionBindings B = GetRegionBindings(store);
-  return StoreRef(addBinding(B, R, BindingKey::Direct,
-                             V).getRootWithoutRetain(), *this);
+  B = removeSubRegionBindings(B, cast<SubRegion>(R));
+  BindingKey Key = BindingKey::Make(R, BindingKey::Direct);
+  return StoreRef(addBinding(B, Key, V).getRootWithoutRetain(), *this);
 }
 
 StoreRef RegionStoreManager::BindDecl(Store store, const VarRegion *VR,
@@ -1643,12 +1657,12 @@
     nonloc::LazyCompoundVal LCV =
       cast<nonloc::LazyCompoundVal>(svalBuilder.
                                 makeLazyCompoundVal(StoreRef(store, *this), S));
-    return CopyLazyBindings(LCV, store, R);
+    return BindAggregate(store, R, LCV);
   }
 
   // Handle lazy compound values.
-  if (nonloc::LazyCompoundVal *LCV = dyn_cast<nonloc::LazyCompoundVal>(&Init))
-    return CopyLazyBindings(*LCV, store, R);
+  if (isa<nonloc::LazyCompoundVal>(Init))
+    return BindAggregate(store, R, Init);
 
   // Remaining case: explicit compound values.
 
@@ -1690,16 +1704,15 @@
   assert(T->isVectorType());
   const VectorType *VT = T->getAs<VectorType>(); // Use getAs for typedefs.
  
-  // Handle lazy compound values.
-  if (nonloc::LazyCompoundVal *LCV = dyn_cast<nonloc::LazyCompoundVal>(&V))
-    return CopyLazyBindings(*LCV, store, R);
+  // Handle lazy compound values and symbolic values.
+  if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))
+    return BindAggregate(store, R, V);
   
   // 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);
+  if (!isa<nonloc::CompoundVal>(V)) {
+    return BindAggregate(store, R, UnknownVal());
   }
 
   QualType ElemType = VT->getElementType();
@@ -1740,17 +1753,15 @@
   if (!RD->isCompleteDefinition())
     return StoreRef(store, *this);
 
-  // Handle lazy compound values.
-  if (const nonloc::LazyCompoundVal *LCV=dyn_cast<nonloc::LazyCompoundVal>(&V))
-    return CopyLazyBindings(*LCV, store, R);
+  // Handle lazy compound values and symbolic values.
+  if (isa<nonloc::LazyCompoundVal>(V) || isa<nonloc::SymbolVal>(V))
+    return BindAggregate(store, R, V);
 
   // 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);
-  }
+  if (V.isUnknown() || !isa<nonloc::CompoundVal>(V))
+    return BindAggregate(store, R, UnknownVal());
 
   nonloc::CompoundVal& CV = cast<nonloc::CompoundVal>(V);
   nonloc::CompoundVal::iterator VI = CV.begin(), VE = CV.end();
@@ -1789,58 +1800,16 @@
   return newStore;
 }
 
-StoreRef RegionStoreManager::KillStruct(Store store, const TypedRegion* R,
-                                     SVal DefaultVal) {
-  BindingKey key = BindingKey::Make(R, BindingKey::Default);
-  
-  // The BindingKey may be "invalid" if we cannot handle the region binding
-  // explicitly.  One example is something like array[index], where index
-  // is a symbolic value.  In such cases, we want to invalidate the entire
-  // array, as the index assignment could have been to any element.  In
-  // the case of nested symbolic indices, we need to march up the region
-  // hierarchy untile we reach a region whose binding we can reason about.
-  const SubRegion *subReg = R;
-
-  while (!key.isValid()) {
-    if (const SubRegion *tmp = dyn_cast<SubRegion>(subReg->getSuperRegion())) {
-      subReg = tmp;
-      key = BindingKey::Make(tmp, BindingKey::Default);
-    }
-    else
-      break;
-  }                                 
-
-  // Remove the old bindings, using 'subReg' as the root of all regions
-  // we will invalidate.
-  RegionBindings B = GetRegionBindings(store);
-  OwningPtr<RegionStoreSubRegionMap>
-    SubRegions(getRegionStoreSubRegionMap(store));
-  RemoveSubRegionBindings(B, subReg, *SubRegions);
-
-  // Set the default value of the struct region to "unknown".
-  if (!key.isValid())
-    return StoreRef(B.getRootWithoutRetain(), *this);
-  
-  return StoreRef(addBinding(B, key, DefaultVal).getRootWithoutRetain(), *this);
-}
-
-StoreRef RegionStoreManager::CopyLazyBindings(nonloc::LazyCompoundVal V,
-                                              Store store,
-                                              const TypedRegion *R) {
-
-  // Nuke the old bindings stemming from R.
+StoreRef RegionStoreManager::BindAggregate(Store store, const TypedRegion *R,
+                                           SVal Val) {
+  // Remove the old bindings, using 'R' as the root of all regions
+  // we will invalidate. Then add the new binding.
   RegionBindings B = GetRegionBindings(store);
 
-  OwningPtr<RegionStoreSubRegionMap>
-    SubRegions(getRegionStoreSubRegionMap(store));
+  B = removeSubRegionBindings(B, R);
+  B = addBinding(B, R, BindingKey::Default, Val);
 
-  // B and DVM are updated after the call to RemoveSubRegionBindings.
-  RemoveSubRegionBindings(B, R, *SubRegions.get());
-
-  // Now copy the bindings.  This amounts to just binding 'V' to 'R'.  This
-  // results in a zero-copy algorithm.
-  return StoreRef(addBinding(B, R, BindingKey::Default,
-                             V).getRootWithoutRetain(), *this);
+  return StoreRef(B.getRootWithoutRetain(), *this);
 }
 
 //===----------------------------------------------------------------------===//
@@ -1850,9 +1819,14 @@
 
 RegionBindings RegionStoreManager::addBinding(RegionBindings B, BindingKey K,
                                               SVal V) {
-  if (!K.isValid())
-    return B;
-  return RBFactory.add(B, K, V);
+  const MemRegion *Base = K.getBaseRegion();
+  
+  const ClusterBindings *ExistingCluster = B.lookup(Base);
+  ClusterBindings Cluster = (ExistingCluster ? *ExistingCluster
+                                             : CBFactory.getEmptyMap());
+
+  ClusterBindings NewCluster = CBFactory.add(Cluster, K, V);
+  return RBFactory.add(B, Base, NewCluster);
 }
 
 RegionBindings RegionStoreManager::addBinding(RegionBindings B,
@@ -1862,9 +1836,11 @@
 }
 
 const SVal *RegionStoreManager::lookup(RegionBindings B, BindingKey K) {
-  if (!K.isValid())
-    return NULL;
-  return B.lookup(K);
+  const ClusterBindings *Cluster = B.lookup(K.getBaseRegion());
+  if (!Cluster)
+    return 0;
+
+  return Cluster->lookup(K);
 }
 
 const SVal *RegionStoreManager::lookup(RegionBindings B,
@@ -1875,9 +1851,15 @@
 
 RegionBindings RegionStoreManager::removeBinding(RegionBindings B,
                                                  BindingKey K) {
-  if (!K.isValid())
+  const MemRegion *Base = K.getBaseRegion();
+  const ClusterBindings *Cluster = B.lookup(Base);
+  if (!Cluster)
     return B;
-  return RBFactory.remove(B, K);
+
+  ClusterBindings NewCluster = CBFactory.remove(*Cluster, K);
+  if (NewCluster.isEmpty())
+    return RBFactory.remove(B, Base);
+  return RBFactory.add(B, Base, NewCluster);
 }
 
 RegionBindings RegionStoreManager::removeBinding(RegionBindings B,
@@ -1886,6 +1868,11 @@
   return removeBinding(B, BindingKey::Make(R, k));
 }
 
+RegionBindings RegionStoreManager::removeCluster(RegionBindings B,
+                                                 const MemRegion *Base) {
+  return RBFactory.remove(B, Base);
+}
+
 //===----------------------------------------------------------------------===//
 // State pruning.
 //===----------------------------------------------------------------------===//
@@ -1907,8 +1894,8 @@
       SymReaper(symReaper), CurrentLCtx(LCtx) {}
 
   // Called by ClusterAnalysis.
-  void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C);
-  void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
+  void VisitAddedToCluster(const MemRegion *baseR, const ClusterBindings &C);
+  void VisitCluster(const MemRegion *baseR, const ClusterBindings &C);
 
   void VisitBindingKey(BindingKey K);
   bool UpdatePostponed();
@@ -1917,18 +1904,18 @@
 }
 
 void removeDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR,
-                                                   RegionCluster &C) {
+                                                   const ClusterBindings &C) {
 
   if (const VarRegion *VR = dyn_cast<VarRegion>(baseR)) {
     if (SymReaper.isLive(VR))
-      AddToWorkList(baseR, C);
+      AddToWorkList(baseR, &C);
 
     return;
   }
 
   if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR)) {
     if (SymReaper.isLive(SR->getSymbol()))
-      AddToWorkList(SR, C);
+      AddToWorkList(SR, &C);
     else
       Postponed.push_back(SR);
 
@@ -1936,7 +1923,7 @@
   }
 
   if (isa<NonStaticGlobalSpaceRegion>(baseR)) {
-    AddToWorkList(baseR, C);
+    AddToWorkList(baseR, &C);
     return;
   }
 
@@ -1946,28 +1933,41 @@
       cast<StackArgumentsSpaceRegion>(TR->getSuperRegion());
     const StackFrameContext *RegCtx = StackReg->getStackFrame();
     if (RegCtx == CurrentLCtx || RegCtx->isParentOf(CurrentLCtx))
-      AddToWorkList(TR, C);
+      AddToWorkList(TR, &C);
   }
 }
 
 void removeDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
-                                            BindingKey *I, BindingKey *E) {
-  for ( ; I != E; ++I)
-    VisitBindingKey(*I);
+                                            const ClusterBindings &C) {
+  for (ClusterBindings::iterator I = C.begin(), E = C.end(); I != E; ++I) {
+    VisitBindingKey(I.getKey());
+    VisitBinding(I.getData());
+  }
 }
 
 void removeDeadBindingsWorker::VisitBinding(SVal V) {
   // Is it a LazyCompoundVal?  All referenced regions are live as well.
   if (const nonloc::LazyCompoundVal *LCS =
-      dyn_cast<nonloc::LazyCompoundVal>(&V)) {
+        dyn_cast<nonloc::LazyCompoundVal>(&V)) {
 
     const MemRegion *LazyR = LCS->getRegion();
     RegionBindings B = RegionStoreManager::GetRegionBindings(LCS->getStore());
+
+    // FIXME: This should not have to walk all bindings in the old store.
     for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI){
-      const SubRegion *baseR = dyn_cast<SubRegion>(RI.getKey().getRegion());
-      if (baseR && baseR->isSubRegionOf(LazyR))
-        VisitBinding(RI.getData());
+      const ClusterBindings &Cluster = RI.getData();
+      for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
+           CI != CE; ++CI) {
+        BindingKey K = CI.getKey();
+        if (const SubRegion *BaseR = dyn_cast<SubRegion>(K.getRegion())) {
+          if (BaseR == LazyR)
+            VisitBinding(CI.getData());
+          else if (K.hasSymbolicOffset() && BaseR->isSubRegionOf(LazyR))
+            VisitBinding(CI.getData());
+        }
+      }
     }
+
     return;
   }
 
@@ -2003,10 +2003,6 @@
     if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
       SymReaper.markLive(SymR->getSymbol());
   }
-
-  // Visit the data binding for K.
-  if (const SVal *V = RM.lookup(B, K))
-    VisitBinding(*V);
 }
 
 bool removeDeadBindingsWorker::UpdatePostponed() {
@@ -2046,23 +2042,27 @@
   // as live.  We now remove all the regions that are dead from the store
   // as well as update DSymbols with the set symbols that are now dead.
   for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
-    const BindingKey &K = I.getKey();
+    const MemRegion *Base = I.getKey();
 
     // If the cluster has been visited, we know the region has been marked.
-    if (W.isVisited(K.getRegion()))
+    if (W.isVisited(Base))
       continue;
 
     // Remove the dead entry.
-    B = removeBinding(B, K);
+    B = removeCluster(B, Base);
 
-    // Mark all non-live symbols that this binding references as dead.
-    if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(K.getRegion()))
+    if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(Base))
       SymReaper.maybeDead(SymR->getSymbol());
 
-    SVal X = I.getData();
-    SymExpr::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
-    for (; SI != SE; ++SI)
-      SymReaper.maybeDead(*SI);
+    // Mark all non-live symbols that this binding references as dead.
+    const ClusterBindings &Cluster = I.getData();
+    for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
+         CI != CE; ++CI) {
+      SVal X = CI.getData();
+      SymExpr::symbol_iterator SI = X.symbol_begin(), SE = X.symbol_end();
+      for (; SI != SE; ++SI)
+        SymReaper.maybeDead(*SI);
+    }
   }
 
   return StoreRef(B.getRootWithoutRetain(), *this);
@@ -2079,6 +2079,12 @@
      << (void*) B.getRootWithoutRetain()
      << " :" << nl;
 
-  for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I)
-    OS << ' ' << I.getKey() << " : " << I.getData() << nl;
+  for (RegionBindings::iterator I = B.begin(), E = B.end(); I != E; ++I) {
+    const ClusterBindings &Cluster = I.getData();
+    for (ClusterBindings::iterator CI = Cluster.begin(), CE = Cluster.end();
+         CI != CE; ++CI) {
+      OS << ' ' << CI.getKey() << " : " << CI.getData() << nl;
+    }
+    OS << nl;
+  }
 }
diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp
index e32ffe2..8437f50 100644
--- a/lib/StaticAnalyzer/Core/SVals.cpp
+++ b/lib/StaticAnalyzer/Core/SVals.cpp
@@ -133,9 +133,9 @@
   return 0;
 }
 
-const MemRegion *loc::MemRegionVal::stripCasts() const {
+const MemRegion *loc::MemRegionVal::stripCasts(bool StripBaseCasts) const {
   const MemRegion *R = getRegion();
-  return R ?  R->StripCasts() : NULL;
+  return R ?  R->StripCasts(StripBaseCasts) : NULL;
 }
 
 const void *nonloc::LazyCompoundVal::getStore() const {
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index 5568f1c..0f675cd 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -84,14 +84,9 @@
     const SubRegion *SubR = dyn_cast<SubRegion>(R);
 
     while (SubR) {
-      // FIXME: now we only find the first symbolic region.
-      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) {
-        const llvm::APSInt &zero = getBasicVals().getZeroWithPtrWidth();
-        if (Assumption)
-          return assumeSymNE(state, SymR->getSymbol(), zero, zero);
-        else
-          return assumeSymEQ(state, SymR->getSymbol(), zero, zero);
-      }
+      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR))
+        return assumeAuxForSymbol(state, SymR->getSymbol(), Assumption);
+
       SubR = dyn_cast<SubRegion>(SubR->getSuperRegion());
     }
 
@@ -138,10 +133,13 @@
   BasicValueFactory &BVF = getBasicVals();
   QualType T = Sym->getType(BVF.getContext());
 
-  // None of the constraint solvers currently support non-integer types.
-  if (!T->isIntegerType())
+  // Don't do anything if this isn't a type we can constrain.
+  if (!(T->isIntegralOrEnumerationType() || Loc::isLocType(T)))
     return State;
 
+  if (T->isReferenceType())
+    return Assumption ? State : NULL;
+
   const llvm::APSInt &zero = BVF.getValue(0, T);
   if (Assumption)
     return assumeSymNE(State, Sym, zero, zero);
@@ -161,8 +159,6 @@
     return assumeAuxForSymbol(state, sym, Assumption);
   }
 
-  BasicValueFactory &BasicVals = getBasicVals();
-
   switch (Cond.getSubKind()) {
   default:
     llvm_unreachable("'Assume' not implemented for this NonLoc");
@@ -185,12 +181,9 @@
 
       BinaryOperator::Opcode op = SE->getOpcode();
       // Implicitly compare non-comparison expressions to 0.
-      if (!BinaryOperator::isComparisonOp(op)) {
-        QualType T = SE->getType(BasicVals.getContext());
-        const llvm::APSInt &zero = BasicVals.getValue(0, T);
-        op = (Assumption ? BO_NE : BO_EQ);
-        return assumeSymRel(state, SE, op, zero);
-      }
+      if (!BinaryOperator::isComparisonOp(op))
+        return assumeAuxForSymbol(state, SE, Assumption);
+
       // From here on out, op is the real comparison we'll be testing.
       if (!Assumption)
         op = NegateComparison(op);
@@ -238,8 +231,25 @@
   BasicValueFactory &BVF = getBasicVals();
   ASTContext &Ctx = BVF.getContext();
 
+  // Special case for references, which cannot be null.
+  QualType Ty = LHS->getType(Ctx);
+  if (Ty->isReferenceType() && Int == 0) {
+    switch (op) {
+    case BO_EQ:
+    case BO_LE:
+    case BO_LT:
+      return NULL;
+    case BO_NE:
+    case BO_GT:
+    case BO_GE:
+      return state;
+    default:
+      llvm_unreachable("We should only be handling comparisons here.");
+    }
+  }
+
   // Get the type used for calculating wraparound.
-  APSIntType WraparoundType = BVF.getAPSIntType(LHS->getType(Ctx));
+  APSIntType WraparoundType = BVF.getAPSIntType(Ty);
 
   // We only handle simple comparisons of the form "$sym == constant"
   // or "($sym+constant1) == constant2".
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index 916db13..3af60a1 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -12,7 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/Calls.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
@@ -29,28 +29,13 @@
                                        const StackFrameContext *LCtx) {
   StoreRef Store = StoreRef(OldStore, *this);
 
-  unsigned Idx = 0;
-  for (CallEvent::param_iterator I = Call.param_begin(/*UseDefinition=*/true),
-                                 E = Call.param_end(/*UseDefinition=*/true);
-       I != E; ++I, ++Idx) {
-    const ParmVarDecl *Decl = *I;
-    assert(Decl && "Formal parameter has no decl?");
+  SmallVector<CallEvent::FrameBindingTy, 16> InitialBindings;
+  Call.getInitialStackFrameContents(LCtx, InitialBindings);
 
-    SVal ArgVal = Call.getArgSVal(Idx);
-    if (!ArgVal.isUnknown()) {
-      Store = Bind(Store.getStore(),
-                   svalBuilder.makeLoc(MRMgr.getVarRegion(Decl, LCtx)),
-                   ArgVal);
-    }
-  }
-
-  // FIXME: We will eventually want to generalize this to handle other non-
-  // parameter arguments besides 'this' (such as 'self' for ObjC methods).
-  SVal ThisVal = Call.getCXXThisVal();
-  if (isa<DefinedSVal>(ThisVal)) {
-    const CXXMethodDecl *MD = cast<CXXMethodDecl>(Call.getDecl());
-    loc::MemRegionVal ThisRegion = svalBuilder.getCXXThis(MD, LCtx);
-    Store = Bind(Store.getStore(), ThisRegion, ThisVal);
+  for (CallEvent::BindingsTy::iterator I = InitialBindings.begin(),
+                                       E = InitialBindings.end();
+       I != E; ++I) {
+    Store = Bind(Store.getStore(), I->first, I->second);
   }
 
   return Store;
@@ -237,6 +222,17 @@
   llvm_unreachable("unreachable");
 }
 
+SVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) {
+  // Walk through the cast path to create nested CXXBaseRegions.
+  SVal Result = Derived;
+  for (CastExpr::path_const_iterator I = Cast->path_begin(),
+                                     E = Cast->path_end();
+       I != E; ++I) {
+    Result = evalDerivedToBase(Result, (*I)->getType());
+  }
+  return Result;
+}
+
 
 /// CastRetrievedVal - Used by subclasses of StoreManager to implement
 ///  implicit casts that arise from loads from regions that are reinterpreted
@@ -384,6 +380,3 @@
 
   return true;
 }
-
-void SubRegionMap::anchor() { }
-void SubRegionMap::Visitor::anchor() { }
diff --git a/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp b/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
index fe912df..66bf4bb 100644
--- a/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/TextPathDiagnostics.cpp
@@ -32,7 +32,7 @@
     : OutputFile(output), Diag(diag) {}
 
   void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
-                            SmallVectorImpl<std::string> *FilesMade);
+                            FilesMade *filesMade);
   
   virtual StringRef getName() const {
     return "TextPathDiagnostics";
@@ -42,23 +42,26 @@
   bool supportsLogicalOpControlFlow() const { return true; }
   bool supportsAllBlockEdges() const { return true; }
   virtual bool useVerboseDescription() const { return true; }
+  virtual bool supportsCrossFileDiagnostics() const { return true; }
 };
 
 } // end anonymous namespace
 
-PathDiagnosticConsumer*
-ento::createTextPathDiagnosticConsumer(const std::string& out,
-                                     const Preprocessor &PP) {
-  return new TextPathDiagnostics(out, PP.getDiagnostics());
+void ento::createTextPathDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                            const std::string& out,
+                                            const Preprocessor &PP) {
+  C.push_back(new TextPathDiagnostics(out, PP.getDiagnostics()));
 }
 
 void TextPathDiagnostics::FlushDiagnosticsImpl(
                               std::vector<const PathDiagnostic *> &Diags,
-                              SmallVectorImpl<std::string> *FilesMade) {
+                              FilesMade *) {
   for (std::vector<const PathDiagnostic *>::iterator it = Diags.begin(),
        et = Diags.end(); it != et; ++it) {
     const PathDiagnostic *D = *it;
-    for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end(); 
+
+    PathPieces FlatPath = D->path.flatten(/*ShouldFlattenMacros=*/true);
+    for (PathPieces::const_iterator I = FlatPath.begin(), E = FlatPath.end(); 
          I != E; ++I) {
       unsigned diagID =
         Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 72e5639..34b5266 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -64,14 +64,55 @@
 // Special PathDiagnosticConsumers.
 //===----------------------------------------------------------------------===//
 
-static PathDiagnosticConsumer*
-createPlistHTMLDiagnosticConsumer(const std::string& prefix,
-                                const Preprocessor &PP) {
-  PathDiagnosticConsumer *PD =
-    createHTMLDiagnosticConsumer(llvm::sys::path::parent_path(prefix), PP);
-  return createPlistDiagnosticConsumer(prefix, PP, PD);
+static void createPlistHTMLDiagnosticConsumer(PathDiagnosticConsumers &C,
+                                              const std::string &prefix,
+                                              const Preprocessor &PP) {
+  createHTMLDiagnosticConsumer(C, llvm::sys::path::parent_path(prefix), PP);
+  createPlistDiagnosticConsumer(C, prefix, PP);
 }
 
+namespace {
+class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
+  DiagnosticsEngine &Diag;
+public:
+  ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag) : Diag(Diag) {}
+  virtual ~ClangDiagPathDiagConsumer() {}
+  virtual StringRef getName() const { return "ClangDiags"; }
+  virtual bool useVerboseDescription() const { return false; }
+  virtual PathGenerationScheme getGenerationScheme() const { return None; }
+
+  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
+                            FilesMade *filesMade) {
+    for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(),
+         E = Diags.end(); I != E; ++I) {
+      const PathDiagnostic *PD = *I;
+      StringRef desc = PD->getDescription();
+      SmallString<512> TmpStr;
+      llvm::raw_svector_ostream Out(TmpStr);
+      for (StringRef::iterator I=desc.begin(), E=desc.end(); I!=E; ++I) {
+        if (*I == '%')
+          Out << "%%";
+        else
+          Out << *I;
+      }
+      Out.flush();
+      unsigned ErrorDiag = Diag.getCustomDiagID(DiagnosticsEngine::Warning,
+                                                TmpStr);
+      SourceLocation L = PD->getLocation().asLocation();
+      DiagnosticBuilder diagBuilder = Diag.Report(L, ErrorDiag);
+
+      // Get the ranges from the last point in the path.
+      ArrayRef<SourceRange> Ranges = PD->path.back()->getRanges();
+
+      for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
+                                           E = Ranges.end(); I != E; ++I) {
+        diagBuilder << *I;
+      }
+    }
+  }
+};
+} // end anonymous namespace
+
 //===----------------------------------------------------------------------===//
 // AnalysisConsumer declaration.
 //===----------------------------------------------------------------------===//
@@ -105,8 +146,8 @@
   /// working with a PCH file.
   SetOfDecls LocalTUDecls;
                            
-  // PD is owned by AnalysisManager.
-  PathDiagnosticConsumer *PD;
+  // Set of PathDiagnosticConsumers.  Owned by AnalysisManager.
+  PathDiagnosticConsumers PathConsumers;
 
   StoreManagerCreator CreateStoreMgr;
   ConstraintManagerCreator CreateConstraintMgr;
@@ -126,7 +167,7 @@
                    const AnalyzerOptions& opts,
                    ArrayRef<std::string> plugins)
     : RecVisitorMode(ANALYSIS_ALL), RecVisitorBR(0),
-      Ctx(0), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins), PD(0) {
+      Ctx(0), PP(pp), OutDir(outdir), Opts(opts), Plugins(plugins) {
     DigestAnalyzerOptions();
     if (Opts.PrintStats) {
       llvm::EnableStatistics();
@@ -141,17 +182,19 @@
 
   void DigestAnalyzerOptions() {
     // Create the PathDiagnosticConsumer.
+    PathConsumers.push_back(new ClangDiagPathDiagConsumer(PP.getDiagnostics()));
+
     if (!OutDir.empty()) {
       switch (Opts.AnalysisDiagOpt) {
       default:
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) \
-        case PD_##NAME: PD = CREATEFN(OutDir, PP); break;
+        case PD_##NAME: CREATEFN(PathConsumers, OutDir, PP); break;
 #include "clang/Frontend/Analyses.def"
       }
     } else if (Opts.AnalysisDiagOpt == PD_TEXT) {
       // Create the text client even without a specified output file since
       // it just uses diagnostic notes.
-      PD = createTextPathDiagnosticConsumer("", PP);
+      createTextPathDiagnosticConsumer(PathConsumers, "", PP);
     }
 
     // Create the analyzer component creators.
@@ -205,16 +248,18 @@
     Ctx = &Context;
     checkerMgr.reset(createCheckerManager(Opts, PP.getLangOpts(), Plugins,
                                           PP.getDiagnostics()));
-    Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
-                                  PP.getLangOpts(), PD,
-                                  CreateStoreMgr, CreateConstraintMgr,
+    Mgr.reset(new AnalysisManager(*Ctx,
+                                  PP.getDiagnostics(),
+                                  PP.getLangOpts(),
+                                  PathConsumers,
+                                  CreateStoreMgr,
+                                  CreateConstraintMgr,
                                   checkerMgr.get(),
                                   Opts.MaxNodes, Opts.MaxLoop,
                                   Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
                                   Opts.AnalysisPurgeOpt, Opts.EagerlyAssume,
                                   Opts.TrimGraph,
                                   Opts.UnoptimizedCFG, Opts.CFGAddImplicitDtors,
-                                  Opts.CFGAddInitializers,
                                   Opts.EagerlyTrimEGraph,
                                   Opts.IPAMode,
                                   Opts.InlineMaxStackDepth,
diff --git a/lib/StaticAnalyzer/Frontend/CMakeLists.txt b/lib/StaticAnalyzer/Frontend/CMakeLists.txt
index c45326f..06d1485 100644
--- a/lib/StaticAnalyzer/Frontend/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Frontend/CMakeLists.txt
@@ -15,6 +15,8 @@
   ClangAttrList
   ClangCommentNodes
   ClangDeclNodes
+  ClangDiagnosticCommon
+  ClangDiagnosticFrontend
   ClangStmtNodes
   )
 
diff --git a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
index c06da0d..0229aed 100644
--- a/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
+++ b/lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp
@@ -118,7 +118,7 @@
 
   for (unsigned i = 0, e = checkerOpts.size(); i != e; ++i) {
     if (checkerOpts[i].isUnclaimed())
-      diags.Report(diag::warn_unknown_analyzer_checker)
+      diags.Report(diag::err_unknown_analyzer_checker)
           << checkerOpts[i].getName();
   }
 
diff --git a/lib/Tooling/CMakeLists.txt b/lib/Tooling/CMakeLists.txt
index bec266c..49d3101 100644
--- a/lib/Tooling/CMakeLists.txt
+++ b/lib/Tooling/CMakeLists.txt
@@ -1,17 +1,22 @@
 set(LLVM_LINK_COMPONENTS support)
 
 add_clang_library(clangTooling
+  ArgumentsAdjusters.cpp
   CommandLineClangTool.cpp
   CompilationDatabase.cpp
   Refactoring.cpp
-  Tooling.cpp
-  ArgumentsAdjusters.cpp
   RefactoringCallbacks.cpp
+  Tooling.cpp
   )
 
 add_dependencies(clangTooling
+  ClangAttrClasses
+  ClangAttrList
+  ClangDeclNodes
   ClangDiagnosticCommon
-)
+  ClangDiagnosticFrontend
+  ClangStmtNodes
+  )
 
 target_link_libraries(clangTooling
   clangBasic
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index 5d41172..e93e0c9 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -212,6 +212,7 @@
   const bool Success = Compiler.ExecuteAction(*ScopedToolAction);
 
   Compiler.resetAndLeakFileManager();
+  Files->clearStatCaches();
   return Success;
 }
 
diff --git a/test/ARCMT/releases-driver.m b/test/ARCMT/releases-driver.m
index b75432a..7b1d2fb 100644
--- a/test/ARCMT/releases-driver.m
+++ b/test/ARCMT/releases-driver.m
@@ -53,9 +53,8 @@
 @end
 
 @implementation Baz
-- dealloc {
+- (void) dealloc {
   [_foo release];
-  return 0;
 }
 @end
 
diff --git a/test/ARCMT/releases-driver.m.result b/test/ARCMT/releases-driver.m.result
index 70c0aec..4c864bd 100644
--- a/test/ARCMT/releases-driver.m.result
+++ b/test/ARCMT/releases-driver.m.result
@@ -49,9 +49,6 @@
 @end
 
 @implementation Baz
-- dealloc {
-  return 0;
-}
 @end
 
 #define RELEASE_MACRO(x) [x release]
diff --git a/test/ARCMT/releases.m b/test/ARCMT/releases.m
index 867fab9..5500895 100644
--- a/test/ARCMT/releases.m
+++ b/test/ARCMT/releases.m
@@ -58,9 +58,8 @@
 @end
 
 @implementation Baz
-- dealloc {
+- (void) dealloc {
   [_foo release];
-  return 0;
 }
 @end
 
diff --git a/test/ARCMT/releases.m.result b/test/ARCMT/releases.m.result
index 556610a..473750e 100644
--- a/test/ARCMT/releases.m.result
+++ b/test/ARCMT/releases.m.result
@@ -54,9 +54,6 @@
 @end
 
 @implementation Baz
-- dealloc {
-  return 0;
-}
 @end
 
 void block_test(Foo *p) {
diff --git a/test/ARCMT/verify.m b/test/ARCMT/verify.m
new file mode 100644
index 0000000..9110fe6
--- /dev/null
+++ b/test/ARCMT/verify.m
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -arcmt-check -verify %s
+// RUN: %clang_cc1 -arcmt-check -verify %t.invalid 2>&1 | FileCheck %s
+
+#if 0
+// expected-error {{should be ignored}}
+#endif
+
+#error should not be ignored
+// expected-error@-1 {{should not be ignored}}
+
+//      CHECK: error: 'error' diagnostics seen but not expected:
+// CHECK-NEXT:   (frontend): error reading '{{.*}}verify.m.tmp.invalid'
+// CHECK-NEXT: 1 error generated.
diff --git a/test/ASTMerge/function.c b/test/ASTMerge/function.c
index f97ecee..320bca2 100644
--- a/test/ASTMerge/function.c
+++ b/test/ASTMerge/function.c
@@ -1,9 +1,15 @@
 // RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/function1.c
 // RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/function2.c
 // RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -ast-merge %t.1.ast -ast-merge %t.2.ast -fsyntax-only -verify %s
 
 // CHECK: function2.c:3:6: error: external function 'f1' declared with incompatible types in different translation units ('void (Int, double)' vs. 'void (int, float)')
 // CHECK: function1.c:2:6: note: declared here with type 'void (int, float)'
 // CHECK: function2.c:5:6: error: external function 'f3' declared with incompatible types in different translation units ('void (int)' vs. 'void (void)')
 // CHECK: function1.c:4:6: note: declared here with type 'void (void)'
 // CHECK: 2 errors generated
+
+// expected-error@3 {{external function 'f1' declared with incompatible types}}
+// expected-note@2 {{declared here}}
+// expected-error@5 {{external function 'f3' declared with incompatible types}}
+// expected-note@4 {{declared here}}
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c
index fbbe4d1..537e497 100644
--- a/test/Analysis/CFNumber.c
+++ b/test/Analysis/CFNumber.c
@@ -17,11 +17,11 @@
 extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
 
 CFNumberRef f1(unsigned char x) {
-  return CFNumberCreate(0, kCFNumberSInt16Type, &x);  // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage.}}
+  return CFNumberCreate(0, kCFNumberSInt16Type, &x);  // expected-warning{{An 8 bit integer is used to initialize a CFNumber object that represents a 16 bit integer. 8 bits of the CFNumber value will be garbage}}
 }
 
 __attribute__((cf_returns_retained)) CFNumberRef f2(unsigned short x) {
-  return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost.}}
+  return CFNumberCreate(0, kCFNumberSInt8Type, &x); // expected-warning{{A 16 bit integer is used to initialize a CFNumber object that represents an 8 bit integer. 8 bits of the input integer will be lost}}
 }
 
 // test that the attribute overrides the naming convention.
@@ -30,5 +30,5 @@
 }
 
 CFNumberRef f3(unsigned i) {
-  return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer.}}
+  return CFNumberCreate(0, kCFNumberLongType, &i); // expected-warning{{A 32 bit integer is used to initialize a CFNumber object that represents a 64 bit integer}}
 }
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
index d35b686..cdec1d5 100644
--- a/test/Analysis/CheckNSError.m
+++ b/test/Analysis/CheckNSError.m
@@ -23,7 +23,7 @@
 
 @implementation A
 - (void)myMethodWhichMayFail:(NSError **)error {   // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred}}
-  *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference.}}
+  *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference}}
 }
 
 - (BOOL)myMethodWhichMayFail2:(NSError **)error {  // no-warning
@@ -36,7 +36,7 @@
 typedef struct __CFError* CFErrorRef;
 
 void foo(CFErrorRef* error) { // expected-warning {{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred}}
-  *error = 0;  // expected-warning {{Potential null dereference.}}
+  *error = 0;  // expected-warning {{Potential null dereference}}
 }
 
 int f1(CFErrorRef* error) {
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
index c452709..257a45e 100644
--- a/test/Analysis/array-struct-region.c
+++ b/test/Analysis/array-struct-region.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=basic -analyzer-ipa=inlining -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -analyzer-ipa=inlining -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-constraints=basic -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-constraints=range -verify %s
 
 void clang_analyzer_eval(int);
 
@@ -92,3 +92,95 @@
   return c.r; // no-warning
 }
 
+
+int randomInt();
+
+int testSymbolicInvalidation(int index) {
+  int vals[10];
+
+  vals[0] = 42;
+  clang_analyzer_eval(vals[0] == 42); // expected-warning{{TRUE}}
+
+  vals[index] = randomInt();
+  clang_analyzer_eval(vals[0] == 42); // expected-warning{{UNKNOWN}}
+
+  return vals[index]; // no-warning
+}
+
+int testConcreteInvalidation(int index) {
+  int vals[10];
+
+  vals[index] = 42;
+  clang_analyzer_eval(vals[index] == 42); // expected-warning{{TRUE}}
+  vals[0] = randomInt();
+  clang_analyzer_eval(vals[index] == 42); // expected-warning{{UNKNOWN}}
+
+  return vals[0]; // no-warning
+}
+
+
+typedef struct {
+  int x, y, z;
+} S;
+
+S makeS();
+
+int testSymbolicInvalidationStruct(int index) {
+  S vals[10];
+
+  vals[0].x = 42;
+  clang_analyzer_eval(vals[0].x == 42); // expected-warning{{TRUE}}
+
+  vals[index] = makeS();
+  clang_analyzer_eval(vals[0].x == 42); // expected-warning{{UNKNOWN}}
+
+  return vals[index].x; // no-warning
+}
+
+int testConcreteInvalidationStruct(int index) {
+  S vals[10];
+
+  vals[index].x = 42;
+  clang_analyzer_eval(vals[index].x == 42); // expected-warning{{TRUE}}
+  vals[0] = makeS();
+  clang_analyzer_eval(vals[index].x == 42); // expected-warning{{UNKNOWN}}
+
+  return vals[0].x; // no-warning
+}
+
+typedef struct {
+  S a[5];
+  S b[5];
+} SS;
+
+int testSymbolicInvalidationDoubleStruct(int index) {
+  SS vals;
+
+  vals.a[0].x = 42;
+  vals.b[0].x = 42;
+  clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{TRUE}}
+  clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}}
+
+  vals.a[index] = makeS();
+  clang_analyzer_eval(vals.a[0].x == 42); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(vals.b[0].x == 42); // expected-warning{{TRUE}}
+
+  return vals.b[index].x; // no-warning
+}
+
+int testConcreteInvalidationDoubleStruct(int index) {
+  SS vals;
+
+  vals.a[index].x = 42;
+  vals.b[index].x = 42;
+  clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{TRUE}}
+  clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}}
+
+  vals.a[0] = makeS();
+  clang_analyzer_eval(vals.a[index].x == 42); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(vals.b[index].x == 42); // expected-warning{{TRUE}}
+
+  return vals.b[0].x; // no-warning
+}
+
+
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
index c5bdb86..1b36190 100644
--- a/test/Analysis/array-struct.c
+++ b/test/Analysis/array-struct.c
@@ -151,7 +151,7 @@
 // an ElementRegion of type 'char'. Then load a nonloc::SymbolVal from it and
 // assigns to 'a'. 
 void f16(struct s3 *p) {
-  struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+  struct s3 a = *((struct s3*) ((char*) &p[0])); // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
 }
 
 void inv(struct s1 *);
diff --git a/test/Analysis/base-init.cpp b/test/Analysis/base-init.cpp
index ae99d53..e63d508 100644
--- a/test/Analysis/base-init.cpp
+++ b/test/Analysis/base-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -verify %s
 // XFAIL: *
 
 void clang_analyzer_eval(bool);
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
index ff376d1..54ff58c 100644
--- a/test/Analysis/blocks.m
+++ b/test/Analysis/blocks.m
@@ -26,10 +26,12 @@
 @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
 @interface NSObject <NSObject> {}
 + (id)alloc;
+- (id)copy;
 @end
 extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
-@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>    - (NSUInteger)length;
-- ( const char *)UTF8String;
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
+- (NSUInteger)length;
+- (const char *)UTF8String;
 - (id)initWithFormat:(NSString *)format arguments:(va_list)argList __attribute__((format(__NSString__, 1, 0)));
 @end
 @class NSString, NSData;
@@ -85,4 +87,10 @@
 void test2_c() {
   typedef void (^myblock)(void);
   myblock f = ^() { f(); }; // expected-warning{{Variable 'f' is uninitialized when captured by block}}
-}
\ No newline at end of file
+}
+
+
+void testMessaging() {
+  // <rdar://problem/12119814>
+  [[^(){} copy] release];
+}
diff --git a/test/Analysis/cstring-syntax.c b/test/Analysis/cstring-syntax.c
index 64ecb67..4aa88ed 100644
--- a/test/Analysis/cstring-syntax.c
+++ b/test/Analysis/cstring-syntax.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strncat-size -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s
 
 typedef __SIZE_TYPE__ size_t;
 char  *strncat(char *, const char *, size_t);
diff --git a/test/Analysis/ctor-inlining.mm b/test/Analysis/ctor-inlining.mm
new file mode 100644
index 0000000..da44a79
--- /dev/null
+++ b/test/Analysis/ctor-inlining.mm
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+
+void clang_analyzer_eval(bool);
+
+struct Wrapper {
+  __strong id obj;
+};
+
+void test() {
+  Wrapper w;
+  // force a diagnostic
+  *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+
+struct IntWrapper {
+  int x;
+};
+
+void testCopyConstructor() {
+  IntWrapper a;
+  a.x = 42;
+
+  IntWrapper b(a);
+  clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
+}
+
+struct NonPODIntWrapper {
+  int x;
+
+  virtual int get();
+};
+
+void testNonPODCopyConstructor() {
+  NonPODIntWrapper a;
+  a.x = 42;
+
+  NonPODIntWrapper b(a);
+  clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
+}
+
+
+namespace ConstructorVirtualCalls {
+  class A {
+  public:
+    int *out1, *out2, *out3;
+
+    virtual int get() { return 1; }
+
+    A(int *out1) {
+      *out1 = get();
+    }
+  };
+
+  class B : public A {
+  public:
+    virtual int get() { return 2; }
+
+    B(int *out1, int *out2) : A(out1) {
+      *out2 = get();
+    }
+  };
+
+  class C : public B {
+  public:
+    virtual int get() { return 3; }
+
+    C(int *out1, int *out2, int *out3) : B(out1, out2) {
+      *out3 = get();
+    }
+  };
+
+  void test() {
+    int a, b, c;
+
+    C obj(&a, &b, &c);
+    clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
+    clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+
+    clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
+
+    // Sanity check for devirtualization.
+    A *base = &obj;
+    clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
+  }
+}
+
+
diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m
index 970f81a..7fc4f2b 100644
--- a/test/Analysis/delegates.m
+++ b/test/Analysis/delegates.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -Wno-objc-root-class -verify %s
 
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp
index f65b9db..30e7a31 100644
--- a/test/Analysis/derived-to-base.cpp
+++ b/test/Analysis/derived-to-base.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
+
+void clang_analyzer_eval(bool);
 
 class A {
 protected:
@@ -13,3 +15,123 @@
 void B::f() {
   x = 3;
 }
+
+
+class C : public B {
+public:
+  void g() {
+    // This used to crash because we are upcasting through two bases.
+    x = 5;
+  }
+};
+
+
+namespace VirtualBaseClasses {
+  class A {
+  protected:
+    int x;
+  };
+
+  class B : public virtual A {
+  public:
+    int getX() { return x; }
+  };
+
+  class C : public virtual A {
+  public:
+    void setX() { x = 42; }
+  };
+
+  class D : public B, public C {};
+  class DV : virtual public B, public C {};
+  class DV2 : public B, virtual public C {};
+
+  void test() {
+    D d;
+    d.setX();
+    clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
+
+    DV dv;
+    dv.setX();
+    clang_analyzer_eval(dv.getX() == 42); // expected-warning{{TRUE}}
+
+    DV2 dv2;
+    dv2.setX();
+    clang_analyzer_eval(dv2.getX() == 42); // expected-warning{{TRUE}}
+  }
+
+
+  // Make sure we're consistent about the offset of the A subobject within an
+  // Intermediate virtual base class.
+  class Padding1 { int unused; };
+  class Padding2 { int unused; };
+  class Intermediate : public Padding1, public A, public Padding2 {};
+
+  class BI : public virtual Intermediate {
+  public:
+    int getX() { return x; }
+  };
+
+  class CI : public virtual Intermediate {
+  public:
+    void setX() { x = 42; }
+  };
+
+  class DI : public BI, public CI {};
+
+  void testIntermediate() {
+    DI d;
+    d.setX();
+    clang_analyzer_eval(d.getX() == 42); // expected-warning{{TRUE}}
+  }
+}
+
+
+namespace DynamicVirtualUpcast {
+  class A {
+  public:
+    virtual ~A();
+  };
+
+  class B : virtual public A {};
+  class C : virtual public B {};
+  class D : virtual public C {};
+
+  bool testCast(A *a) {
+    return dynamic_cast<B*>(a) && dynamic_cast<C*>(a);
+  }
+
+  void test() {
+    D d;
+    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
+  }
+}
+
+namespace DynamicMultipleInheritanceUpcast {
+  class B {
+  public:
+    virtual ~B();
+  };
+  class C {
+  public:
+    virtual ~C();
+  };
+  class D : public B, public C {};
+
+  bool testCast(B *a) {
+    return dynamic_cast<C*>(a);
+  }
+
+  void test() {
+    D d;
+    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
+  }
+
+
+  class DV : virtual public B, virtual public C {};
+
+  void testVirtual() {
+    DV d;
+    clang_analyzer_eval(testCast(&d)); // expected-warning{{TRUE}}
+  }
+}
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index 8d63cc4..1f45925 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
+
+void clang_analyzer_eval(bool);
 
 class A {
 public:
@@ -11,3 +13,217 @@
 int main() {
   A a;
 }
+
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+class SmartPointer {
+  void *X;
+public:
+  SmartPointer(void *x) : X(x) {}
+  ~SmartPointer() {
+    free(X);
+  }
+};
+
+void testSmartPointer() {
+  char *mem = (char*)malloc(4);
+  {
+    SmartPointer Deleter(mem);
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}
+
+
+void doSomething();
+void testSmartPointer2() {
+  char *mem = (char*)malloc(4);
+  {
+    SmartPointer Deleter(mem);
+    // Remove dead bindings...
+    doSomething();
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}
+
+
+class Subclass : public SmartPointer {
+public:
+  Subclass(void *x) : SmartPointer(x) {}
+};
+
+void testSubclassSmartPointer() {
+  char *mem = (char*)malloc(4);
+  {
+    Subclass Deleter(mem);
+    // Remove dead bindings...
+    doSomething();
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}
+
+
+class MultipleInheritance : public Subclass, public SmartPointer {
+public:
+  MultipleInheritance(void *a, void *b) : Subclass(a), SmartPointer(b) {}
+};
+
+void testMultipleInheritance1() {
+  char *mem = (char*)malloc(4);
+  {
+    MultipleInheritance Deleter(mem, 0);
+    // Remove dead bindings...
+    doSomething();
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testMultipleInheritance2() {
+  char *mem = (char*)malloc(4);
+  {
+    MultipleInheritance Deleter(0, mem);
+    // Remove dead bindings...
+    doSomething();
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}
+
+void testMultipleInheritance3() {
+  char *mem = (char*)malloc(4);
+  {
+    MultipleInheritance Deleter(mem, mem);
+    // Remove dead bindings...
+    doSomething();
+    // destructor called here
+    // expected-warning@27 {{Attempt to free released memory}}
+  }
+}
+
+
+class SmartPointerMember {
+  SmartPointer P;
+public:
+  SmartPointerMember(void *x) : P(x) {}
+};
+
+void testSmartPointerMember() {
+  char *mem = (char*)malloc(4);
+  {
+    SmartPointerMember Deleter(mem);
+    // Remove dead bindings...
+    doSomething();
+    // destructor called here
+  }
+  *mem = 0; // expected-warning{{Use of memory after it is freed}}
+}
+
+
+struct IntWrapper {
+  IntWrapper() : x(0) {}
+  ~IntWrapper();
+  int *x;
+};
+
+void testArrayInvalidation() {
+  int i = 42;
+  int j = 42;
+
+  {
+    IntWrapper arr[2];
+
+    // There should be no undefined value warnings here.
+    // Eventually these should be TRUE as well, but right now
+    // we can't handle array constructors.
+    clang_analyzer_eval(arr[0].x == 0); // expected-warning{{UNKNOWN}}
+    clang_analyzer_eval(arr[1].x == 0); // expected-warning{{UNKNOWN}}
+
+    arr[0].x = &i;
+    arr[1].x = &j;
+    clang_analyzer_eval(*arr[0].x == 42); // expected-warning{{TRUE}}
+    clang_analyzer_eval(*arr[1].x == 42); // expected-warning{{TRUE}}
+  }
+
+  // The destructors should have invalidated i and j.
+  clang_analyzer_eval(i == 42); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(j == 42); // expected-warning{{UNKNOWN}}
+}
+
+
+
+// Don't crash on a default argument inside an initializer.
+struct DefaultArg {
+  DefaultArg(int x = 0) {}
+  ~DefaultArg();
+};
+
+struct InheritsDefaultArg : DefaultArg {
+  InheritsDefaultArg() {}
+  virtual ~InheritsDefaultArg();
+};
+
+void testDefaultArg() {
+  InheritsDefaultArg a;
+  // Force a bug to be emitted.
+  *(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
+}
+
+
+namespace DestructorVirtualCalls {
+  class A {
+  public:
+    int *out1, *out2, *out3;
+
+    virtual int get() { return 1; }
+
+    ~A() {
+      *out1 = get();
+    }
+  };
+
+  class B : public A {
+  public:
+    virtual int get() { return 2; }
+
+    ~B() {
+      *out2 = get();
+    }
+  };
+
+  class C : public B {
+  public:
+    virtual int get() { return 3; }
+
+    ~C() {
+      *out3 = get();
+    }
+  };
+
+  void test() {
+    int a, b, c;
+
+    // New scope for the C object.
+    {
+      C obj;
+      clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
+
+      // Sanity check for devirtualization.
+      A *base = &obj;
+      clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
+
+      obj.out1 = &a;
+      obj.out2 = &b;
+      obj.out3 = &c;
+    }
+
+    clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
+    clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
+    clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+  }
+}
diff --git a/test/Analysis/dynamic-cast.cpp b/test/Analysis/dynamic-cast.cpp
index 215bc49..b1133ac 100644
--- a/test/Analysis/dynamic-cast.cpp
+++ b/test/Analysis/dynamic-cast.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core -analyzer-ipa=none -verify %s
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=none -verify %s
+
+void clang_analyzer_eval(bool);
 
 class A {
 public:
@@ -208,7 +210,25 @@
   testDynCastMostLikelyWillFail(&m);
 }
 
+
+void testDynCastToMiddleClass () {
+  class BBB : public BB {};
+  BBB obj;
+  A &ref = obj;
+
+  // These didn't always correctly layer base regions.
+  B *ptr = dynamic_cast<B*>(&ref);
+  clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}}
+
+  // This is actually statically resolved to be a DerivedToBase cast.
+  ptr = dynamic_cast<B*>(&obj);
+  clang_analyzer_eval(ptr != 0); // expected-warning{{TRUE}}
+}
+
+
+// -----------------------------
 // False positives/negatives.
+// -----------------------------
 
 // Due to symbolic regions not being typed.
 int testDynCastFalsePositive(BB *c) {
diff --git a/test/Analysis/exceptions.mm b/test/Analysis/exceptions.mm
new file mode 100644
index 0000000..dab1b5e
--- /dev/null
+++ b/test/Analysis/exceptions.mm
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -analyze -fexceptions -fobjc-exceptions -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+
+void clang_analyzer_checkInlined(bool);
+
+typedef typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+void free(void *);
+
+
+id getException();
+void inlinedObjC() {
+  clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+  @throw getException();
+}
+
+int testObjC() {
+  int a; // uninitialized
+  void *mem = malloc(4); // no-warning (ObjC exceptions are usually fatal)
+  inlinedObjC();
+  free(mem);
+  return a; // no-warning
+}
+
+
+void inlinedCXX() {
+  clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+  throw -1;
+}
+
+int testCXX() {
+  int a; // uninitialized
+  // FIXME: this should be reported as a leak, because C++ exceptions are
+  // often not fatal.
+  void *mem = malloc(4);
+  inlinedCXX();
+  free(mem);
+  return a; // no-warning
+}
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
index b6cebde..709ebf7 100644
--- a/test/Analysis/func.c
+++ b/test/Analysis/func.c
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -verify %s
+
+void clang_analyzer_eval(int);
 
 void f(void) {
   void (*p)(void);
@@ -13,3 +15,13 @@
 void f2() {
   g(f);
 }
+
+void f3(void (*f)(void), void (*g)(void)) {
+  clang_analyzer_eval(!f); // expected-warning{{UNKNOWN}}
+  f();
+  clang_analyzer_eval(!f); // expected-warning{{FALSE}}
+
+  clang_analyzer_eval(!g); // expected-warning{{UNKNOWN}}
+  (*g)();
+  clang_analyzer_eval(!g); // expected-warning{{FALSE}}
+}
diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c
index 59d81a5..7c15df6 100644
--- a/test/Analysis/html-diags.c
+++ b/test/Analysis/html-diags.c
@@ -1,6 +1,6 @@
-// RUN: mkdir %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %T.dir %s
-// RUN: rm -fR %t.dir
+// RUN: mkdir %T/dir
+// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %T/dir %s
+// RUN: rm -fR %T/dir
 
 // Currently this test mainly checks that the HTML diagnostics doesn't crash
 // when handling macros will calls with macros.  We should actually validate
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index 6640e1f..4f800d5 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -cfg-add-implicit-dtors -std=c++11 -verify %s
+
+// We don't inline constructors unless we have destructors turned on.
 
 void clang_analyzer_eval(bool);
 
@@ -11,3 +13,66 @@
 A::A() : x(0) {
   clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
 }
+
+
+class DirectMember {
+  int x;
+public:
+  DirectMember(int value) : x(value) {}
+
+  int getX() { return x; }
+};
+
+void testDirectMember() {
+  DirectMember obj(3);
+  clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
+}
+
+
+class IndirectMember {
+  struct {
+    int x;
+  };
+public:
+  IndirectMember(int value) : x(value) {}
+
+  int getX() { return x; }
+};
+
+void testIndirectMember() {
+  IndirectMember obj(3);
+  clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
+}
+
+
+struct DelegatingConstructor {
+  int x;
+  DelegatingConstructor(int y) { x = y; }
+  DelegatingConstructor() : DelegatingConstructor(42) {}
+};
+
+void testDelegatingConstructor() {
+  DelegatingConstructor obj;
+  clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
+}
+
+
+// ------------------------------------
+// False negatives
+// ------------------------------------
+
+struct RefWrapper {
+  RefWrapper(int *p) : x(*p) {}
+  RefWrapper(int &r) : x(r) {}
+  int &x;
+};
+
+void testReferenceMember() {
+  int *p = 0;
+  RefWrapper X(p); // should warn in the constructor
+}
+
+void testReferenceMember2() {
+  int *p = 0;
+  RefWrapper X(*p); // should warn here
+}
diff --git a/test/Analysis/initializers-cfg-output.cpp b/test/Analysis/initializers-cfg-output.cpp
index 8a7a3f5..8aaa94c 100644
--- a/test/Analysis/initializers-cfg-output.cpp
+++ b/test/Analysis/initializers-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-initializers %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 // XPASS: *
 
 class A {
diff --git a/test/Analysis/inline-not-supported.c b/test/Analysis/inline-not-supported.c
index bff0e4d..756d5d8 100644
--- a/test/Analysis/inline-not-supported.c
+++ b/test/Analysis/inline-not-supported.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-store region -verify %s
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core -verify %s
 
 // For now, don't inline varargs.
 void foo(int *x, ...) {
@@ -16,7 +16,7 @@
   baz(0, 2); // no-warning
 }
 
-// For now, don't inline blocks.
+// For now, don't inline global blocks.
 void (^qux)(int *p) = ^(int *p) { *p = 1; };
 void test_qux() {
   qux(0); // no-warning
diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c
index 1523e82..4cc33ff 100644
--- a/test/Analysis/inline-plist.c
+++ b/test/Analysis/inline-plist.c
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -Xclang -analyzer-ipa=inlining -fblocks -o %t
+// RUN: %clang --analyze %s -fblocks -o %t
 // RUN: FileCheck -input-file %t %s
 
 // <rdar://problem/10967815>
diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c
index 6ae77e2..356ab72 100644
--- a/test/Analysis/inline-unique-reports.c
+++ b/test/Analysis/inline-unique-reports.c
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -Xclang -analyzer-ipa=inlining -o %t > /dev/null 2>&1
+// RUN: %clang --analyze %s -o %t > /dev/null 2>&1
 // RUN: FileCheck -input-file %t %s
 
 static inline bug(int *p) {
@@ -34,12 +34,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>14</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>9</integer>
+// CHECK:            <key>line</key><integer>14</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -47,12 +47,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>15</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>15</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -64,7 +64,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>10</integer>
+// CHECK:       <key>line</key><integer>15</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -72,12 +72,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>line</key><integer>15</integer>
 // CHECK:          <key>col</key><integer>3</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>line</key><integer>15</integer>
 // CHECK:          <key>col</key><integer>8</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -99,9 +99,9 @@
 // CHECK:      </dict>
 // CHECK:      <key>depth</key><integer>1</integer>
 // CHECK:      <key>extended_message</key>
-// CHECK:      <string>Entered call from &apos;test_bug_1&apos;</string>
+// CHECK:      <string>Entered call from &apos;test_bug_2&apos;</string>
 // CHECK:      <key>message</key>
-// CHECK: <string>Entered call from &apos;test_bug_1&apos;</string>
+// CHECK: <string>Entered call from &apos;test_bug_2&apos;</string>
 // CHECK:     </dict>
 // CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
@@ -172,6 +172,7 @@
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>issue_context_kind</key><string>function</string>
 // CHECK:   <key>issue_context</key><string>bug</string>
+// CHECK:   <key>issue_hash</key><integer>1</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
 // CHECK:    <key>line</key><integer>5</integer>
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
index 73d629a..8cba63f 100644
--- a/test/Analysis/inline.c
+++ b/test/Analysis/inline.c
@@ -1,10 +1,12 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
+void clang_analyzer_checkInlined(int);
 
 int test1_f1() {
   int y = 1;
   y++;
+  clang_analyzer_checkInlined(1); // expected-warning{{TRUE}}
   return y;
 }
 
@@ -103,3 +105,8 @@
   return x + 1;
 }
 
+
+void never_called_by_anyone() {
+  clang_analyzer_checkInlined(0); // no-warning
+}
+
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index d16eeaf..6b9a885 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
 
 void clang_analyzer_eval(bool);
+void clang_analyzer_checkInlined(bool);
 
 class A {
 public:
@@ -43,3 +44,152 @@
   clang_analyzer_eval(ptr->getNum() == x); // expected-warning {{TRUE}}
 }
 
+
+namespace PureVirtualParent {
+  class Parent {
+  public:
+    virtual int pureVirtual() const = 0;
+    int callVirtual() const {
+      return pureVirtual();
+    }
+  };
+
+  class Child : public Parent {
+  public:
+    virtual int pureVirtual() const {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+      return 42;
+    }
+  };
+
+  void testVirtual() {
+    Child x;
+
+    clang_analyzer_eval(x.pureVirtual() == 42); // expected-warning{{TRUE}}
+    clang_analyzer_eval(x.callVirtual() == 42); // expected-warning{{TRUE}}
+  }
+}
+
+
+namespace PR13569 {
+  class Parent {
+  protected:
+    int m_parent;
+    virtual int impl() const = 0;
+
+    Parent() : m_parent(0) {}
+
+  public:
+    int interface() const {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+      return impl();
+    }
+  };
+
+  class Child : public Parent {
+  protected:
+    virtual int impl() const {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+      return m_parent + m_child;
+    }
+
+  public:
+    Child() : m_child(0) {}
+
+    int m_child;
+  };
+
+  void testVirtual() {
+    Child x;
+    x.m_child = 42;
+
+    // Don't crash when inlining and devirtualizing.
+    x.interface();
+  }
+
+
+  class Grandchild : public Child {};
+
+  void testDevirtualizeToMiddle() {
+    Grandchild x;
+    x.m_child = 42;
+
+    // Don't crash when inlining and devirtualizing.
+    x.interface();
+  }
+}
+
+namespace PR13569_virtual {
+  class Parent {
+  protected:
+    int m_parent;
+    virtual int impl() const = 0;
+
+    Parent() : m_parent(0) {}
+
+  public:
+    int interface() const {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+      return impl();
+    }
+  };
+
+  class Child : virtual public Parent {
+  protected:
+    virtual int impl() const {
+      clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
+      return m_parent + m_child;
+    }
+
+  public:
+    Child() : m_child(0) {}
+
+    int m_child;
+  };
+
+  void testVirtual() {
+    Child x;
+    x.m_child = 42;
+
+    // Don't crash when inlining and devirtualizing.
+    x.interface();
+  }
+
+
+  class Grandchild : virtual public Child {};
+
+  void testDevirtualizeToMiddle() {
+    Grandchild x;
+    x.m_child = 42;
+
+    // Don't crash when inlining and devirtualizing.
+    x.interface();
+  }
+}
+
+namespace Invalidation {
+  struct X {
+    void touch(int &x) const {
+      x = 0;
+    }
+
+    void touch2(int &x) const;
+
+    virtual void touchV(int &x) const {
+      x = 0;
+    }
+
+    virtual void touchV2(int &x) const;
+
+    int test() const {
+      // We were accidentally not invalidating under -analyzer-ipa=inlining
+      // at one point for virtual methods with visible definitions.
+      int a, b, c, d;
+      touch(a);
+      touch2(b);
+      touchV(c);
+      touchV2(d);
+      return a + b + c + d; // no-warning
+    }
+  };
+}
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
index 473146c..2a39c66 100644
--- a/test/Analysis/inline2.c
+++ b/test/Analysis/inline2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -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 968d82a..05f56fb 100644
--- a/test/Analysis/inline3.c
+++ b/test/Analysis/inline3.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
 
 // Test when entering f1(), we set the right AnalysisDeclContext 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 e7715e0..1dcebbe 100644
--- a/test/Analysis/inline4.c
+++ b/test/Analysis/inline4.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-store region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
 
 int g(int a) {    
   return a;
diff --git a/test/Analysis/inlining/DynDispatchBifurcate.m b/test/Analysis/inlining/DynDispatchBifurcate.m
new file mode 100644
index 0000000..6637dfd
--- /dev/null
+++ b/test/Analysis/inlining/DynDispatchBifurcate.m
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s
+
+#include "InlineObjCInstanceMethod.h"
+
+@interface MyParent : NSObject
+- (int)getZero;
+@end
+@implementation MyParent
+- (int)getZero {
+    return 0;
+}
+@end
+
+@interface PublicClass () {
+   int value2;
+}
+@property (readwrite) int value1;
+- (void)setValue2:(int)newValue2;
+@end
+
+@implementation PublicClass
+
+- (int)getZeroPublic {
+    return 0;
+}
+
+@synthesize value1;
+
+- (int)value2 {
+    return value2;
+} 
+- (void)setValue2:(int)newValue {
+    value2 = newValue;
+}
+
+- (int)value3 {
+    return value3;
+} 
+- (void)setValue3:(int)newValue {
+    value3 = newValue;
+}
+
+@end
+
+@interface MyClassWithPublicParent : PublicClass
+- (int)getZeroPublic;
+@end
+@implementation MyClassWithPublicParent
+- (int)getZeroPublic {
+    return 0;
+}
+@end
+
+// Category overrides a public method.
+@interface PublicSubClass (PrvateCat)
+  - (int) getZeroPublic;
+@end
+@implementation PublicSubClass (PrvateCat)
+- (int)getZeroPublic {
+    return 0;
+}
+@end
+
+
+@interface MyClass : MyParent {
+  int value;
+}
+- (int)getZero;
+@property int value;
+@end
+
+// Since class is private, we assume that it cannot be subclassed.
+// False negative: this class is "privately subclassed". this is very rare 
+// in practice.
+@implementation MyClass
++ (int) testTypeFromParam:(MyParent*) p {
+  int m = 0;
+  int z = [p getZero];
+  if (z)
+    return 5/m; // false negative
+  return 5/[p getZero];// expected-warning {{Division by zero}}
+}
+
+// Here only one definition is possible, since the declaration is not visible 
+// from outside. 
++ (int) testTypeFromParamPrivateChild:(MyClass*) c {
+  int m = 0;
+  int z = [c getZero]; // MyClass overrides getZero to return '1'.
+  if (z)
+    return 5/m; // expected-warning {{Division by zero}}
+  return 5/[c getZero];//no warning
+}
+
+- (int)getZero {
+    return 1;
+}
+
+- (int)value {
+  return value;
+}
+ 
+- (void)setValue:(int)newValue {
+  value = newValue;
+}
+
+// Test ivar access.
+- (int) testIvarInSelf {
+  value = 0;
+  return 5/value; // expected-warning {{Division by zero}}
+}
+
++ (int) testIvar: (MyClass*) p {
+  p.value = 0;
+  return 5/p.value; // expected-warning {{Division by zero}}
+}
+
+// Test simple property access.
++ (int) testProperty: (MyClass*) p {
+  int x= 0;
+  [p setValue:0];
+  return 5/[p value]; // expected-warning {{Division by zero}}  
+}
+
+@end
+
+// The class is prvate and is not subclassed.
+int testCallToPublicAPIInParent(MyClassWithPublicParent *p) {
+  int m = 0;
+  int z = [p getZeroPublic];
+  if (z)
+    return 5/m; // no warning
+  return 5/[p getZeroPublic];// expected-warning {{Division by zero}}  
+}
+
+// When the called method is public (due to it being defined outside of main file),
+// split the path and analyze both branches.
+// In this case, p can be either the object of type MyParent* or MyClass*:
+// - If it's MyParent*, getZero returns 0.
+// - If it's MyClass*, getZero returns 1 and 'return 5/m' is reachable.
+// Declaration is provate, but p can be a subclass (MyClass*).
+int testCallToPublicAPI(PublicClass *p) {
+  int m = 0;
+  int z = [p getZeroPublic];
+  if (z)
+    return 5/m; // expected-warning {{Division by zero}}
+  return 5/[p getZeroPublic];// expected-warning {{Division by zero}}  
+}
+
+// Even though the method is privately declared in the category, the parent 
+// declares the method as public. Assume the instance can be subclassed.
+int testCallToPublicAPICat(PublicSubClass *p) {
+  int m = 0;
+  int z = [p getZeroPublic];
+  if (z)
+    return 5/m; // expected-warning {{Division by zero}}
+  return 5/[p getZeroPublic];// expected-warning {{Division by zero}}  
+}
+
+// Test public property - properties should always be inlined, regardless 
+// weither they are "public" or private. 
+int testPublicProperty(PublicClass *p) {
+  int x = 0;
+  p.value3 = 0;
+  if (p.value3 != 0)
+    return 5/x; 
+  return 5/p.value3;// expected-warning {{Division by zero}}
+}
+
+int testExtension(PublicClass *p) {
+  int x = 0;
+  [p setValue2:0];
+  if ([p value2] != 0)
+    return 5/x; // expected-warning {{Division by zero}}
+  return 5/[p value2]; // expected-warning {{Division by zero}}
+}
+
+// TODO: we do not handle synthesized properties yet.
+int testPropertySynthesized(PublicClass *p) {
+  [p setValue1:0];
+  return 5/[p value1];  
+}
diff --git a/test/Analysis/inlining/InlineObjCClassMethod.m b/test/Analysis/inlining/InlineObjCClassMethod.m
new file mode 100644
index 0000000..814d437
--- /dev/null
+++ b/test/Analysis/inlining/InlineObjCClassMethod.m
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s
+
+// Test inlining of ObjC class methods.
+
+typedef signed char BOOL;
+typedef struct objc_class *Class;
+typedef struct objc_object {
+    Class isa;
+} *id;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+- (Class)class;
+-(id)retain;
+@end
+
+// Vanila: ObjC class method is called by name.
+@interface MyParent : NSObject
++ (int)getInt;
+@end
+@interface MyClass : MyParent
++ (int)getInt;
+@end
+@implementation MyClass
++ (int)testClassMethodByName {
+    int y = [MyClass getInt];
+    return 5/y; // expected-warning {{Division by zero}}
+}
++ (int)getInt {
+  return 0;
+}
+@end
+
+// The definition is defined by the parent. Make sure we find it and inline.
+@interface MyParentDIP : NSObject
++ (int)getInt;
+@end
+@interface MyClassDIP : MyParentDIP
+@end
+@implementation MyClassDIP
++ (int)testClassMethodByName {
+    int y = [MyClassDIP getInt];
+    return 5/y; // expected-warning {{Division by zero}}
+}
+@end
+@implementation MyParentDIP
++ (int)getInt {
+    return 0;
+}
+@end
+
+// ObjC class method is called by name. Definition is in the category.
+@interface AAA : NSObject
+@end
+@interface AAA (MyCat)
++ (int)getInt;
+@end
+int foo() {
+    int y = [AAA getInt];
+    return 5/y; // expected-warning {{Division by zero}}
+}
+@implementation AAA
+@end
+@implementation AAA (MyCat)
++ (int)getInt {
+    return 0;
+}
+@end
+
+// ObjC class method is called by name. Definition is in the parent category.
+@interface PPP : NSObject
+@end
+@interface PPP (MyCat)
++ (int)getInt;
+@end
+@interface CCC : PPP
+@end
+int foo4() {
+    int y = [CCC getInt];
+    return 5/y; // expected-warning {{Division by zero}}
+}
+@implementation PPP
+@end
+@implementation PPP (MyCat)
++ (int)getInt {
+    return 0;
+}
+@end
+
+// There is no declaration in the class but there is one in the parent. Make 
+// sure we pick the definition from the class and not the parent.
+@interface MyParentTricky : NSObject
++ (int)getInt;
+@end
+@interface MyClassTricky : MyParentTricky
+@end
+@implementation MyParentTricky
++ (int)getInt {
+    return 0;
+}
+@end
+@implementation MyClassTricky
++ (int)getInt {
+  return 1;
+}
++ (int)testClassMethodByName {
+    int y = [MyClassTricky getInt];
+    return 5/y; // no-warning
+}
+@end
+
+// ObjC class method is called by unknown class declaration (passed in as a 
+// parameter). We should not inline in such case.
+@interface MyParentUnknown : NSObject
++ (int)getInt;
+@end
+@interface MyClassUnknown : MyParentUnknown
++ (int)getInt;
+@end
+@implementation MyClassUnknown
++ (int)testClassVariableByUnknownVarDecl: (Class)cl  {
+  int y = [cl getInt];
+  return 3/y; // no-warning
+}
++ (int)getInt {
+  return 0;
+}
+@end
+
+
+// False negative.
+// ObjC class method call through a decl with a known type.
+// We should be able to track the type of currentClass and inline this call.
+// Note, [self class] could be a subclass. Do we still want to inline here?
+@interface MyClassKT : NSObject
+@end
+@interface MyClassKT (MyCatKT)
++ (int)getInt;
+@end
+@implementation MyClassKT (MyCatKT)
++ (int)getInt {
+    return 0;
+}
+@end
+@implementation MyClassKT
+- (int)testClassMethodByKnownVarDecl {
+  Class currentClass = [self class];
+  int y = [currentClass getInt];
+  return 5/y; // Would be great to get a warning here.
+}
+@end
+
+// Another false negative due to us not reasoning about self, which in this 
+// case points to the object of the class in the call site and should be equal 
+// to [MyParent class].
+@interface MyParentSelf : NSObject
++ (int)testSelf;
+@end
+@implementation MyParentSelf
++ (int)testSelf {
+  if (self == [MyParentSelf class])
+      return 0;
+    else
+      return 1;
+}
+@end
+@interface MyClassSelf : MyParentSelf
+@end
+@implementation MyClassSelf
++ (int)testClassMethodByKnownVarDecl {
+  int y = [MyParentSelf testSelf];
+  return 5/y; // Should warn here.
+}
+@end
+int foo2() {
+  int y = [MyParentSelf testSelf];
+  return 5/y; // Should warn here.
+}
+
+// TODO: We do not inline 'getNum' in the following case, where the value of 
+// 'self' in call '[self getNum]' is available and evaualtes to 
+// 'SelfUsedInParentChild' if it's called from fooA.
+// Self region should get created before we call foo and yje call to super 
+// should keep it live. 
+@interface SelfUsedInParent : NSObject
++ (int)getNum;
++ (int)foo;
+@end
+@implementation SelfUsedInParent
++ (int)getNum {return 5;}
++ (int)foo {
+  return [self getNum];
+}
+@end
+@interface SelfUsedInParentChild : SelfUsedInParent
++ (int)getNum;
++ (int)fooA;
+@end
+@implementation SelfUsedInParentChild
++ (int)getNum {return 0;}
++ (int)fooA {
+  return [super foo];
+}
+@end
+int checkSelfUsedInparentClassMethod() {
+    return 5/[SelfUsedInParentChild fooA];
+}
+
diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.h b/test/Analysis/inlining/InlineObjCInstanceMethod.h
new file mode 100644
index 0000000..bb0da28
--- /dev/null
+++ b/test/Analysis/inlining/InlineObjCInstanceMethod.h
@@ -0,0 +1,46 @@
+
+// Define a public header for the ObjC methods that are "visible" externally
+// and, thus, could be sub-classed. We should explore the path on which these
+// are sub-classed with unknown class by not inlining them.
+
+typedef signed char BOOL;
+typedef struct objc_class *Class;
+typedef struct objc_object {
+    Class isa;
+} *id;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
++(id)new;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+- (Class)class;
+-(id)retain;
+@end
+
+@interface PublicClass : NSObject {
+  int value3;
+}
+- (int)getZeroPublic;
+
+- (int) value2;
+
+@property (readonly) int value1;
+
+@property int value3;
+- (int)value3;
+- (void)setValue3:(int)newValue;
+@end
+
+@interface PublicSubClass : PublicClass
+@end
+
+@interface PublicParent : NSObject
+- (int)getZeroOverridden;
+@end
+
+@interface PublicSubClass2 : PublicParent
+- (int) getZeroOverridden;
+@end
+
diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.m b/test/Analysis/inlining/InlineObjCInstanceMethod.m
new file mode 100644
index 0000000..31b6d5b
--- /dev/null
+++ b/test/Analysis/inlining/InlineObjCInstanceMethod.m
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=dynamic-bifurcate -verify %s
+
+#include "InlineObjCInstanceMethod.h"
+
+// Method is defined in the parent; called through self.
+@interface MyParent : NSObject
+- (int)getInt;
+@end
+@implementation MyParent
+- (int)getInt {
+    return 0;
+}
+@end
+
+@interface MyClass : MyParent
+@end
+@implementation MyClass
+- (int)testDynDispatchSelf {
+  int y = [self getInt];
+  return 5/y; // expected-warning {{Division by zero}}
+}
+
+// Get the dynamic type info from a cast (from id to MyClass*).
++ (int)testAllocInit {
+  MyClass *a = [[self alloc] init];
+  return 5/[a getInt]; // expected-warning {{Division by zero}}
+}
+
+// Method is called on inited object.
++ (int)testAllocInit2 {
+  MyClass *a = [[MyClass alloc] init];
+  return 5/[a getInt]; // expected-warning {{Division by zero}}
+}
+
+// Method is called on a parameter.
++ (int)testParam: (MyClass*) a {
+  return 5/[a getInt]; // expected-warning {{Division by zero}}
+}
+
+// Method is called on a parameter of unnown type.
++ (int)testParamUnknownType: (id) a {
+  return 5/[a getInt]; // no warning
+}
+
+@end
+
+// TODO: When method is inlined, the attribute reset should be visible.
+@interface TestSettingAnAttributeInCallee : NSObject {
+  int _attribute;
+}
+  - (void) method2;
+@end
+
+@implementation TestSettingAnAttributeInCallee
+- (int) method1 {
+  [self method2];
+  return 5/_attribute; // expected-warning {{Division by zero}}
+}
+
+- (void) method2 {
+  _attribute = 0;
+}
+@end
+
+@interface TestSettingAnAttributeInCaller : NSObject {
+  int _attribute;
+}
+  - (int) method2;
+@end
+
+@implementation TestSettingAnAttributeInCaller
+- (void) method1 {
+  _attribute = 0;
+  [self method2];
+}
+
+- (int) method2 {
+  return 5/_attribute; // expected-warning {{Division by zero}}
+}
+@end
+
+
+// Don't crash if we don't know the receiver's region.
+void randomlyMessageAnObject(MyClass *arr[], int i) {
+  (void)[arr[i] getInt];
+}
\ No newline at end of file
diff --git a/test/Analysis/inlining/ObjCDynTypePopagation.m b/test/Analysis/inlining/ObjCDynTypePopagation.m
new file mode 100644
index 0000000..4faaa2c
--- /dev/null
+++ b/test/Analysis/inlining/ObjCDynTypePopagation.m
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
+
+#include "InlineObjCInstanceMethod.h"
+
+void clang_analyzer_eval(int);
+
+PublicSubClass2 *getObj();
+
+@implementation PublicParent
+- (int) getZeroOverridden {
+   return 1;
+}
+- (int) getZero {
+   return 0;
+}
+@end
+
+@implementation PublicSubClass2
+- (int) getZeroOverridden {
+   return 0;
+}
+
+/* Test that we get the right type from call to alloc. */
++ (void) testAllocSelf {
+  id a = [self alloc];
+  clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
+}
+
+
++ (void) testAllocClass {
+  id a = [PublicSubClass2 alloc];
+  clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
+}
+
++ (void) testAllocSuperOverriden {
+  id a = [super alloc];
+  // Evaluates to 1 in the parent.
+  clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{FALSE}} 
+}
+
++ (void) testAllocSuper {
+  id a = [super alloc];
+  clang_analyzer_eval([a getZero] == 0); // expected-warning{{TRUE}}
+}
+
++ (void) testAllocInit {
+  id a = [[self alloc] init];
+  clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
+}
+
++ (void) testNewSelf {
+  id a = [self new];
+  clang_analyzer_eval([a getZeroOverridden] == 0); // expected-warning{{TRUE}}
+}
+
+// Casting to parent should not pessimize the dynamic type. 
++ (void) testCastToParent {
+ id a = [[self alloc] init];
+ PublicParent *p = a;  
+  clang_analyzer_eval([p getZeroOverridden] == 0); // expected-warning{{TRUE}}
+}
+
+// The type of parameter gets used.
++ (void)testTypeFromParam:(PublicParent*) p {
+  clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
+}
+
+// Test implicit cast.
+// Note, in this case, p could also be a subclass of MyParent.
++ (void) testCastFromId:(id) a {
+  PublicParent *p = a;  
+  clang_analyzer_eval([p getZero] == 0); // expected-warning{{TRUE}}
+}
+@end
+
+// TODO: Would be nice to handle the case of dynamically obtained class info
+// as well. We need a MemRegion for class types for this.
+int testDynamicClass(BOOL coin) {
+ Class AllocClass = (coin ? [NSObject class] : [PublicSubClass2 class]);
+ id x = [[AllocClass alloc] init];
+ if (coin)
+   return [x getZero];
+ return 1;
+}
diff --git a/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
new file mode 100644
index 0000000..739e10f
--- /dev/null
+++ b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
@@ -0,0 +1,37 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
+
+typedef signed char BOOL;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
+-(id)init;
++(id)new;
+-(id)autorelease;
+-(id)copy;
+- (Class)class;
+-(id)retain;
+@end
+void clang_analyzer_eval(BOOL);
+
+@interface SomeOtherClass : NSObject
+- (int)getZero;
+@end
+@implementation SomeOtherClass
+- (int)getZero { return 0; }
+@end
+
+@interface MyClass : NSObject
+- (int)getZero;
+@end
+
+@implementation MyClass
+- (int)getZero { return 1; }
+
+// TODO: Not only we should correctly determine that the type of o at runtime 
+// is MyClass, but we should also warn about it. 
++ (void) testCastToParent {
+  id a = [[self alloc] init];
+  SomeOtherClass *o = a;  
+  clang_analyzer_eval([o getZero] == 0); // expected-warning{{FALSE}}
+}
+@end
diff --git a/test/Analysis/inlining/RetainCountExamples.m b/test/Analysis/inlining/RetainCountExamples.m
new file mode 100644
index 0000000..2b682c2
--- /dev/null
+++ b/test/Analysis/inlining/RetainCountExamples.m
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-ipa=dynamic-bifurcate -verify %s
+
+typedef signed char BOOL;
+typedef struct objc_class *Class;
+typedef struct objc_object {
+    Class isa;
+} *id;
+@protocol NSObject  - (BOOL)isEqual:(id)object; @end
+@interface NSObject <NSObject> {}
++(id)alloc;
++(id)new;
+- (oneway void)release;
+-(id)init;
+-(id)autorelease;
+-(id)copy;
+- (Class)class;
+-(id)retain;
+@end
+
+@interface SelfStaysLive : NSObject
+- (id)init;
+@end
+
+@implementation SelfStaysLive
+- (id)init {
+  return [super init];
+}
+@end
+
+void selfStaysLive() {
+    SelfStaysLive *foo = [[SelfStaysLive alloc] init]; 
+    [foo release];
+}
\ No newline at end of file
diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
new file mode 100644
index 0000000..fa473ae
--- /dev/null
+++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=dynamic-bifurcate -verify %s
+
+void clang_analyzer_eval(bool);
+
+class A {
+public:
+  virtual int get() { return 0; }
+};
+
+void testBifurcation(A *a) {
+  clang_analyzer_eval(a->get() == 0); // expected-warning{{TRUE}} expected-warning{{UNKNOWN}}
+}
+
+void testKnown() {
+  A a;
+  clang_analyzer_eval(a.get() == 0); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c
new file mode 100644
index 0000000..bd23915
--- /dev/null
+++ b/test/Analysis/inlining/path-notes.c
@@ -0,0 +1,1291 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file %s -o - | FileCheck %s
+
+void zero(int **p) {
+  *p = 0;
+  // expected-note@-1 {{Null pointer value stored to 'a'}}
+}
+
+void testZero(int *a) {
+  zero(&a);
+  // expected-note@-1 {{Calling 'zero'}}
+  // expected-note@-2 {{Returning from 'zero'}}
+  *a = 1; // expected-warning{{Dereference of null pointer}}
+  // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
+
+
+void check(int *p) {
+  if (p) {
+    // expected-note@-1 + {{Assuming 'p' is null}}
+    // expected-note@-2 + {{Assuming pointer value is null}}
+    // expected-note@-3 + {{Taking false branch}}
+    return;
+  }
+  return;
+}
+
+void testCheck(int *a) {
+  check(a);
+  // expected-note@-1 {{Calling 'check'}}
+  // expected-note@-2 {{Returning from 'check'}}
+  *a = 1; // expected-warning{{Dereference of null pointer}}
+  // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
+
+
+int *getPointer();
+
+void testInitCheck() {
+  int *a = getPointer();
+  // expected-note@-1 {{Variable 'a' initialized here}}
+  check(a);
+  // expected-note@-1 {{Calling 'check'}}
+  // expected-note@-2 {{Returning from 'check'}}
+  *a = 1; // expected-warning{{Dereference of null pointer}}
+  // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
+
+void testStoreCheck(int *a) {
+  a = getPointer();
+  // expected-note@-1 {{Value assigned to 'a'}}
+  check(a);
+  // expected-note@-1 {{Calling 'check'}}
+  // expected-note@-2 {{Returning from 'check'}}
+  *a = 1; // expected-warning{{Dereference of null pointer}}
+  // expected-note@-1 {{Dereference of null pointer (loaded from variable 'a')}}
+}
+
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK:  <key>files</key>
+// CHECK:  <array>
+// CHECK:   <string>{{.*}}path-notes.c</string>
+// CHECK:  </array>
+// CHECK:  <key>diagnostics</key>
+// CHECK:  <array>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>10</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling &apos;zero&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling &apos;zero&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>4</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call from &apos;testZero&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call from &apos;testZero&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>4</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>5</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>5</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>5</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Null pointer value stored to &apos;a&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Null pointer value stored to &apos;a&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>10</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning from &apos;zero&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning from &apos;zero&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>6</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>13</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>13</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>13</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>13</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>13</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testZero</string>
+// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>13</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>29</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling &apos;check&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling &apos;check&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call from &apos;testCheck&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call from &apos;testCheck&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>19</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming &apos;p&apos; is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming &apos;p&apos; is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>19</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming pointer value is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>29</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning from &apos;check&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning from &apos;check&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>32</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>32</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>32</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>32</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>32</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testCheck</string>
+// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>32</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>40</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>40</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>40</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;a&apos; initialized here</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;a&apos; initialized here</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>40</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>40</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>42</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>42</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>42</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling &apos;check&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling &apos;check&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call from &apos;testInitCheck&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call from &apos;testInitCheck&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>19</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming &apos;p&apos; is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming &apos;p&apos; is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>42</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>42</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>42</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning from &apos;check&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning from &apos;check&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>45</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testInitCheck</string>
+// CHECK:   <key>issue_hash</key><integer>6</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>45</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>50</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Value assigned to &apos;a&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Value assigned to &apos;a&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>52</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>52</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>52</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Calling &apos;check&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Calling &apos;check&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>col</key><integer>1</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Entered call from &apos;testStoreCheck&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Entered call from &apos;testStoreCheck&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>1</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>19</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming &apos;p&apos; is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming &apos;p&apos; is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>25</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>52</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>52</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>52</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>1</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Returning from &apos;check&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Returning from &apos;check&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>55</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>55</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>55</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Dereference of null pointer (loaded from variable &apos;a&apos;)</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testStoreCheck</string>
+// CHECK:   <key>issue_hash</key><integer>6</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>55</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:  </array>
+// CHECK: </dict>
+// CHECK: </plist>
diff --git a/test/Analysis/iterators.cpp b/test/Analysis/iterators.cpp
deleted file mode 100644
index 9d7ef32..0000000
--- a/test/Analysis/iterators.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-// RUN: %clang --analyze -Xclang -analyzer-checker=core,experimental.cplusplus.Iterators -Xclang -verify %s
-// XFAIL: win32
-
-// FIXME: Does not work with inlined C++ methods.
-// XFAIL: *
-
-#include <vector>
-
-void fum(std::vector<int>::iterator t);
-
-void foo1()
-{
-  // iterators that are defined but not initialized
-  std::vector<int>::iterator it2;
-  fum(it2); // expected-warning{{Use of iterator that is not defined}}
-  *it2;     // expected-warning{{Use of iterator that is not defined}}
-
-  std::vector<int> v, vv;
-  std::vector<int>::iterator it = v.begin();
-  fum(it);  // no-warning
-  *it;  // no-warning
-  // a valid iterator plus an integer is still valid
-  std::vector<int>::iterator et = it + 3;
-  while(it != et) { // no-warning
-    if (*it == 0) // no-warning
-      *it = 1;  // no-warning
-  }
-  // iterators from different instances Cannot be compared
-  et = vv.end();
-  while(it != et) // expected-warning{{Cannot compare iterators from different containers}}
-    ;
-
-  for( std::vector<int>::iterator it = v.begin(); it != v.end(); it++ ) { // no-warning
-    if (*it == 1) // no-warning
-      *it = 0;  // no-warning
-  }
-
-  // copying a valid iterator results in a valid iterator
-  et = it;  // no-warning
-  *et;  // no-warning
-
-  // any combo of valid iterator plus a constant is still valid
-  et = it + 2;  // no-warning
-  *et;  // no-warning
-  et = 2 + it;  // no-warning
-  *et;  // no-warning
-  et = 2 + 4 + it;  // no-warning
-  *et;  // no-warning
-
-  // calling insert invalidates unless assigned to as result, but still
-  // invalidates other iterators on the same instance
-  it = v.insert( it, 1 ); // no-warning
-  *et;  // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}}
-  ++it; // no-warning
-
-  // calling erase invalidates the iterator
-  v.erase(it);  // no-warning
-  et = it + 2;  // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  et = 2 + it + 2;  // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  et = 2 + it;  // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  ++it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  it++; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  *it;  // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  it = v.insert( it, 1 ); // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}}
-  // now valid after return from insert
-  *it;  // no-warning
-}
-
-// work with using namespace
-void foo2()
-{
-  using namespace std;
-
-  vector<int> v;
-  vector<int>::iterator it = v.begin();
-  *it;  // no-warning
-  v.insert( it, 1 );  // no-warning
-  *it;  // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}}
-  it = v.insert( it, 1 ); // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}}
-  *it;  // no-warning
-}
-
-// using reserve eliminates some warnings
-void foo3()
-{
-  std::vector<long> v;
-  std::vector<long>::iterator b = v.begin();
-  v.reserve( 100 );
-
-  // iterator assigned before the reserve is still invalidated
-  *b; // expected-warning{{Attempt to use an iterator made invalid by call to 'reserve'}}
-  b = v.begin();
-  v.insert( b, 1 ); // no-warning
-
-  // iterator after assignment is still valid (probably)
-  *b; // no-warning
-}
-
-// check on copying one iterator to another
-void foo4()
-{
-  std::vector<float> v, vv;
-  std::vector<float>::iterator it = v.begin();
-  *it;  // no-warning
-  v = vv;
-  *it;  // expected-warning{{Attempt to use an iterator made invalid by copying another container to its container}}
-}
-
diff --git a/test/Analysis/ivars.m b/test/Analysis/ivars.m
new file mode 100644
index 0000000..42e92d2
--- /dev/null
+++ b/test/Analysis/ivars.m
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
+
+void clang_analyzer_eval(int);
+
+@interface Root {
+@public
+  int uniqueID;
+}
+
+- (void)refreshID;
+@end
+
+void testInvalidation(Root *obj) {
+  int savedID = obj->uniqueID;
+  clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{TRUE}}
+
+  [obj refreshID];
+  clang_analyzer_eval(savedID == obj->uniqueID); // expected-warning{{UNKNOWN}}
+}
+
+
+@interface Child : Root
+@end
+
+@implementation Child
+- (void)testSuperInvalidation {
+  int savedID = self->uniqueID;
+  clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{TRUE}}
+
+  [super refreshID];
+  clang_analyzer_eval(savedID == self->uniqueID); // expected-warning{{UNKNOWN}}
+}
+@end
+
+
+@interface ManyIvars {
+  struct S { int a, b; } s;
+  int c;
+  int d;
+}
+@end
+
+struct S makeS();
+
+@implementation ManyIvars
+
+- (void)testMultipleIvarInvalidation:(int)useConstraints {
+  if (useConstraints) {
+    if (s.a != 1) return;
+    if (s.b != 2) return;
+    if (c != 3) return;
+    if (d != 4) return;
+    return;
+  } else {
+    s.a = 1;
+    s.b = 2;
+    c = 3;
+    d = 4;
+  }
+
+  clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
+
+  d = 0;
+
+  clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(s.b == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(d == 0); // expected-warning{{TRUE}}
+
+  d = 4;
+  s = makeS();
+
+  clang_analyzer_eval(s.a == 1); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
+
+  s.a = 1;
+
+  clang_analyzer_eval(s.a == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(s.b == 2); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(d == 4); // expected-warning{{TRUE}}
+}
+
++ (void)testMultipleIvarInvalidation:(int)useConstraints
+                           forObject:(ManyIvars *)obj {
+  if (useConstraints) {
+    if (obj->s.a != 1) return;
+    if (obj->s.b != 2) return;
+    if (obj->c != 3) return;
+    if (obj->d != 4) return;
+    return;
+  } else {
+    obj->s.a = 1;
+    obj->s.b = 2;
+    obj->c = 3;
+    obj->d = 4;
+  }
+
+  clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}}
+
+  obj->d = 0;
+
+  clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->s.b == 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->d == 0); // expected-warning{{TRUE}}
+
+  obj->d = 4;
+  obj->s = makeS();
+
+  clang_analyzer_eval(obj->s.a == 1); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}}
+
+  obj->s.a = 1;
+
+  clang_analyzer_eval(obj->s.a == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->s.b == 2); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(obj->c == 3); // expected-warning{{TRUE}}
+  clang_analyzer_eval(obj->d == 4); // expected-warning{{TRUE}}
+}
+
+@end
diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m
index cb4f72c..fe6c61d 100644
--- a/test/Analysis/keychainAPI.m
+++ b/test/Analysis/keychainAPI.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -analyzer-ipa=inlining -verify
+// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify
 
 // Fake typedefs.
 typedef unsigned int OSStatus;
@@ -76,7 +76,7 @@
   UInt32 length;
   void *outData;
   st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
-  if (st == GenericError) // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'.}}
+  if (st == GenericError) // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
     SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}}
 }
 
@@ -220,7 +220,7 @@
     if (st == noErr)
       SecKeychainItemFreeContent(ptr, outData[3]);
   }
-  if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'.}}
+  if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
     length++;
   }
   return 0;
@@ -318,7 +318,7 @@
   UInt32 pwdLen = 0;
   void*  pwdBytes = 0;
   OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);
-  SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned.}}
+  SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}}
 }
 
 //Example from bug 10797.
diff --git a/test/Analysis/logical-ops.c b/test/Analysis/logical-ops.c
new file mode 100644
index 0000000..a1223b3
--- /dev/null
+++ b/test/Analysis/logical-ops.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
+
+void testAnd(int i, int *p) {
+  int *nullP = 0;
+  int *knownP = &i;
+  clang_analyzer_eval((knownP && knownP) == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval((knownP && nullP) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((knownP && p) == 1); // expected-warning{{UNKNOWN}}
+}
+
+void testOr(int i, int *p) {
+  int *nullP = 0;
+  int *knownP = &i;
+  clang_analyzer_eval((nullP || knownP) == 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval((nullP || nullP) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval((nullP || p) == 1); // expected-warning{{UNKNOWN}}
+}
+
+
+// PR13461
+int testTypeIsInt(int i, void *p) {
+  if (i | (p && p))
+    return 1;
+  return 0;
+}
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index 089e531..9c040b6 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -70,10 +70,9 @@
   myglobalpointer = my_malloc(12); // no-warning
 }
 
-// TODO: We will be able to handle this after we add support for tracking allocations stored in struct fields.
 void af1_d() {
   struct stuff mystuff;
-  mystuff.somefield = my_malloc(12); // false negative
+  mystuff.somefield = my_malloc(12); // expected-warning{{Memory is never released; potential leak}}
 }
 
 // Test that we can pass out allocated memory via pointer-to-pointer.
@@ -209,11 +208,11 @@
 }
 
 void PR6123() {
-  int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+  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.}}
+  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
 }
 
diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c
index 589bc4f..c804219 100644
--- a/test/Analysis/malloc-interprocedural.c
+++ b/test/Analysis/malloc-interprocedural.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-ipa=inlining -analyzer-inline-max-stack-depth=5 -analyzer-inline-max-function-size=6 -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -analyzer-inline-max-function-size=6 -verify %s
 
 #include "system-header-simulator.h"
 
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 377642c..e3d92d9 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -19,7 +19,7 @@
 
 void f1() {
   int *p = malloc(12);
-  return; // expected-warning{{Memory is never released; potential leak}}
+  return; // expected-warning{{Memory is never released; potential leak of memory pointed to by 'p'}}
 }
 
 void f2() {
@@ -44,7 +44,7 @@
   char *p = (char*)malloc(size);
   if (p) {
     char *q = (char*)realloc(p, sizeIn);
-    char x = *q; // expected-warning {{Memory is never released; potential leak}}
+    char x = *q; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'q'}}
   }
 }
 
@@ -69,7 +69,7 @@
   char *p = malloc(12);
   char *r = realloc(p, 0);
   if (!r) {
-    free(p);
+    free(p); // expected-warning {{Attempt to free released memory}}
   } else {
     free(r);
   }
@@ -79,7 +79,7 @@
   char *p = malloc(12);
   char *r = realloc(p, 0);
   if (!r) {
-    free(p);
+    free(p); // expected-warning {{Attempt to free released memory}}
   } else {
     free(r);
   }
@@ -102,7 +102,7 @@
 }
 
 void reallocPtrZero1() {
-  char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak}}
+  char *r = realloc(0, 12); // expected-warning {{Memory is never released; potential leak of memory pointed to by 'r'}}
 }
 
 void reallocPtrZero2() {
@@ -260,11 +260,11 @@
 }
 
 void PR6123() {
-  int *x = malloc(11); // expected-warning{{Cast a region whose size is not a multiple of the destination type size.}}
+  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.}}
+  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
 }
 
@@ -321,7 +321,7 @@
 void paramFree(int *p) {
   myfoo(p);
   free(p); // no warning
-  myfoo(p); // TODO: This should be a warning.
+  myfoo(p); // expected-warning {{Use of memory after it is freed}}
 }
 
 int* mallocEscapeRet() {
@@ -389,7 +389,7 @@
 
 void mallocMalloc() {
   int *p = malloc(12);
-  p = malloc(12); // expected-warning 2 {{Memory is never released; potential leak}}
+  p = malloc(12); // expected-warning {{Memory is never released; potential leak}}
 }
 
 void mallocFreeMalloc() {
@@ -513,20 +513,26 @@
   int *x = malloc(12);
   StructWithPtr St;
   St.memP = x;
-  arrOfStructs[0] = St;
+  arrOfStructs[0] = St; // no-warning
 }
 
 StructWithPtr testMalloc2() {
   int *x = malloc(12);
   StructWithPtr St;
   St.memP = x;
-  return St;
+  return St; // no-warning
 }
 
 int *testMalloc3() {
   int *x = malloc(12);
   int *y = x;
-  return y;
+  return y; // no-warning
+}
+
+void testStructLeak() {
+  StructWithPtr St;
+  St.memP = malloc(12);
+  return; // expected-warning {{Memory is never released; potential leak of memory pointed to by 'St.memP'}}
 }
 
 void testElemRegion1() {
@@ -926,31 +932,16 @@
   return 0;
 }
 
-// ----------------------------------------------------------------------------
-// False negatives.
-
-// TODO: This requires tracking symbols stored inside the structs/arrays.
-void testMalloc5() {
-  StructWithPtr St;
-  StructWithPtr *pSt = &St;
-  pSt->memP = malloc(12);
-}
-
-// TODO: This is another false negative.
-void testMallocWithParam(int **p) {
-  *p = (int*) malloc(sizeof(int));
-  *p = 0;
-}
-
-void testMallocWithParam_2(int **p) {
-  *p = (int*) malloc(sizeof(int));
-}
-
-// TODO: This should produce a warning, similar to the previous issue.
 void localArrayTest() {
   char *p = (char*)malloc(12);
   char *ArrayL[12];
-  ArrayL[0] = p;
+  ArrayL[0] = p; // expected-warning {{leak}}
+}
+
+void localStructTest() {
+  StructWithPtr St;
+  StructWithPtr *pSt = &St;
+  pSt->memP = malloc(12); // expected-warning{{Memory is never released; potential leak}}
 }
 
 // Test double assignment through integers.
@@ -999,3 +990,36 @@
   xpc_connection_resume(peer);
 }
 
+// Make sure we catch errors when we free in a function which does not allocate memory.
+void freeButNoMalloc(int *p, int x){
+  if (x) {
+    free(p);
+    //user forgot a return here.
+  }
+  free(p); // expected-warning {{Attempt to free released memory}}
+}
+
+struct HasPtr {
+  int *p;
+};
+
+int* reallocButNoMalloc(struct HasPtr *a, int c, int size) {
+  int *s;
+  a->p = (int *)realloc(a->p, size);
+  if (a->p == 0)
+    return 0; // expected-warning{{Memory is never released; potential leak}}
+  return a->p;
+}
+
+// ----------------------------------------------------------------------------
+// False negatives.
+
+// TODO: This is another false negative.
+void testMallocWithParam(int **p) {
+  *p = (int*) malloc(sizeof(int));
+  *p = 0;
+}
+
+void testMallocWithParam_2(int **p) {
+  *p = (int*) malloc(sizeof(int));
+}
diff --git a/test/Analysis/method-call-path-notes.cpp b/test/Analysis/method-call-path-notes.cpp
new file mode 100644
index 0000000..17034b9
--- /dev/null
+++ b/test/Analysis/method-call-path-notes.cpp
@@ -0,0 +1,749 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-output=plist-multi-file %s -o - | FileCheck %s
+
+// Test warning about null or uninitialized pointer values used as instance member
+// calls.
+class TestInstanceCall {
+public:
+  void foo() {}
+};
+
+void test_ic() {
+  TestInstanceCall *p; // expected-note {{Variable 'p' declared without an initial value}}
+  p->foo(); // expected-warning {{Called C++ object pointer is uninitialized}} expected-note {{Called C++ object pointer is uninitialized}}
+}
+
+void test_ic_null() {
+  TestInstanceCall *p = 0; // expected-note {{Variable 'p' initialized to a null pointer value}}
+  p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
+}
+
+void test_ic_set_to_null() {
+  TestInstanceCall *p;
+  p = 0; // expected-note {{Null pointer value stored to 'p'}}
+  p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
+}
+
+void test_ic_null(TestInstanceCall *p) {
+  if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}}
+    p->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
+}
+
+void test_ic_member_ptr() {
+  TestInstanceCall *p = 0; // expected-note {{Variable 'p' initialized to a null pointer value}}
+  typedef void (TestInstanceCall::*IC_Ptr)();
+  IC_Ptr bar = &TestInstanceCall::foo;
+  (p->*bar)(); // expected-warning {{Called C++ object pointer is null}} expected-note{{Called C++ object pointer is null}}
+}
+
+void test_cast(const TestInstanceCall *p) {
+  if (!p) // expected-note {{Assuming pointer value is null}} expected-note {{Taking true branch}}
+    const_cast<TestInstanceCall *>(p)->foo(); // expected-warning {{Called C++ object pointer is null}} expected-note {{Called C++ object pointer is null}}
+}
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK:  <key>files</key>
+// CHECK:  <array>
+// CHECK:   <string>{{.*}}method-call-path-notes.cpp</string>
+// CHECK:  </array>
+// CHECK:  <key>diagnostics</key>
+// CHECK:  <array>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>12</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>12</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>12</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; declared without an initial value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; declared without an initial value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>12</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>12</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>13</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>13</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>13</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>13</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>13</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Called C++ object pointer is uninitialized</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Called C++ object pointer is uninitialized</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Called C++ object pointer is uninitialized</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Called C++ object pointer is uninitialized</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>test_ic</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>13</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>17</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>17</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>17</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>18</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>18</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Called C++ object pointer is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>test_ic_null</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>18</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>22</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>23</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>24</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>24</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>24</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>24</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>24</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Called C++ object pointer is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>test_ic_set_to_null</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>24</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>28</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>28</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>28</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming pointer value is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>28</integer>
+// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>29</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>5</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>5</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Called C++ object pointer is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>test_ic_null</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>29</integer>
+// CHECK:    <key>col</key><integer>5</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>33</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>33</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>33</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>33</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>33</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>36</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>36</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>36</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>36</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Called C++ object pointer is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>test_ic_member_ptr</string>
+// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>36</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>40</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>40</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>41</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>41</integer>
+// CHECK:            <key>col</key><integer>14</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>41</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>41</integer>
+// CHECK:          <key>col</key><integer>5</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>41</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Called C++ object pointer is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Called C++ object pointer is null</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Called C++ object pointer is null</string>
+// CHECK:    <key>category</key><string>Logic error</string>
+// CHECK:    <key>type</key><string>Called C++ object pointer is null</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>test_cast</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>41</integer>
+// CHECK:    <key>col</key><integer>5</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:  </array>
+// CHECK: </dict>
+// CHECK: </plist>
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp
index 91da532..9120627 100644
--- a/test/Analysis/method-call.cpp
+++ b/test/Analysis/method-call.cpp
@@ -1,25 +1,37 @@
 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -analyzer-store region -verify %s
-// XFAIL: *
 
 void clang_analyzer_eval(bool);
 
+
 struct A {
   int x;
   A(int a) { x = a; }
   int getx() const { return x; }
 };
 
+void testNullObject(A *a) {
+  clang_analyzer_eval(a); // expected-warning{{UNKNOWN}}
+  (void)a->getx(); // assume we know what we're doing
+  clang_analyzer_eval(a); // expected-warning{{TRUE}}
+}
+
+
+// FIXME: These require constructor inlining to be enabled.
+
 void f1() {
   A x(3);
-  clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
+  // should be TRUE
+  clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}}
 }
 
 void f2() {
   const A &x = A(3);
-  clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
+  // should be TRUE
+  clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}}
 }
 
 void f3() {
   const A &x = (A)3;
-  clang_analyzer_eval(x.getx() == 3); // expected-warning{{TRUE}}
+  // should be TRUE
+  clang_analyzer_eval(x.getx() == 3); // expected-warning{{UNKNOWN}}
 }
diff --git a/test/Analysis/misc-ps-cxx0x.cpp b/test/Analysis/misc-ps-cxx0x.cpp
index 7712bb8..164af5d 100644
--- a/test/Analysis/misc-ps-cxx0x.cpp
+++ b/test/Analysis/misc-ps-cxx0x.cpp
@@ -87,4 +87,3 @@
   operator=(dynamic_cast<const rdar11817693_BaseBase&>(src));
 }
 
-
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index 381aa03..981e059 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify -fblocks -analyzer-ipa=inlining -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -verify -fblocks -analyzer-ipa=inlining -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions
 
 // Test basic handling of references.
 char &test1_aux();
@@ -271,13 +271,27 @@
 const Rdar9212495_A& rdar9212495(const Rdar9212495_C* ptr) {
   const Rdar9212495_A& val = dynamic_cast<const Rdar9212495_A&>(*ptr);
   
+  // This is not valid C++; dynamic_cast with a reference type will throw an
+  // exception if the pointer does not match the expected type. However, our
+  // implementation of dynamic_cast will pass through a null pointer...or a
+  // "null reference"! So this branch is actually possible.
   if (&val == 0) {
-    val.bar(); // FIXME: This should eventually be a null dereference.
+    val.bar(); // expected-warning{{Called C++ object pointer is null}}
   }
   
   return val;
 }
 
+const Rdar9212495_A* rdar9212495_ptr(const Rdar9212495_C* ptr) {
+  const Rdar9212495_A* val = dynamic_cast<const Rdar9212495_A*>(ptr);
+
+  if (val == 0) {
+    val->bar(); // expected-warning{{Called C++ object pointer is null}}
+  }
+
+  return val;
+}
+
 // Test constructors invalidating arguments.  Previously this raised
 // an uninitialized value warning.
 extern "C" void __attribute__((noreturn)) PR9645_exit(int i);
@@ -523,7 +537,8 @@
     throw MyEnumValue;
   } catch (MyEnum e) {
     int *p = 0;
-    *p = 0xDEADBEEF; // expected-warning {{null}}
+    // FALSE NEGATIVE
+    *p = 0xDEADBEEF; // {{null}}
     return e;
   }
   return MyEnumValue;
@@ -548,7 +563,8 @@
   catch (...)
   {
     int *p = 0;
-    *p = 0xDEADBEEF; // expected-warning {{null}}
+    // FALSE NEGATIVE
+    *p = 0xDEADBEEF; // {{null}}
   }
 }
 
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 88860bb..2b481c4 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -299,7 +299,7 @@
 int test_handle_array_wrapper() {
   struct ArrayWrapper x;
   test_handle_array_wrapper_helper(&x);
-  struct WrappedStruct *p = (struct WrappedStruct*) x.y; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption.}}
+  struct WrappedStruct *p = (struct WrappedStruct*) x.y; // expected-warning{{Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption}}
   return p->z;  // no-warning
 }
 
diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c
index f81b0dd..8ff710b 100644
--- a/test/Analysis/misc-ps.c
+++ b/test/Analysis/misc-ps.c
@@ -126,3 +126,10 @@
     }
 }
 
+// This example tests CFG handling of '||' nested in a ternary expression,
+// and seeing that the analyzer doesn't crash.
+int isctype(char c, unsigned long f)
+{
+  return (c < 1 || c > 10) ? 0 : !!(c & f);
+}
+
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index c22837e..bcc0472 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -1356,3 +1356,20 @@
 }
 @end
 
+// Don't crash when a ?: is only preceded by a statement (not an expression)
+// in the CFG.
+void __assert_fail();
+
+enum rdar1196620_e { E_A, E_B, E_C, E_D };
+struct rdar1196620_s { int ints[E_D+1]; };
+
+static void rdar1196620_call_assert(struct rdar1196620_s* s) {
+  int i = 0;
+  s?(void)0:__assert_fail();
+}
+
+static void rdar1196620(struct rdar1196620_s* s) {
+  rdar1196620_call_assert(s);
+}
+
+
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 e4d5aaf..7cf2aee 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -80,11 +80,11 @@
 int marker(void) { // control reaches end of non-void function
 }
 
-// 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 'unsignedLongLongM' is nil and returns a value of type 'unsigned 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: 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 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' 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-darwin9-NOT: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
 // CHECK-darwin9-NOT: warning: The receiver of message 'unsignedLongLongM' is nil and returns a value of type 'unsigned long long' that will be garbage
diff --git a/test/Analysis/objc-method-coverage.m b/test/Analysis/objc-method-coverage.m
index 056aafe..3088a29 100644
--- a/test/Analysis/objc-method-coverage.m
+++ b/test/Analysis/objc-method-coverage.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=inlining -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
 // RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-ipa=none -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
 
 @interface I
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
index cae08ab..769c1bc 100644
--- a/test/Analysis/plist-output.m
+++ b/test/Analysis/plist-output.m
@@ -1,5 +1,4 @@
-// RUN: %clang --analyze %s -o %t > /dev/null 2>&1
-// RUN: FileCheck -input-file %t %s
+// RUN: %clang --analyze %s -o - 2>/dev/null | FileCheck %s
 
 void test_null_init(void) {
   int *p = 0;
@@ -27,7 +26,6 @@
   
 void test_null_cond_transitive(int *q) {
   if (!q) {
-    // FIXME: we need a diagnostic saying that p is initialized to 0
     int *p = q;
     *p = 0xDEADBEEF;
   }
@@ -81,10 +79,12 @@
 @end
 
 // CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 // CHECK: <plist version="1.0">
 // CHECK: <dict>
 // CHECK:  <key>files</key>
 // CHECK:  <array>
+// CHECK:   <string>{{.*}}plist-output.m</string>
 // CHECK:  </array>
 // CHECK:  <key>diagnostics</key>
 // CHECK:  <array>
@@ -92,6 +92,35 @@
 // CHECK:    <key>path</key>
 // CHECK:    <array>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>4</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>4</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>4</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -99,12 +128,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>line</key><integer>4</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>5</integer>
+// CHECK:            <key>line</key><integer>4</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -112,12 +141,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>6</integer>
+// CHECK:            <key>line</key><integer>5</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>6</integer>
+// CHECK:            <key>line</key><integer>5</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -129,7 +158,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>6</integer>
+// CHECK:       <key>line</key><integer>5</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -137,12 +166,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>6</integer>
+// CHECK:          <key>line</key><integer>5</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>6</integer>
+// CHECK:          <key>line</key><integer>5</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -163,7 +192,7 @@
 // CHECK:   <key>issue_hash</key><integer>2</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>6</integer>
+// CHECK:    <key>line</key><integer>5</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -179,12 +208,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>9</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>line</key><integer>9</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -192,12 +221,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>12</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>12</integer>
+// CHECK:            <key>line</key><integer>10</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -209,7 +238,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>12</integer>
+// CHECK:       <key>line</key><integer>10</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -217,12 +246,75 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>12</integer>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>10</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>10</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>11</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>11</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>11</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>11</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>12</integer>
+// CHECK:          <key>line</key><integer>11</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -243,7 +335,7 @@
 // CHECK:   <key>issue_hash</key><integer>3</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>12</integer>
+// CHECK:    <key>line</key><integer>11</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -259,12 +351,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>16</integer>
+// CHECK:            <key>line</key><integer>15</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>16</integer>
+// CHECK:            <key>line</key><integer>15</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -272,12 +364,75 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>line</key><integer>17</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>19</integer>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>17</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>17</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>17</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;q&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;q&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>17</integer>
+// CHECK:            <key>col</key><integer>5</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>18</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -289,7 +444,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>19</integer>
+// CHECK:       <key>line</key><integer>18</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -297,12 +452,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>line</key><integer>18</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>19</integer>
+// CHECK:          <key>line</key><integer>18</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -323,7 +478,7 @@
 // CHECK:   <key>issue_hash</key><integer>4</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>19</integer>
+// CHECK:    <key>line</key><integer>18</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -339,12 +494,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>22</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>22</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -352,12 +507,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>22</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>22</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -369,7 +524,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>23</integer>
+// CHECK:       <key>line</key><integer>22</integer>
 // CHECK:       <key>col</key><integer>7</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -377,12 +532,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>line</key><integer>22</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>23</integer>
+// CHECK:          <key>line</key><integer>22</integer>
 // CHECK:          <key>col</key><integer>8</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -395,6 +550,35 @@
 // CHECK: <string>Assuming &apos;p&apos; is null</string>
 // CHECK:     </dict>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>22</integer>
+// CHECK:       <key>col</key><integer>7</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>22</integer>
+// CHECK:          <key>col</key><integer>7</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>22</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Assuming pointer value is null</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Assuming pointer value is null</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -402,12 +586,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>22</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>23</integer>
+// CHECK:            <key>line</key><integer>22</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -415,12 +599,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>24</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>24</integer>
+// CHECK:            <key>line</key><integer>23</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -432,7 +616,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>24</integer>
+// CHECK:       <key>line</key><integer>23</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -440,12 +624,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>24</integer>
+// CHECK:          <key>line</key><integer>23</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>24</integer>
+// CHECK:          <key>line</key><integer>23</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -466,7 +650,7 @@
 // CHECK:   <key>issue_hash</key><integer>2</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>24</integer>
+// CHECK:    <key>line</key><integer>23</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -482,12 +666,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>28</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>28</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -495,12 +679,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>28</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>28</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -516,12 +700,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>28</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>29</integer>
+// CHECK:            <key>line</key><integer>28</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -529,12 +713,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>31</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>31</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -543,6 +727,35 @@
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>29</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>5</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>29</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -550,12 +763,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>31</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>31</integer>
+// CHECK:            <key>line</key><integer>29</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -563,12 +776,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>32</integer>
+// CHECK:            <key>line</key><integer>30</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>32</integer>
+// CHECK:            <key>line</key><integer>30</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -580,7 +793,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>32</integer>
+// CHECK:       <key>line</key><integer>30</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -588,12 +801,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>32</integer>
+// CHECK:          <key>line</key><integer>30</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>32</integer>
+// CHECK:          <key>line</key><integer>30</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -611,10 +824,10 @@
 // CHECK:    <key>type</key><string>Dereference of null pointer</string>
 // CHECK:   <key>issue_context_kind</key><string>function</string>
 // CHECK:   <key>issue_context</key><string>test_null_cond_transitive</string>
-// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>32</integer>
+// CHECK:    <key>line</key><integer>30</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -630,12 +843,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>35</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>35</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -643,12 +856,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>35</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>35</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -664,12 +877,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>35</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>37</integer>
+// CHECK:            <key>line</key><integer>35</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -677,12 +890,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>39</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>39</integer>
+// CHECK:            <key>line</key><integer>37</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -694,7 +907,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>39</integer>
+// CHECK:       <key>line</key><integer>37</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -702,12 +915,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>39</integer>
+// CHECK:          <key>line</key><integer>37</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>39</integer>
+// CHECK:          <key>line</key><integer>37</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -728,7 +941,7 @@
 // CHECK:   <key>issue_hash</key><integer>3</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>39</integer>
+// CHECK:    <key>line</key><integer>37</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -744,12 +957,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>44</integer>
+// CHECK:            <key>line</key><integer>42</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>44</integer>
+// CHECK:            <key>line</key><integer>42</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -757,12 +970,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>44</integer>
+// CHECK:            <key>line</key><integer>42</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>44</integer>
+// CHECK:            <key>line</key><integer>42</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -778,12 +991,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>44</integer>
+// CHECK:            <key>line</key><integer>42</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>44</integer>
+// CHECK:            <key>line</key><integer>42</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -791,12 +1004,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -812,12 +1025,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -825,12 +1038,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -846,12 +1059,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>line</key><integer>45</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -859,12 +1072,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>line</key><integer>48</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>line</key><integer>48</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -873,6 +1086,35 @@
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>48</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>48</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>48</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -880,12 +1122,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>line</key><integer>48</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>line</key><integer>48</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -893,12 +1135,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>line</key><integer>49</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>line</key><integer>49</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -910,7 +1152,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>51</integer>
+// CHECK:       <key>line</key><integer>49</integer>
 // CHECK:       <key>col</key><integer>3</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -918,12 +1160,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>line</key><integer>49</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>line</key><integer>49</integer>
 // CHECK:          <key>col</key><integer>4</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -944,7 +1186,7 @@
 // CHECK:   <key>issue_hash</key><integer>8</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>51</integer>
+// CHECK:    <key>line</key><integer>49</integer>
 // CHECK:    <key>col</key><integer>3</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -960,12 +1202,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>line</key><integer>54</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -973,12 +1215,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -994,12 +1236,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1007,12 +1249,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1024,7 +1266,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>57</integer>
+// CHECK:       <key>line</key><integer>55</integer>
 // CHECK:       <key>col</key><integer>7</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -1032,12 +1274,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>line</key><integer>55</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>line</key><integer>55</integer>
 // CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -1057,12 +1299,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>line</key><integer>55</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1070,12 +1312,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1091,12 +1333,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>8</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1104,12 +1346,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>line</key><integer>57</integer>
 // CHECK:            <key>col</key><integer>10</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1121,7 +1363,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>59</integer>
+// CHECK:       <key>line</key><integer>57</integer>
 // CHECK:       <key>col</key><integer>10</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -1129,12 +1371,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>line</key><integer>57</integer>
 // CHECK:          <key>col</key><integer>11</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>line</key><integer>57</integer>
 // CHECK:          <key>col</key><integer>11</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -1155,7 +1397,7 @@
 // CHECK:   <key>issue_hash</key><integer>4</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>59</integer>
+// CHECK:    <key>line</key><integer>57</integer>
 // CHECK:    <key>col</key><integer>10</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
@@ -1171,12 +1413,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>74</integer>
 // CHECK:            <key>col</key><integer>3</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>74</integer>
 // CHECK:            <key>col</key><integer>4</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1184,12 +1426,12 @@
 // CHECK:         <key>end</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
-// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>75</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1198,6 +1440,35 @@
 // CHECK:       </array>
 // CHECK:     </dict>
 // CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>75</integer>
+// CHECK:       <key>col</key><integer>5</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>75</integer>
+// CHECK:          <key>col</key><integer>5</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>75</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Variable &apos;p&apos; initialized to a null pointer value</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
 // CHECK:      <key>kind</key><string>control</string>
 // CHECK:      <key>edges</key>
 // CHECK:       <array>
@@ -1205,12 +1476,12 @@
 // CHECK:         <key>start</key>
 // CHECK:          <array>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
-// CHECK:            <key>col</key><integer>7</integer>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>line</key><integer>75</integer>
 // CHECK:            <key>col</key><integer>7</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1219,79 +1490,11 @@
 // CHECK:          <array>
 // CHECK:           <dict>
 // CHECK:            <key>line</key><integer>76</integer>
-// CHECK:            <key>col</key><integer>3</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
-// CHECK:            <key>col</key><integer>4</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:          </array>
-// CHECK:        </dict>
-// CHECK:       </array>
-// CHECK:     </dict>
-// CHECK:     <dict>
-// CHECK:      <key>kind</key><string>control</string>
-// CHECK:      <key>edges</key>
-// CHECK:       <array>
-// CHECK:        <dict>
-// CHECK:         <key>start</key>
-// CHECK:          <array>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
-// CHECK:            <key>col</key><integer>3</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>76</integer>
-// CHECK:            <key>col</key><integer>4</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:          </array>
-// CHECK:         <key>end</key>
-// CHECK:          <array>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>77</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
 // CHECK:           <dict>
-// CHECK:            <key>line</key><integer>77</integer>
-// CHECK:            <key>col</key><integer>7</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:          </array>
-// CHECK:        </dict>
-// CHECK:       </array>
-// CHECK:     </dict>
-// CHECK:     <dict>
-// CHECK:      <key>kind</key><string>control</string>
-// CHECK:      <key>edges</key>
-// CHECK:       <array>
-// CHECK:        <dict>
-// CHECK:         <key>start</key>
-// CHECK:          <array>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>77</integer>
-// CHECK:            <key>col</key><integer>5</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>77</integer>
-// CHECK:            <key>col</key><integer>7</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:          </array>
-// CHECK:         <key>end</key>
-// CHECK:          <array>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>78</integer>
-// CHECK:            <key>col</key><integer>5</integer>
-// CHECK:            <key>file</key><integer>0</integer>
-// CHECK:           </dict>
-// CHECK:           <dict>
-// CHECK:            <key>line</key><integer>78</integer>
+// CHECK:            <key>line</key><integer>76</integer>
 // CHECK:            <key>col</key><integer>5</integer>
 // CHECK:            <key>file</key><integer>0</integer>
 // CHECK:           </dict>
@@ -1303,7 +1506,7 @@
 // CHECK:      <key>kind</key><string>event</string>
 // CHECK:      <key>location</key>
 // CHECK:      <dict>
-// CHECK:       <key>line</key><integer>78</integer>
+// CHECK:       <key>line</key><integer>76</integer>
 // CHECK:       <key>col</key><integer>5</integer>
 // CHECK:       <key>file</key><integer>0</integer>
 // CHECK:      </dict>
@@ -1311,12 +1514,12 @@
 // CHECK:      <array>
 // CHECK:        <array>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>78</integer>
+// CHECK:          <key>line</key><integer>76</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:         <dict>
-// CHECK:          <key>line</key><integer>78</integer>
+// CHECK:          <key>line</key><integer>76</integer>
 // CHECK:          <key>col</key><integer>6</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
@@ -1337,7 +1540,7 @@
 // CHECK:   <key>issue_hash</key><integer>3</integer>
 // CHECK:   <key>location</key>
 // CHECK:   <dict>
-// CHECK:    <key>line</key><integer>78</integer>
+// CHECK:    <key>line</key><integer>76</integer>
 // CHECK:    <key>col</key><integer>5</integer>
 // CHECK:    <key>file</key><integer>0</integer>
 // CHECK:   </dict>
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index 6567000..884ae5b 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -36,7 +36,7 @@
 
 void f3() {
   int x, y;
-  int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result.}}
+  int d = &y - &x; // expected-warning{{Subtraction of two pointers that do not point to the same memory chunk may cause incorrect result}}
 
   int a[10];
   int *p = &a[2];
@@ -46,13 +46,13 @@
 
 void f4() {
   int *p;
-  p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms.}}
+  p = (int*) 0x10000; // expected-warning{{Using a fixed address is not portable because that address will probably not be valid in all environments or platforms}}
 }
 
 void f5() {
   int x, y;
   int *p;
-  p = &x + 1;  // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous.}}
+  p = &x + 1;  // expected-warning{{Pointer arithmetic done on non-array variables means reliance on memory layout, which is dangerous}}
 
   int a[10];
   p = a + 1; // no-warning
diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m
index aff713b..1d3a9b7 100644
--- a/test/Analysis/refcnt_naming.m
+++ b/test/Analysis/refcnt_naming.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,experimental.core -analyzer-ipa=none -analyzer-store=region -verify %s
 
 typedef const struct __CFString * CFStringRef;
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index e80952b..f9a7e66 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=basic -verify -Wno-null-dereference %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.core,debug.ExprInspection -analyzer-store=region -analyzer-constraints=range -verify -Wno-null-dereference %s
+
+void clang_analyzer_eval(bool);
 
 typedef typeof(sizeof(int)) size_t;
 void malloc (size_t);
@@ -55,3 +58,94 @@
   if (*p) return *p;
   return *(char*)0; // no-warning
 }
+
+
+// PR13440 / <rdar://problem/11977113>
+// Test that the array-to-pointer decay works for array references as well.
+// More generally, when we want an lvalue for a reference field, we still need
+// to do one level of load.
+namespace PR13440 {
+  typedef int T[1];
+  struct S {
+    T &x;
+
+    int *m() { return x; }
+  };
+
+  struct S2 {
+    int (&x)[1];
+
+    int *m() { return x; }
+  };
+
+  void test() {
+    int a[1];
+    S s = { a };
+    S2 s2 = { a };
+
+    if (s.x != a) return;
+    if (s2.x != a) return;
+
+    a[0] = 42;
+    clang_analyzer_eval(s.x[0] == 42); // expected-warning{{TRUE}}
+    clang_analyzer_eval(s2.x[0] == 42); // expected-warning{{TRUE}}
+  }
+}
+
+void testNullReference() {
+  int *x = 0;
+  int &y = *x; // expected-warning{{Dereference of null pointer}}
+  y = 5;
+}
+
+void testRetroactiveNullReference(int *x) {
+  // According to the C++ standard, there is no such thing as a
+  // "null reference". So the 'if' statement ought to be dead code.
+  // However, Clang (and other compilers) don't actually check that a pointer
+  // value is non-null in the implementation of references, so it is possible
+  // to produce a supposed "null reference" at runtime. The analyzer shoeuld
+  // still warn when it can prove such errors.
+  int &y = *x;
+  if (x != 0)
+    return;
+  y = 5; // expected-warning{{Dereference of null pointer}}
+}
+
+void testReferenceAddress(int &x) {
+  clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
+
+  struct S { int &x; };
+
+  extern S *getS();
+  clang_analyzer_eval(&getS()->x != 0); // expected-warning{{TRUE}}
+
+  // This actually takes a different path, because it's not a BinaryOperator.
+  clang_analyzer_eval(&getS()->x); // expected-warning{{TRUE}}
+}
+
+
+// ------------------------------------
+// False negatives
+// ------------------------------------
+
+namespace rdar11212286 {
+  class B{};
+
+  B test() {
+    B *x = 0;
+    return *x; // should warn here!
+  }
+
+  B &testRef() {
+    B *x = 0;
+    return *x; // should warn here!
+  }
+}
+
+void testReferenceFieldAddress() {
+  struct S { int &x; };
+
+  extern S getS();
+  clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/reinterpret-cast.cpp b/test/Analysis/reinterpret-cast.cpp
new file mode 100644
index 0000000..73f2e2d
--- /dev/null
+++ b/test/Analysis/reinterpret-cast.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify %s
+
+void clang_analyzer_eval(bool);
+
+typedef struct Opaque *Data;
+struct IntWrapper {
+  int x;
+};
+
+struct Child : public IntWrapper {
+  void set() { x = 42; }
+};
+
+void test(Data data) {
+  Child *wrapper = reinterpret_cast<Child*>(data);
+  // Don't crash when upcasting here.
+  // We don't actually know if 'data' is a Child.
+  wrapper->set();
+  clang_analyzer_eval(wrapper->x == 42); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m
index 0340a3c..1a5ed34 100644
--- a/test/Analysis/retain-release-gc-only.m
+++ b/test/Analysis/retain-release-gc-only.m
@@ -107,9 +107,14 @@
 @end  @interface NSNumber : NSValue  - (char)charValue;
 - (id)initWithInt:(int)value;
 @end   @class NSString;
-@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
-@end  @interface NSArray (NSArrayCreation)  + (id)array;
-@end       @interface NSAutoreleasePool : NSObject {
+@interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>
+- (NSUInteger)count;
+@end
+@interface NSArray (NSArrayCreation)
++ (id)array;
++ (id)arrayWithObjects:(const id [])objects count:(NSUInteger)cnt;
+@end
+       @interface NSAutoreleasePool : NSObject {
 }
 - (void)drain;
 - (id)init;
@@ -385,3 +390,45 @@
   return (NSDate*) returnsRetainedCFDate(); // expected-warning{{leak}}
 }
 @end
+
+
+#if __has_feature(attribute_ns_consumed)
+#define NS_CONSUMED __attribute__((ns_consumed))
+#endif
+#if __has_feature(attribute_cf_consumed)
+#define CF_CONSUMED __attribute__((cf_consumed))
+#endif
+
+void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void));
+void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void));
+
+void testConsumeAndStopTracking() {
+  id retained = [@[] retain]; // +0, GC
+  consumeAndStopTracking(retained, ^{}); // no-warning
+
+  id doubleRetained = [[@[] retain] retain]; // +0, GC
+  consumeAndStopTracking(doubleRetained, ^{
+    [doubleRetained release];
+  }); // no-warning
+
+  id unretained = @[]; // +0
+  consumeAndStopTracking(unretained, ^{}); // no-warning, GC
+}
+
+void testCFConsumeAndStopTrackingMsg() {
+  id retained = [@[] retain]; // +0, GC
+  CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+}
+
+void testCFConsumeAndStopTracking() {
+  CFTypeRef retained = returnsRetainedCFDate(); // +1
+  CFConsumeAndStopTracking(retained, ^{}); // no-warning
+
+  CFTypeRef doubleRetained = CFRetain(returnsRetainedCFDate()); // +2
+  CFConsumeAndStopTracking(doubleRetained, ^{
+    CFRelease(doubleRetained);
+  }); // no-warning
+
+  id unretained = @[]; // +0
+  CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+}
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 610df7f..a06b353 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -analyzer-ipa=inlining -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from Mac OS X headers:
diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m
index 1e74f00..feee525 100644
--- a/test/Analysis/retain-release-path-notes-gc.m
+++ b/test/Analysis/retain-release-path-notes-gc.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -fobjc-gc-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=text -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=plist-multi-file %s -o - | FileCheck %s
 
 /***
 This file is for testing the path-sensitive notes for retain/release errors.
@@ -71,3 +72,1339 @@
 }
 @end
 
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK:  <key>files</key>
+// CHECK:  <array>
+// CHECK:   <string>{{.*}}retain-release-path-notes-gc.m</string>
+// CHECK:  </array>
+// CHECK:  <key>diagnostics</key>
+// CHECK:  <array>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>42</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>42</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>42</integer>
+// CHECK:          <key>col</key><integer>40</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>42</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>43</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>43</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>43</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>43</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak of object when using garbage collection</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>creationViaCFCreate</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>43</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>47</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>47</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>47</integer>
+// CHECK:          <key>col</key><integer>40</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>47</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>48</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>48</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>48</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>48</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>48</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>48</integer>
+// CHECK:          <key>col</key><integer>12</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>48</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>48</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>48</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>49</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>49</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>49</integer>
+// CHECK:          <key>col</key><integer>27</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>49</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>49</integer>
+// CHECK:          <key>col</key><integer>26</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>In GC mode a call to &apos;CFMakeCollectable&apos; decrements an object&apos;s retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>In GC mode a call to &apos;CFMakeCollectable&apos; decrements an object&apos;s retain count and registers the object with the garbage collector. An object must have a 0 retain count to be garbage collected. After this call its retain count is +1</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>49</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>50</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>27</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>26</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>In GC mode a call to &apos;NSMakeCollectable&apos; decrements an object&apos;s retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>In GC mode a call to &apos;NSMakeCollectable&apos; decrements an object&apos;s retain count and registers the object with the garbage collector. Since it now has a 0 retain count the object can be automatically collected by the garbage collector</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>51</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>col</key><integer>12</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count incremented. The object now has a +1 retain count. The object is not eligible for garbage collection until the retain count reaches 0 again</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>52</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>52</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>52</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>52</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak of object when using garbage collection</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>makeCollectable</string>
+// CHECK:   <key>issue_hash</key><integer>6</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>52</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>56</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>57</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>In GC mode the &apos;retain&apos; message has no effect</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>In GC mode the &apos;retain&apos; message has no effect</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>58</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>In GC mode the &apos;release&apos; message has no effect</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>In GC mode the &apos;release&apos; message has no effect</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>59</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>In GC mode an &apos;autorelease&apos; has no effect</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>In GC mode an &apos;autorelease&apos; has no effect</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>60</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>60</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>60</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>60</integer>
+// CHECK:          <key>col</key><integer>13</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>60</integer>
+// CHECK:          <key>col</key><integer>29</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Bad release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>retainReleaseIgnored</string>
+// CHECK:   <key>issue_hash</key><integer>5</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>60</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>20</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>36</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>65</integer>
+// CHECK:       <key>col</key><integer>20</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>65</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>65</integer>
+// CHECK:          <key>col</key><integer>38</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>20</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>36</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>66</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>66</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>66</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>66</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>66</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>66</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>66</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>66</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>66</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>66</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;getViolation&apos; is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;getViolation&apos; is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;object&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak of returned object when using garbage collection</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>getViolation</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>66</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>20</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>36</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>70</integer>
+// CHECK:       <key>col</key><integer>20</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>70</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>70</integer>
+// CHECK:          <key>col</key><integer>38</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count.  Core Foundation objects are not automatically garbage collected</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>20</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>36</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>71</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>71</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>71</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>71</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;copyViolation&apos; is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;object&apos; and returned from method &apos;copyViolation&apos; is potentially leaked when using garbage collection.  Callers of this method do not expect a returned object with a +1 retain count since they expect the object to be managed by the garbage collector</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak (when using garbage collection) of an object stored into &apos;object&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak of returned object when using garbage collection</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>copyViolation</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>71</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:  </array>
+// CHECK: </dict>
+// CHECK: </plist>
diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m
index 5b70221..ebcfd6a 100644
--- a/test/Analysis/retain-release-path-notes.m
+++ b/test/Analysis/retain-release-path-notes.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
+// RN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file %s -o - | FileCheck %s
 
 /***
 This file is for testing the path-sensitive notes for retain/release errors.
@@ -187,3 +188,4426 @@
   id result = @{key: value}; // expected-note{{NSDictionary literal is an object with a +0 retain count}}
   [result release]; // expected-warning{{decrement}} expected-note{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
 }
+
+
+// CHECK: <?xml version="1.0" encoding="UTF-8"?>
+// CHECK: <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+// CHECK: <plist version="1.0">
+// CHECK: <dict>
+// CHECK:  <key>files</key>
+// CHECK:  <array>
+// CHECK:   <string>{{.*}}retain-release-path-notes.m</string>
+// CHECK:  </array>
+// CHECK:  <key>diagnostics</key>
+// CHECK:  <array>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>45</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>45</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>45</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>46</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>46</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>46</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>46</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>creationViaAlloc</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>46</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>50</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>50</integer>
+// CHECK:          <key>col</key><integer>40</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>50</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>51</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>51</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>51</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>creationViaCFCreate</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>51</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>55</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>55</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>55</integer>
+// CHECK:          <key>col</key><integer>35</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>55</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>56</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>56</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>56</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>57</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>57</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count incremented. The object now has a +2 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>57</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>58</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>58</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count decremented. The object now has a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count decremented. The object now has a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>58</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>59</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>59</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>59</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>acquisitionViaMethod</string>
+// CHECK:   <key>issue_hash</key><integer>5</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>59</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>63</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>63</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>63</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>63</integer>
+// CHECK:            <key>col</key><integer>31</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>63</integer>
+// CHECK:       <key>col</key><integer>19</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>63</integer>
+// CHECK:          <key>col</key><integer>19</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>63</integer>
+// CHECK:          <key>col</key><integer>31</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Property returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>63</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>63</integer>
+// CHECK:            <key>col</key><integer>31</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>64</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>64</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>64</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>65</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>65</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>65</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>65</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>acquisitionViaProperty</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>65</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>69</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>69</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>69</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>69</integer>
+// CHECK:            <key>col</key><integer>35</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>69</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>69</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>69</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>69</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>69</integer>
+// CHECK:            <key>col</key><integer>35</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>70</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>70</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>70</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>70</integer>
+// CHECK:          <key>col</key><integer>12</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>70</integer>
+// CHECK:          <key>col</key><integer>17</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference count incremented. The object now has a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>70</integer>
+// CHECK:            <key>col</key><integer>10</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>71</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>71</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>71</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>71</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>acquisitionViaCFFunction</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>71</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>75</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>75</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>75</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>75</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>76</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>76</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>76</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>76</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>76</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object released by directly sending the &apos;-dealloc&apos; message</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object released by directly sending the &apos;-dealloc&apos; message</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>76</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>77</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>77</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>77</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>77</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>77</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference-counted object is used after it is released</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference-counted object is used after it is released</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Reference-counted object is used after it is released</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Use-after-release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>explicitDealloc</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>77</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>81</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>81</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>81</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>81</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>81</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>81</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>81</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>81</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>81</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>82</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>82</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>82</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>82</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>82</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>82</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>82</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object released</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object released</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>82</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>82</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>83</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>83</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>83</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>83</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>83</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Reference-counted object is used after it is released</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Reference-counted object is used after it is released</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Reference-counted object is used after it is released</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Use-after-release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>implicitDealloc</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>83</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>87</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>87</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>87</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>87</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>87</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>87</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>87</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>87</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>87</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>88</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>88</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>88</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>88</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>88</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>88</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>88</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object sent -autorelease message</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object sent -autorelease message</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>88</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>88</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>89</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>89</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>89</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>89</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>89</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>89</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>89</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object sent -autorelease message</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object sent -autorelease message</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>89</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>89</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>90</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>90</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>90</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>90</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>90</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object over-autoreleased: object was sent -autorelease 2 times but the object has a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>overAutorelease</string>
+// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>90</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>col</key><integer>31</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>94</integer>
+// CHECK:       <key>col</key><integer>19</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>94</integer>
+// CHECK:          <key>col</key><integer>19</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>94</integer>
+// CHECK:          <key>col</key><integer>31</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Property returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>94</integer>
+// CHECK:            <key>col</key><integer>31</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>95</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>95</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>95</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>95</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>95</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>95</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>95</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object sent -autorelease message</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object sent -autorelease message</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>95</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>95</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>96</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>96</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>96</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>96</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>96</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object over-autoreleased: object was sent -autorelease but the object has a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object sent -autorelease too many times</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Object sent -autorelease too many times</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>autoreleaseUnowned</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>96</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>100</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>100</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>100</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>100</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>100</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>100</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>100</integer>
+// CHECK:          <key>col</key><integer>40</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>100</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>100</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>101</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>101</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>101</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>101</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>101</integer>
+// CHECK:          <key>col</key><integer>27</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>101</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>101</integer>
+// CHECK:          <key>col</key><integer>26</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>When GC is not enabled a call to &apos;CFMakeCollectable&apos; has no effect on its argument</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>When GC is not enabled a call to &apos;CFMakeCollectable&apos; has no effect on its argument</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>101</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>101</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>102</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>102</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>102</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>102</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>102</integer>
+// CHECK:          <key>col</key><integer>27</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>102</integer>
+// CHECK:          <key>col</key><integer>21</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>102</integer>
+// CHECK:          <key>col</key><integer>26</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>When GC is not enabled a call to &apos;NSMakeCollectable&apos; has no effect on its argument</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>When GC is not enabled a call to &apos;NSMakeCollectable&apos; has no effect on its argument</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>102</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>102</integer>
+// CHECK:            <key>col</key><integer>19</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>103</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>103</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>103</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>103</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>103</integer>
+// CHECK:          <key>col</key><integer>8</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;leaked&apos; is not referenced later in this execution path and has a retain count of +1</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;leaked&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>makeCollectableIgnored</string>
+// CHECK:   <key>issue_hash</key><integer>4</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>103</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>107</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>107</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>107</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>107</integer>
+// CHECK:            <key>col</key><integer>35</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>107</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>107</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>107</integer>
+// CHECK:          <key>col</key><integer>37</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFGetSomething&apos; returns a Core Foundation object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>107</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>107</integer>
+// CHECK:            <key>col</key><integer>35</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>108</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>108</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>108</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>108</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>108</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>108</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>108</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>108</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>108</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>108</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Method should return an owned object</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>CFCopyRuleViolation</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>108</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>112</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>112</integer>
+// CHECK:            <key>col</key><integer>11</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>112</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>112</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>112</integer>
+// CHECK:       <key>col</key><integer>22</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>112</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>112</integer>
+// CHECK:          <key>col</key><integer>40</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Call to function &apos;CFCreateSomething&apos; returns a Core Foundation object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>112</integer>
+// CHECK:            <key>col</key><integer>22</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>112</integer>
+// CHECK:            <key>col</key><integer>38</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>113</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>113</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>113</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>113</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>113</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>113</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>113</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>113</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>113</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>113</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;object&apos; is returned from a function whose name (&apos;CFGetRuleViolation&apos;) does not contain &apos;Copy&apos; or &apos;Create&apos;.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;object&apos; is returned from a function whose name (&apos;CFGetRuleViolation&apos;) does not contain &apos;Copy&apos; or &apos;Create&apos;.  This violates the naming convention rules given in the Memory Management Guide for Core Foundation</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;object&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak of returned object</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>CFGetRuleViolation</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>113</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>118</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>118</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>118</integer>
+// CHECK:            <key>col</key><integer>20</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>118</integer>
+// CHECK:            <key>col</key><integer>32</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>118</integer>
+// CHECK:       <key>col</key><integer>20</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>118</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>118</integer>
+// CHECK:          <key>col</key><integer>32</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Property returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Property returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>118</integer>
+// CHECK:            <key>col</key><integer>20</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>118</integer>
+// CHECK:            <key>col</key><integer>32</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>119</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>119</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>119</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>119</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>119</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>119</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>119</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>119</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>119</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>119</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Method should return an owned object</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>copyViolation</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>119</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>123</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>123</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>123</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>123</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>123</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>123</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>123</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Subscript returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Subscript returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>123</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>123</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>124</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>124</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>124</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>124</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>124</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>124</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>124</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>124</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>124</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>124</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Method should return an owned object</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>copyViolationIndexedSubscript</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>124</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>128</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>128</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>128</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>128</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>128</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>128</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>128</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Subscript returns an Objective-C object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Subscript returns an Objective-C object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>128</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>128</integer>
+// CHECK:            <key>col</key><integer>18</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>129</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>129</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>129</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>129</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>129</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>129</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>129</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>129</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>129</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>129</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Method should return an owned object</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>copyViolationKeyedSubscript</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>129</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>133</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>133</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>133</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>133</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>133</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>133</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>133</integer>
+// CHECK:          <key>col</key><integer>32</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>133</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>133</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>134</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>134</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>134</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>134</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>134</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>134</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>134</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller as an owning reference (single retain count transferred to caller)</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>134</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>134</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>134</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object leaked: object allocated and stored into &apos;result&apos; is returned from a method whose name (&apos;getViolation&apos;) does not start with &apos;copy&apos;, &apos;mutableCopy&apos;, &apos;alloc&apos; or &apos;new&apos;.  This violates the naming convention rules given in the Memory Management Guide for Cocoa</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object leaked: object allocated and stored into &apos;result&apos; is returned from a method whose name (&apos;getViolation&apos;) does not start with &apos;copy&apos;, &apos;mutableCopy&apos;, &apos;alloc&apos; or &apos;new&apos;.  This violates the naming convention rules given in the Memory Management Guide for Cocoa</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Potential leak of an object stored into &apos;result&apos;</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Leak of returned object</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>getViolation</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>134</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>138</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>138</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>138</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>138</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>138</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>138</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>138</integer>
+// CHECK:          <key>col</key><integer>32</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Method returns an Objective-C object with a +1 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>138</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>138</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>139</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>139</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>139</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>139</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>139</integer>
+// CHECK:          <key>col</key><integer>22</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>139</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>139</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object sent -autorelease message</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object sent -autorelease message</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>139</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>139</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>140</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>140</integer>
+// CHECK:            <key>col</key><integer>8</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>140</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>140</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>140</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>140</integer>
+// CHECK:          <key>col</key><integer>10</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>140</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object returned to caller with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object returned to caller with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>140</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>140</integer>
+// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>140</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Method should return an owned object</string>
+// CHECK:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK:   <key>issue_context</key><string>copyAutorelease</string>
+// CHECK:   <key>issue_hash</key><integer>3</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>140</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>168</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>168</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>168</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>168</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>168</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>168</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>168</integer>
+// CHECK:          <key>col</key><integer>16</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>NSNumber literal is an object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>NSNumber literal is an object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>168</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>168</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>169</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>169</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>169</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>169</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>169</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Bad release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testNumericLiteral</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>169</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>173</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>173</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>173</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>173</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>173</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>173</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>173</integer>
+// CHECK:          <key>col</key><integer>18</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>NSNumber boxed expression produces an object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>NSNumber boxed expression produces an object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>173</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>173</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>174</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>174</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>174</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>174</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>174</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Bad release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testBoxedInt</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>174</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>178</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>178</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>178</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>178</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>178</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>178</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>178</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>NSString boxed expression produces an object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>NSString boxed expression produces an object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>178</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>178</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>179</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>179</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>179</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>179</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>179</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Bad release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testBoxedString</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>179</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>183</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>183</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>183</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>183</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>183</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>183</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>183</integer>
+// CHECK:          <key>col</key><integer>20</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>NSArray literal is an object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>NSArray literal is an object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>183</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>183</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>184</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>184</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>184</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>184</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>184</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Bad release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testArray</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>184</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:   <dict>
+// CHECK:    <key>path</key>
+// CHECK:    <array>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>188</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>188</integer>
+// CHECK:            <key>col</key><integer>4</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>188</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>188</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>188</integer>
+// CHECK:       <key>col</key><integer>15</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>188</integer>
+// CHECK:          <key>col</key><integer>15</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>188</integer>
+// CHECK:          <key>col</key><integer>27</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>NSDictionary literal is an object with a +0 retain count</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>NSDictionary literal is an object with a +0 retain count</string>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>control</string>
+// CHECK:      <key>edges</key>
+// CHECK:       <array>
+// CHECK:        <dict>
+// CHECK:         <key>start</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>188</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>188</integer>
+// CHECK:            <key>col</key><integer>15</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:         <key>end</key>
+// CHECK:          <array>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>189</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:           <dict>
+// CHECK:            <key>line</key><integer>189</integer>
+// CHECK:            <key>col</key><integer>3</integer>
+// CHECK:            <key>file</key><integer>0</integer>
+// CHECK:           </dict>
+// CHECK:          </array>
+// CHECK:        </dict>
+// CHECK:       </array>
+// CHECK:     </dict>
+// CHECK:     <dict>
+// CHECK:      <key>kind</key><string>event</string>
+// CHECK:      <key>location</key>
+// CHECK:      <dict>
+// CHECK:       <key>line</key><integer>189</integer>
+// CHECK:       <key>col</key><integer>3</integer>
+// CHECK:       <key>file</key><integer>0</integer>
+// CHECK:      </dict>
+// CHECK:      <key>ranges</key>
+// CHECK:      <array>
+// CHECK:        <array>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>189</integer>
+// CHECK:          <key>col</key><integer>4</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:         <dict>
+// CHECK:          <key>line</key><integer>189</integer>
+// CHECK:          <key>col</key><integer>9</integer>
+// CHECK:          <key>file</key><integer>0</integer>
+// CHECK:         </dict>
+// CHECK:        </array>
+// CHECK:      </array>
+// CHECK:      <key>depth</key><integer>0</integer>
+// CHECK:      <key>extended_message</key>
+// CHECK:      <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:      <key>message</key>
+// CHECK: <string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:     </dict>
+// CHECK:    </array>
+// CHECK:    <key>description</key><string>Incorrect decrement of the reference count of an object that is not owned at this point by the caller</string>
+// CHECK:    <key>category</key><string>Memory (Core Foundation/Objective-C)</string>
+// CHECK:    <key>type</key><string>Bad release</string>
+// CHECK:   <key>issue_context_kind</key><string>function</string>
+// CHECK:   <key>issue_context</key><string>testDictionary</string>
+// CHECK:   <key>issue_hash</key><integer>2</integer>
+// CHECK:   <key>location</key>
+// CHECK:   <dict>
+// CHECK:    <key>line</key><integer>189</integer>
+// CHECK:    <key>col</key><integer>3</integer>
+// CHECK:    <key>file</key><integer>0</integer>
+// CHECK:   </dict>
+// CHECK:   </dict>
+// CHECK:  </array>
+// CHECK: </dict>
+// CHECK: </plist>
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 87e09e9..da1477b 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -300,6 +300,9 @@
 + (id)array;
 @end
 
+// This is how NSMakeCollectable is declared in the OS X 10.8 headers.
+id NSMakeCollectable(CFTypeRef __attribute__((cf_consumed))) __attribute__((ns_returns_retained));
+
 
 //===----------------------------------------------------------------------===//
 // Test cases.
@@ -1745,7 +1748,7 @@
 @end
 //===----------------------------------------------------------------------===//
 // Test returning allocated memory in a struct.
-// 
+//
 // We currently don't have a general way to track pointers that "escape".
 // Here we test that RetainCountChecker doesn't get excited about returning
 // allocated CF objects in struct fields.
@@ -1842,3 +1845,43 @@
     NSLog(@"Again: %@", printString); // expected-warning {{Reference-counted object is used after it is released}}
   }
 }
+
+id makeCollectableNonLeak() {
+  extern CFTypeRef CFCreateSomething();
+
+  CFTypeRef object = CFCreateSomething(); // +1
+  CFRetain(object); // +2
+  id objCObject = NSMakeCollectable(object); // +2
+  [objCObject release]; // +1
+  return [objCObject autorelease]; // +0
+}
+
+
+void consumeAndStopTracking(id NS_CONSUMED obj, void (^callback)(void));
+void CFConsumeAndStopTracking(CFTypeRef CF_CONSUMED obj, void (^callback)(void));
+
+void testConsumeAndStopTracking() {
+  id retained = [@[] retain]; // +1
+  consumeAndStopTracking(retained, ^{}); // no-warning
+
+  id doubleRetained = [[@[] retain] retain]; // +2
+  consumeAndStopTracking(doubleRetained, ^{
+    [doubleRetained release];
+  }); // no-warning
+
+  id unretained = @[]; // +0
+  consumeAndStopTracking(unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+}
+
+void testCFConsumeAndStopTracking() {
+  id retained = [@[] retain]; // +1
+  CFConsumeAndStopTracking((CFTypeRef)retained, ^{}); // no-warning
+
+  id doubleRetained = [[@[] retain] retain]; // +2
+  CFConsumeAndStopTracking((CFTypeRef)doubleRetained, ^{
+    [doubleRetained release];
+  }); // no-warning
+
+  id unretained = @[]; // +0
+  CFConsumeAndStopTracking((CFTypeRef)unretained, ^{}); // expected-warning {{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}}
+}
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
index f4ccefe..1df8a40 100644
--- a/test/Analysis/security-syntax-checks.m
+++ b/test/Analysis/security-syntax-checks.m
@@ -46,7 +46,7 @@
 
 void test_getpw() {
   char buff[1024];
-  getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid().}}
+  getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid()}}
 }
 
 // <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
@@ -138,7 +138,7 @@
   char x[4];
   char *y;
 
-  strcpy(x, y); //expected-warning{{Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119.}}
+  strcpy(x, y); //expected-warning{{Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119}}
 }
 
 //===----------------------------------------------------------------------===
@@ -162,7 +162,7 @@
   char x[4];
   char *y;
 
-  strcat(x, y); //expected-warning{{Call to function 'strcat' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcat'. CWE-119.}}
+  strcat(x, y); //expected-warning{{Call to function 'strcat' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcat'. CWE-119}}
 }
 
 //===----------------------------------------------------------------------===
@@ -173,7 +173,7 @@
 pid_t vfork(void);
 
 void test_vfork() {
-  vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process.}}
+  vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process}}
 }
 
 //===----------------------------------------------------------------------===
diff --git a/test/Analysis/self-init.m b/test/Analysis/self-init.m
index 10b0c4d..b0c51a2 100644
--- a/test/Analysis/self-init.m
+++ b/test/Analysis/self-init.m
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -analyzer-ipa=dynamic -fno-builtin %s -verify
 // RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fobjc-default-synthesize-properties -fno-builtin %s -verify
 
 @class NSZone, NSCoder;
diff --git a/test/Analysis/sizeofpointer.c b/test/Analysis/sizeofpointer.c
index 0c86de8..aa85fc0 100644
--- a/test/Analysis/sizeofpointer.c
+++ b/test/Analysis/sizeofpointer.c
@@ -4,5 +4,5 @@
 };
 
 int f(struct s *p) {
-  return sizeof(p); // expected-warning{{The code calls sizeof() on a pointer type. This can produce an unexpected result.}}
+  return sizeof(p); // expected-warning{{The code calls sizeof() on a pointer type. This can produce an unexpected result}}
 }
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index b21a03d..a27bef7 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -87,6 +87,6 @@
 
 // rdar://11345441
 int* f5() {
-  int& i = i; // expected-warning {{Assigned value is garbage or undefined}} expected-note {{binding reference variable 'i' here}}
+  int& i = i; // expected-warning {{Assigned value is garbage or undefined}} expected-note {{binding reference variable 'i' here}} expected-warning{{reference 'i' is not yet bound to a value when used within its own initialization}}
   return &i; // expected-warning {{address of stack memory associated with local variable 'i' returned}}
 }
diff --git a/test/Analysis/stream.c b/test/Analysis/stream.c
index e68835e..4a095cf 100644
--- a/test/Analysis/stream.c
+++ b/test/Analysis/stream.c
@@ -16,25 +16,25 @@
 void f1(void) {
   FILE *p = fopen("foo", "r");
   char buf[1024];
-  fread(buf, 1, 1, p); // expected-warning {{Stream pointer might be NULL.}}
+  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.}}
+  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.}}
+  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.}}
+  rewind(p); // expected-warning {{Stream pointer might be NULL}}
   fclose(p);
 }
 
@@ -43,26 +43,26 @@
   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.}}
+  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.}}
+  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.}}
+  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.}}
+    return; // expected-warning {{Opened File never closed. Potential Resource leak}}
   fclose(p);
 }
 
diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp
index 1a1b132..6dbbc82 100644
--- a/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -1,5 +1,5 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors -cfg-add-initializers %s > %t 2>&1
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -cfg-add-implicit-dtors %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 // XPASS: *
 
diff --git a/test/Analysis/templates.cpp b/test/Analysis/templates.cpp
index 6add18c..671aa78 100644
--- a/test/Analysis/templates.cpp
+++ b/test/Analysis/templates.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -fblocks -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
+
+void clang_analyzer_eval(bool);
 
 // Do not crash on this templated code which uses a block.
 typedef void (^my_block)(void);
@@ -27,3 +29,16 @@
   Mf m;
   m.I();
 }
+
+
+// <rdar://problem/11949235>
+template<class T, unsigned N>
+inline unsigned array_lengthof(T (&)[N]) {
+  return N;
+}
+
+void testNonTypeTemplateInstantiation() {
+  const char *S[] = { "a", "b" };
+  clang_analyzer_eval(array_lengthof(S) == 2); // expected-warning{{TRUE}}
+}
+
diff --git a/test/Analysis/variadic-method-types.m b/test/Analysis/variadic-method-types.m
index 4d0f6bc..9f90e5f 100644
--- a/test/Analysis/variadic-method-types.m
+++ b/test/Analysis/variadic-method-types.m
@@ -74,7 +74,7 @@
   [NSArray arrayWithObjects:@"Hello", a, b, c, d, nil];
   [NSArray arrayWithObjects:@"Foo", ^{}, nil];
 
-  [NSArray arrayWithObjects:@"Foo", "Bar", "Baz", nil]; // expected-warning 2 {{Argument to 'NSArray' method 'arrayWithObjects:' should be an Objective-C pointer type, not 'char *'}}
+  [NSArray arrayWithObjects:@"Foo", "Bar", "Baz", nil]; // expected-warning {{Argument to 'NSArray' method 'arrayWithObjects:' should be an Objective-C pointer type, not 'char *'}}
   [NSDictionary dictionaryWithObjectsAndKeys:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSDictionary' method 'dictionaryWithObjectsAndKeys:' should be an Objective-C pointer type, not 'char *'}}
   [NSSet setWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSSet' method 'setWithObjects:' should be an Objective-C pointer type, not 'char *'}}
   [NSOrderedSet orderedSetWithObjects:@"Foo", "Bar", nil]; // expected-warning {{Argument to 'NSOrderedSet' method 'orderedSetWithObjects:' should be an Objective-C pointer type, not 'char *'}}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 86f0be5..8184c3d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -31,7 +31,7 @@
   set(CLANG_TEST_DEPS
     clang clang-headers
     c-index-test diagtool arcmt-test c-arcmt-test
-    clang-check clang-ast-dump
+    clang-check
     llvm-dis llc opt FileCheck count not
     )
   set(CLANG_TEST_PARAMS
@@ -80,7 +80,7 @@
       COMMENT "Running Clang regression tests"
       DEPENDS clang clang-headers
               c-index-test diagtool arcmt-test c-arcmt-test
-              clang-check clang-ast-dump
+              clang-check
       )
     set_target_properties(check-clang PROPERTIES FOLDER "Clang tests")
   endif()
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index 68ff83f..7cb192b 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -64,6 +64,7 @@
   };
 
   class MemberFriend {
+  public:
     void test();
   };
 
@@ -309,6 +310,7 @@
 // PR8705
 namespace test11 {
   class A {
+  public:
     void test0(int);
     void test1(int);
     void test2(int);
diff --git a/test/CXX/class.access/class.friend/p9-cxx0x.cpp b/test/CXX/class.access/class.friend/p9-cxx0x.cpp
new file mode 100644
index 0000000..f748a2b
--- /dev/null
+++ b/test/CXX/class.access/class.friend/p9-cxx0x.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++98 [class.friend]p7:
+// C++11 [class.friend]p9:
+//   A name nominated by a friend declaration shall be accessible in
+//   the scope of the class containing the friend declaration.
+
+// PR12328
+// Simple, non-templated case.
+namespace test0 {
+  class X {
+    void f(); // expected-note {{implicitly declared private here}}
+  };
+
+  class Y {
+    friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test0::X'}}
+  };
+}
+
+// Templated but non-dependent.
+namespace test1 {
+  class X {
+    void f(); // expected-note {{implicitly declared private here}}
+  };
+
+  template <class T> class Y {
+    friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test1::X'}}
+  };
+}
+
+// Dependent but instantiated at the right type.
+namespace test2 {
+  template <class T> class Y;
+
+  class X {
+    void f();
+    friend class Y<int>;
+  };
+
+  template <class T> class Y {
+    friend void X::f();
+  };
+
+  template class Y<int>;
+}
+
+// Dependent and instantiated at the wrong type.
+namespace test3 {
+  template <class T> class Y;
+
+  class X {
+    void f(); // expected-note {{implicitly declared private here}}
+    friend class Y<int>;
+  };
+
+  template <class T> class Y {
+    friend void X::f(); // expected-error {{friend function 'f' is a private member of 'test3::X'}}
+  };
+
+  template class Y<float>; // expected-note {{in instantiation}}
+}
+
+// Dependent because dependently-scoped.
+namespace test4 {
+  template <class T> class X {
+    void f();
+  };
+
+  template <class T> class Y {
+    friend void X<T>::f();
+  };
+}
+
+// Dependently-scoped, no friends.
+namespace test5 {
+  template <class T> class X {
+    void f(); // expected-note {{implicitly declared private here}}
+  };
+
+  template <class T> class Y {
+    friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test5::X<int>'}}
+  };
+
+  template class Y<int>; // expected-note {{in instantiation}}
+}
+
+// Dependently-scoped, wrong friend.
+namespace test6 {
+  template <class T> class Y;
+
+  template <class T> class X {
+    void f(); // expected-note {{implicitly declared private here}}
+    friend class Y<float>;
+  };
+
+  template <class T> class Y {
+    friend void X<T>::f(); // expected-error {{friend function 'f' is a private member of 'test6::X<int>'}}
+  };
+
+  template class Y<int>; // expected-note {{in instantiation}}
+}
+
+// Dependently-scoped, right friend.
+namespace test7 {
+  template <class T> class Y;
+
+  template <class T> class X {
+    void f();
+    friend class Y<int>;
+  };
+
+  template <class T> class Y {
+    friend void X<T>::f();
+  };
+
+  template class Y<int>;
+}
diff --git a/test/CXX/class.derived/class.virtual/p3-0x.cpp b/test/CXX/class.derived/class.virtual/p3-0x.cpp
index c4a401b..16f9828 100644
--- a/test/CXX/class.derived/class.virtual/p3-0x.cpp
+++ b/test/CXX/class.derived/class.virtual/p3-0x.cpp
@@ -20,9 +20,15 @@
 
 template<typename T>
 struct B : A {
+  // FIXME: Diagnose this.
   virtual void f(T) override;
 };
 
+template<typename T>
+struct C : A {
+  virtual void f(int) override; // expected-error {{does not override}}
+};
+
 }
 
 namespace Test3 {
@@ -51,3 +57,46 @@
 };
 
 }
+
+namespace PR13499 {
+  struct X {
+    virtual void f();
+    virtual void h();
+  };
+  template<typename T> struct A : X {
+    void f() override;
+    void h() final;
+  };
+  template<typename T> struct B : X {
+    void g() override; // expected-error {{only virtual member functions can be marked 'override'}}
+    void i() final; // expected-error {{only virtual member functions can be marked 'final'}}
+  };
+  B<int> b; // no-note
+  template<typename T> struct C : T {
+    void g() override;
+    void i() final;
+  };
+  template<typename T> struct D : X {
+    virtual void g() override; // expected-error {{does not override}}
+    virtual void i() final;
+  };
+  template<typename...T> struct E : X {
+    void f(T...) override;
+    void g(T...) override; // expected-error {{only virtual member functions can be marked 'override'}}
+    void h(T...) final;
+    void i(T...) final; // expected-error {{only virtual member functions can be marked 'final'}}
+  };
+  // FIXME: Diagnose these in the template definition, not in the instantiation.
+  E<> e; // expected-note {{in instantiation of}}
+
+  template<typename T> struct Y : T {
+    void f() override;
+    void h() final;
+  };
+  template<typename T> struct Z : T {
+    void g() override; // expected-error {{only virtual member functions can be marked 'override'}}
+    void i() final; // expected-error {{only virtual member functions can be marked 'final'}}
+  };
+  Y<X> y;
+  Z<X> z; // expected-note {{in instantiation of}}
+}
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
index f344ae5..ee97410 100644
--- a/test/CXX/class/class.union/p1.cpp
+++ b/test/CXX/class/class.union/p1.cpp
@@ -27,9 +27,8 @@
   CopyCtor(CopyCtor &cc) { abort(); } // expected-note 4 {{because type 'CopyCtor' has a user-declared copy constructor}}
 };
 
-// FIXME: this should eventually trigger on the operator's declaration line
-class CopyAssign { // expected-note 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}}
-  CopyAssign& operator=(CopyAssign& CA) { abort(); }
+class CopyAssign {
+  CopyAssign& operator=(CopyAssign& CA) { abort(); } // expected-note 4 {{because type 'CopyAssign' has a user-declared copy assignment operator}}
 };
 
 class Dtor {
diff --git a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
index a4dffda..783aba1 100644
--- a/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
+++ b/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -27,7 +27,7 @@
 //   -- it is implicitly considered to be constexpr if the implicit declaration
 //      would be
 struct S3 {
-  S3() = default; // expected-note {{here}}
+  S3() = default;
   S3(const S3&) = default;
   S3(S3&&) = default;
   constexpr S3(int n) : n(n) {}
@@ -36,7 +36,7 @@
 constexpr S3 s3a = S3(0);
 constexpr S3 s3b = s3a;
 constexpr S3 s3c = S3();
-constexpr S3 s3d; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+constexpr S3 s3d; // expected-error {{default initialization of an object of const type 'const S3' requires a user-provided default constructor}}
 
 struct S4 {
   S4() = default;
@@ -44,7 +44,7 @@
   S4(S4&&) = default; // expected-note {{here}}
   NoCopyMove ncm;
 };
-constexpr S4 s4a; // ok
+constexpr S4 s4a{}; // ok
 constexpr S4 s4b = S4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
 constexpr S4 s4c = s4a; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
 
@@ -112,3 +112,13 @@
 static_assert(!noexcept(E5(e5)), "");
 static_assert(!noexcept(e5 = E5()), "");
 static_assert(!noexcept(e5 = e5), "");
+
+namespace PR13492 {
+  struct B {
+    B() = default;
+  };
+
+  void f() {
+    const B b; // expected-error {{default initialization of an object of const type 'const PR13492::B' requires a user-provided default constructor}}
+  }
+}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp
index 15efb48..21f71f0 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/dcl.fct.def.default/p1.cpp
@@ -4,9 +4,11 @@
 // [...]
 //   -- not have default arguments
 struct DefArg {
+  static DefArg &&make();
   DefArg(int n = 5) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
-  DefArg(const DefArg &DA = DefArg(2)) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
+  DefArg(const DefArg &DA = make()) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
   DefArg(const DefArg &DA, int k = 3) = default; // expected-error {{an explicitly-defaulted copy constructor cannot have default arguments}}
+  DefArg(DefArg &&DA = make()) = default; // expected-error {{an explicitly-defaulted constructor cannot have default arguments}}
   DefArg(DefArg &&DA, int k = 3) = default; // expected-error {{an explicitly-defaulted move constructor cannot have default arguments}}
   DefArg &operator=(const DefArg&, int k = 4) = default; // expected-error {{parameter of overloaded 'operator=' cannot have a default argument}}
   DefArg &operator=(DefArg&&, int k = 4) = default; // expected-error {{parameter of overloaded 'operator=' cannot have a default argument}}
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index 6a6e0d9..0db2bf5 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -89,6 +89,8 @@
 
 namespace PR13117 {
   struct A {
+    template<typename ... Args> static void f(Args...);
+
     template<typename ... Args> static void f1()
     {
       (void)^(Args args) { // expected-error{{block contains unexpanded parameter pack 'Args'}}
@@ -97,9 +99,24 @@
 
     template<typename ... Args> static void f2()
     {
-      (void)[](Args args) { // expected-error{{lambda contains unexpanded parameter pack 'Args'}}
+      // FIXME: Allow this.
+      f(
+        ^(Args args) // expected-error{{block contains unexpanded parameter pack 'Args'}}
+        { }
+        ... // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
+      );
+    }
+
+    template<typename ... Args> static void f3()
+    {
+      (void)[](Args args) { // expected-error{{expression contains unexpanded parameter pack 'Args'}}
       };
     }
+
+    template<typename ... Args> static void f4()
+    {
+      f([](Args args) { } ...);
+    }
   };
 
   void g() {
diff --git a/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp b/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
index 174db25..82fc04a 100644
--- a/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
+++ b/test/CXX/expr/expr.prim/expr.prim.lambda/p23.cpp
@@ -9,8 +9,8 @@
 }
 
 template<typename... Ts>
-void unsupported(Ts ...values) {
-  auto unsup = [values] {}; // expected-error{{unexpanded function parameter pack capture is unsupported}}
+void unexpanded_capture(Ts ...values) {
+  auto unexp = [values] {}; // expected-error{{initializer contains unexpanded parameter pack 'values'}}
 }
 
 template<typename... Ts>
diff --git a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
index 96bb472..66e30f5 100644
--- a/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
+++ b/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
@@ -3,7 +3,7 @@
 struct pr12960 {
   int begin;
   void foo(int x) {
-    for (int& it : x) { // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type 'int'}}
+    for (int& it : x) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
     }
   }
 };
@@ -116,9 +116,9 @@
   struct NoEndADL {
     null_t alt_begin();
   };
-  for (auto u : NoBeginADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type 'NoBeginADL'}}
+  for (auto u : NoBeginADL()) { // expected-error {{invalid range expression of type 'NoBeginADL'; no viable 'begin' function available}}
   }
-  for (auto u : NoEndADL()) { // expected-error {{no matching function for call to 'end'}} expected-note {{range has type 'NoEndADL'}}
+  for (auto u : NoEndADL()) { // expected-error {{invalid range expression of type 'NoEndADL'; no viable 'end' function available}}
   }
 
   struct NoBegin {
@@ -156,8 +156,7 @@
   for (int n : NoCopy()) { // ok
   }
 
-  for (int n : 42) { // expected-error {{no matching function for call to 'begin'}} \
-                        expected-note {{range has type 'int'}}
+  for (int n : 42) { // expected-error {{invalid range expression of type 'int'; no viable 'begin' function available}}
   }
 
   for (auto a : *also_incomplete) { // expected-error {{cannot use incomplete type 'struct Incomplete' as a range}}
@@ -179,9 +178,10 @@
 
 template<typename T>
 void i(T t) {
-  for (auto u : t) { // expected-error {{no matching function for call to 'begin'}} \
+  for (auto u : t) { // expected-error {{invalid range expression of type 'A *'; no viable 'begin' function available}} \
                         expected-error {{member function 'begin' not viable}} \
-                        expected-note {{range has type}}
+                        expected-note {{when looking up 'begin' function}}
+
   }
 }
 template void i<A[13]>(A*); // expected-note {{requested here}}
@@ -204,9 +204,10 @@
 void j() {
   for (auto u : NS::ADL()) {
   }
-  for (auto u : NS::NoADL()) { // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}}
+  for (auto u : NS::NoADL()) { // expected-error {{invalid range expression of type 'NS::NoADL'; no viable 'begin' function available}}
   }
   for (auto a : VoidBeginADL()) { // expected-error {{cannot use type 'void' as an iterator}}
+
   }
 }
 
@@ -215,4 +216,3 @@
   for (int &x : array)
     x *= 2;
 }
-
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 63f569b..640d03d 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -302,6 +302,7 @@
   };
 
   template <class T> class B {
+  public:
     void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}}
   };
 
@@ -320,10 +321,12 @@
   };
 
   template <class T> class B {
+  public:
     void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}
   };
 
   template <> class B<float> {
+  public:
     void foo() { return A<float>::foo(); }
     template <class U> void bar(U u) {
       (void) A<float>::foo();
diff --git a/test/CodeCompletion/auto.cpp b/test/CodeCompletion/auto.cpp
new file mode 100644
index 0000000..1fc9fb0
--- /dev/null
+++ b/test/CodeCompletion/auto.cpp
@@ -0,0 +1,2 @@
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:2:9 %s
+auto i =
diff --git a/test/CodeCompletion/objc-expr.m b/test/CodeCompletion/objc-expr.m
index b59586a..d3c95a6 100644
--- a/test/CodeCompletion/objc-expr.m
+++ b/test/CodeCompletion/objc-expr.m
@@ -11,7 +11,7 @@
 // CHECK-AT: COMPLETION: Pattern : [#char[]#]encode(<#type-name#>)
 // CHECK-AT: COMPLETION: Pattern : [#Protocol *#]protocol(<#protocol-name#>)
 // CHECK-AT: COMPLETION: Pattern : [#SEL#]selector(<#selector#>)
-// CHECK-AT: COMPLETION: Pattern : [#NSDictionary *#]{<#key#> : <#object, ...#>}
+// CHECK-AT: COMPLETION: Pattern : [#NSDictionary *#]{<#key#>: <#object, ...#>}
 
 // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:4:11 %s -fconst-strings -o - | FileCheck -check-prefix=CONST-STRINGS %s
 // CHECK-CONST-STRINGS: COMPLETION: Pattern : [#const char[]#]encode(<#type-name#>)
diff --git a/test/CodeGen/align-global-large.c b/test/CodeGen/align-global-large.c
new file mode 100644
index 0000000..fcbe758
--- /dev/null
+++ b/test/CodeGen/align-global-large.c
@@ -0,0 +1,18 @@
+// PR13606 - Clang crashes with large alignment attribute
+// RUN: %clang -S -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: x
+// CHECK: align
+// CHECK: 1048576
+volatile char x[4000] __attribute__((aligned(0x100000)));
+
+int
+main (int argc, char ** argv) {
+  // CHECK: y
+  // CHECK: align
+  // CHECK: 1048576
+  volatile char y[4000] __attribute__((aligned(0x100000)));
+
+  return y[argc];
+}
+
diff --git a/test/CodeGen/alignment.c b/test/CodeGen/alignment.c
index 8882c91..98ea01b 100644
--- a/test/CodeGen/alignment.c
+++ b/test/CodeGen/alignment.c
@@ -43,7 +43,8 @@
   *p = (packedfloat3) { 3.2f, 2.3f, 0.1f };
 }
 // CHECK: @test3(
-// CHECK: store <3 x float> {{.*}}, align 4
+// CHECK: %{{.*}} = bitcast <3 x float>* %{{.*}} to <4 x float>*
+// CHECK: store <4 x float> {{.*}}, align 4
 // CHECK: ret void
 
 
diff --git a/test/CodeGen/arm-aapcs-vfp.c b/test/CodeGen/arm-aapcs-vfp.c
index fdd87e0..614b52d 100644
--- a/test/CodeGen/arm-aapcs-vfp.c
+++ b/test/CodeGen/arm-aapcs-vfp.c
@@ -88,3 +88,7 @@
 void test_neon(struct neon_struct arg) {
   neon_callee(arg);
 }
+
+// CHECK: define arm_aapcs_vfpcc void @f33(%struct.s33* byval %s)
+struct s33 { char buf[32*32]; };
+void f33(struct s33 s) { }
diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c
index 1ca9a78..2ec729e 100644
--- a/test/CodeGen/arm-arguments.c
+++ b/test/CodeGen/arm-arguments.c
@@ -166,3 +166,15 @@
 // APCS-GNU: %s = alloca %struct.s31, align 4
 // APCS-GNU: alloca [1 x i32]
 // APCS-GNU: store [1 x i32] %s.coerce, [1 x i32]*
+
+// PR13562
+struct s32 { double x; };
+void f32(struct s32 s) { }
+// AAPCS: @f32([1 x i64] %s.coerce)
+// APCS-GNU: @f32([2 x i32] %s.coerce)
+
+// PR13350
+struct s33 { char buf[32*32]; };
+void f33(struct s33 s) { }
+// APCS-GNU: define void @f33(%struct.s33* byval %s)
+// AAPCS: define arm_aapcscc void @f33(%struct.s33* byval %s)
diff --git a/test/CodeGen/arm-neon-misc.c b/test/CodeGen/arm-neon-misc.c
new file mode 100644
index 0000000..56ce316
--- /dev/null
+++ b/test/CodeGen/arm-neon-misc.c
@@ -0,0 +1,34 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple thumbv7-apple-darwin \
+// RUN:   -target-abi apcs-gnu \
+// RUN:   -target-cpu cortex-a8 \
+// RUN:   -mfloat-abi soft \
+// RUN:   -target-feature +soft-float-abi \
+// RUN:   -ffreestanding \
+// RUN:   -emit-llvm -w -o - %s | FileCheck %s
+
+#include <arm_neon.h>
+
+// Radar 11998303: Avoid using i64 types for vld1q_lane and vst1q_lane Neon
+// intrinsics with <2 x i64> vectors to avoid poor code for i64 in the backend.
+void t1(uint64_t *src, uint8_t *dst) {
+// CHECK: @t1
+  uint64x2_t q = vld1q_u64(src);
+// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64
+  vst1q_lane_u64(dst, q, 1);
+// CHECK: bitcast <16 x i8> %{{.*}} to <2 x i64>
+// CHECK: shufflevector <2 x i64>
+// CHECK: call void @llvm.arm.neon.vst1.v1i64
+}
+
+void t2(uint64_t *src1, uint8_t *src2, uint64x2_t *dst) {
+// CHECK: @t2
+    uint64x2_t q = vld1q_u64(src1);
+// CHECK: call <2 x i64> @llvm.arm.neon.vld1.v2i64
+    q = vld1q_lane_u64(src2, q, 0);
+// CHECK: shufflevector <2 x i64>
+// CHECK: call <1 x i64> @llvm.arm.neon.vld1.v1i64
+// CHECK: shufflevector <1 x i64>
+    *dst = q;
+// CHECK: store <2 x i64>
+}
diff --git a/test/CodeGen/asm.c b/test/CodeGen/asm.c
index 84f26e1..b009736 100644
--- a/test/CodeGen/asm.c
+++ b/test/CodeGen/asm.c
@@ -220,3 +220,13 @@
 void t26 (__m256i *p) {
   __asm__ volatile("vmovaps  %0, %%ymm0" :: "m" (*(__m256i*)p) : "ymm0");
 }
+
+// Check to make sure the inline asm non-standard dialect attribute _not_ is
+// emitted.
+void t27(void) {
+  asm volatile("nop");
+// CHECK: @t27
+// CHECK: call void asm sideeffect "nop"
+// CHECK-NOT: ia_nsdialect
+// CHECK: ret void
+}
diff --git a/test/CodeGen/avx-builtins.c b/test/CodeGen/avx-builtins.c
index b963c97..0e5a741 100644
--- a/test/CodeGen/avx-builtins.c
+++ b/test/CodeGen/avx-builtins.c
@@ -23,3 +23,73 @@
   // CHECK: load <4 x i64>* %{{.+}}, align 1
   return _mm256_loadu_si256(p);
 }
+
+__m128i test_mm_cmpestrm(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestrm128
+  return _mm_cmpestrm(A, LA, B, LB, 7);
+}
+
+int test_mm_cmpestri(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestri128
+  return _mm_cmpestri(A, LA, B, LB, 7);
+}
+
+int test_mm_cmpestra(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestria128
+  return _mm_cmpestra(A, LA, B, LB, 7);
+}
+
+int test_mm_cmpestrc(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestric128
+  return _mm_cmpestrc(A, LA, B, LB, 7);
+}
+
+int test_mm_cmpestro(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestrio128
+  return _mm_cmpestro(A, LA, B, LB, 7);
+}
+
+int test_mm_cmpestrs(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestris128
+  return _mm_cmpestrs(A, LA, B, LB, 7);
+}
+
+int test_mm_cmpestrz(__m128i A, int LA, __m128i B, int LB) {
+  // CHECK: @llvm.x86.sse42.pcmpestriz128
+  return _mm_cmpestrz(A, LA, B, LB, 7);
+}
+
+__m128i test_mm_cmpistrm(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistrm128
+  return _mm_cmpistrm(A, B, 7);
+}
+
+int test_mm_cmpistri(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistri128
+  return _mm_cmpistri(A, B, 7);
+}
+
+int test_mm_cmpistra(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistria128
+  return _mm_cmpistra(A, B, 7);
+}
+
+int test_mm_cmpistrc(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistric128
+  return _mm_cmpistrc(A, B, 7);
+}
+
+int test_mm_cmpistro(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistrio128
+  return _mm_cmpistro(A, B, 7);
+}
+
+int test_mm_cmpistrs(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistris128
+  return _mm_cmpistrs(A, B, 7);
+}
+
+int test_mm_cmpistrz(__m128i A, __m128i B) {
+  // CHECK: @llvm.x86.sse42.pcmpistriz128
+  return _mm_cmpistrz(A, B, 7);
+}
diff --git a/test/CodeGen/builtins-mips.c b/test/CodeGen/builtins-mips.c
index a341462..8155a43 100644
--- a/test/CodeGen/builtins-mips.c
+++ b/test/CodeGen/builtins-mips.c
@@ -1,6 +1,6 @@
 // REQUIRES: mips-registered-target
-// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -emit-llvm -o %t %s
-// RUN: not grep __builtin %t
+// RUN: %clang_cc1 -triple mips-unknown-linux-gnu -emit-llvm %s -o - \
+// RUN:   | FileCheck %s
 
 typedef int q31;
 typedef int i32;
@@ -23,206 +23,302 @@
   v4i8_a = (v4i8) {1, 2, 3, 0xFF};
   v4i8_b = (v4i8) {2, 4, 6, 8};
   v4i8_r = __builtin_mips_addu_qb(v4i8_a, v4i8_b);
+// CHECK: call <4 x i8> @llvm.mips.addu.qb
   v4i8_r = __builtin_mips_addu_s_qb(v4i8_a, v4i8_b);
+// CHECK: call <4 x i8> @llvm.mips.addu.s.qb
   v4i8_r = __builtin_mips_subu_qb(v4i8_a, v4i8_b);
+// CHECK: call <4 x i8> @llvm.mips.subu.qb
   v4i8_r = __builtin_mips_subu_s_qb(v4i8_a, v4i8_b);
+// CHECK: call <4 x i8> @llvm.mips.subu.s.qb
 
   v2q15_a = (v2q15) {0x0000, 0x8000};
   v2q15_b = (v2q15) {0x8000, 0x8000};
   v2q15_r = __builtin_mips_addq_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.addq.ph
   v2q15_r = __builtin_mips_addq_s_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.addq.s.ph
   v2q15_r = __builtin_mips_subq_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.subq.ph
   v2q15_r = __builtin_mips_subq_s_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.subq.s.ph
 
   a64_a = 0x12345678;
   i32_b = 0x80000000;
   i32_c = 0x11112222;
   a64_r = __builtin_mips_madd(a64_a, i32_b, i32_c);
+// CHECK: call i64 @llvm.mips.madd
   a64_a = 0x12345678;
   ui32_b = 0x80000000;
   ui32_c = 0x11112222;
   a64_r = __builtin_mips_maddu(a64_a, ui32_b, ui32_c);
+// CHECK: call i64 @llvm.mips.maddu
   a64_a = 0x12345678;
   i32_b = 0x80000000;
   i32_c = 0x11112222;
   a64_r = __builtin_mips_msub(a64_a, i32_b, i32_c);
+// CHECK: call i64 @llvm.mips.msub
   a64_a = 0x12345678;
   ui32_b = 0x80000000;
   ui32_c = 0x11112222;
   a64_r = __builtin_mips_msubu(a64_a, ui32_b, ui32_c);
+// CHECK: call i64 @llvm.mips.msubu
 
   q31_a = 0x12345678;
   q31_b = 0x7FFFFFFF;
   q31_r = __builtin_mips_addq_s_w(q31_a, q31_b);
+// CHECK: call i32 @llvm.mips.addq.s.w
   q31_r = __builtin_mips_subq_s_w(q31_a, q31_b);
+// CHECK: call i32 @llvm.mips.subq.s.w
 
   i32_a = 0xFFFFFFFF;
   i32_b = 1;
   i32_r = __builtin_mips_addsc(i32_a, i32_b);
+// CHECK: call i32 @llvm.mips.addsc
   i32_a = 0;
   i32_b = 1;
   i32_r = __builtin_mips_addwc(i32_a, i32_b);
+// CHECK: call i32 @llvm.mips.addwc
 
   i32_a = 20;
   i32_b = 0x1402;
   i32_r = __builtin_mips_modsub(i32_a, i32_b);
+// CHECK: call i32 @llvm.mips.modsub
 
   v4i8_a = (v4i8) {1, 2, 3, 4};
   i32_r = __builtin_mips_raddu_w_qb(v4i8_a);
+// CHECK: call i32 @llvm.mips.raddu.w.qb
 
   v2q15_a = (v2q15) {0xFFFF, 0x8000};
   v2q15_r = __builtin_mips_absq_s_ph(v2q15_a);
+// CHECK: call <2 x i16> @llvm.mips.absq.s.ph
   q31_a = 0x80000000;
   q31_r = __builtin_mips_absq_s_w(q31_a);
+// CHECK: call i32 @llvm.mips.absq.s.w
 
   v2q15_a = (v2q15) {0x1234, 0x5678};
   v2q15_b = (v2q15) {0x1111, 0x2222};
   v4i8_r = __builtin_mips_precrq_qb_ph(v2q15_a, v2q15_b);
+// CHECK: call <4 x i8> @llvm.mips.precrq.qb.ph
 
   v2q15_a = (v2q15) {0x7F79, 0xFFFF};
   v2q15_b = (v2q15) {0x7F81, 0x2000};
   v4i8_r = __builtin_mips_precrqu_s_qb_ph(v2q15_a, v2q15_b);
+// CHECK: call <4 x i8> @llvm.mips.precrqu.s.qb.ph
   q31_a = 0x12345678;
   q31_b = 0x11112222;
   v2q15_r = __builtin_mips_precrq_ph_w(q31_a, q31_b);
+// CHECK: call <2 x i16> @llvm.mips.precrq.ph.w
   q31_a = 0x7000FFFF;
   q31_b = 0x80000000;
   v2q15_r = __builtin_mips_precrq_rs_ph_w(q31_a, q31_b);
+// CHECK: call <2 x i16> @llvm.mips.precrq.rs.ph.w
   v2q15_a = (v2q15) {0x1234, 0x5678};
   q31_r = __builtin_mips_preceq_w_phl(v2q15_a);
+// CHECK: call i32 @llvm.mips.preceq.w.phl
   q31_r = __builtin_mips_preceq_w_phr(v2q15_a);
+// CHECK: call i32 @llvm.mips.preceq.w.phr
   v4i8_a = (v4i8) {0x12, 0x34, 0x56, 0x78};
   v2q15_r = __builtin_mips_precequ_ph_qbl(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.precequ.ph.qbl
   v2q15_r = __builtin_mips_precequ_ph_qbr(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.precequ.ph.qbr
   v2q15_r = __builtin_mips_precequ_ph_qbla(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.precequ.ph.qbla
   v2q15_r = __builtin_mips_precequ_ph_qbra(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.precequ.ph.qbra
   v2q15_r = __builtin_mips_preceu_ph_qbl(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.preceu.ph.qbl
   v2q15_r = __builtin_mips_preceu_ph_qbr(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.preceu.ph.qbr
   v2q15_r = __builtin_mips_preceu_ph_qbla(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.preceu.ph.qbla
   v2q15_r = __builtin_mips_preceu_ph_qbra(v4i8_a);
+// CHECK: call <2 x i16> @llvm.mips.preceu.ph.qbra
 
   v4i8_a = (v4i8) {1, 2, 3, 4};
   v4i8_r = __builtin_mips_shll_qb(v4i8_a, 2);
+// CHECK: call <4 x i8> @llvm.mips.shll.qb
   v4i8_a = (v4i8) {128, 64, 32, 16};
   v4i8_r = __builtin_mips_shrl_qb(v4i8_a, 2);
+// CHECK: call <4 x i8> @llvm.mips.shrl.qb
   v2q15_a = (v2q15) {0x0001, 0x8000};
   v2q15_r = __builtin_mips_shll_ph(v2q15_a, 2);
+// CHECK: call <2 x i16> @llvm.mips.shll.ph
   v2q15_r = __builtin_mips_shll_s_ph(v2q15_a, 2);
+// CHECK: call <2 x i16> @llvm.mips.shll.s.ph
   v2q15_a = (v2q15) {0x7FFF, 0x8000};
   v2q15_r = __builtin_mips_shra_ph(v2q15_a, 2);
+// CHECK: call <2 x i16> @llvm.mips.shra.ph
   v2q15_r = __builtin_mips_shra_r_ph(v2q15_a, 2);
+// CHECK: call <2 x i16> @llvm.mips.shra.r.ph
   q31_a = 0x70000000;
   q31_r = __builtin_mips_shll_s_w(q31_a, 2);
+// CHECK: call i32 @llvm.mips.shll.s.w
   q31_a = 0x7FFFFFFF;
   q31_r = __builtin_mips_shra_r_w(q31_a, 2);
+// CHECK: call i32 @llvm.mips.shra.r.w
   a64_a = 0x1234567887654321LL;
   a64_r = __builtin_mips_shilo(a64_a, -8);
+// CHECK: call i64 @llvm.mips.shilo
 
   v4i8_a = (v4i8) {0x1, 0x3, 0x5, 0x7};
   v2q15_b = (v2q15) {0x1234, 0x5678};
   v2q15_r = __builtin_mips_muleu_s_ph_qbl(v4i8_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.muleu.s.ph.qbl
   v2q15_r = __builtin_mips_muleu_s_ph_qbr(v4i8_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.muleu.s.ph.qbr
   v2q15_a = (v2q15) {0x7FFF, 0x8000};
   v2q15_b = (v2q15) {0x7FFF, 0x8000};
   v2q15_r = __builtin_mips_mulq_rs_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.mulq.rs.ph
   v2q15_a = (v2q15) {0x1234, 0x8000};
   v2q15_b = (v2q15) {0x5678, 0x8000};
   q31_r = __builtin_mips_muleq_s_w_phl(v2q15_a, v2q15_b);
+// CHECK: call i32 @llvm.mips.muleq.s.w.phl
   q31_r = __builtin_mips_muleq_s_w_phr(v2q15_a, v2q15_b);
+// CHECK: call i32 @llvm.mips.muleq.s.w.phr
   a64_a = 0;
   v2q15_a = (v2q15) {0x0001, 0x8000};
   v2q15_b = (v2q15) {0x0002, 0x8000};
   a64_r = __builtin_mips_mulsaq_s_w_ph(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.mulsaq.s.w.ph
   a64_a = 0;
   v2q15_b = (v2q15) {0x0001, 0x8000};
   v2q15_c = (v2q15) {0x0002, 0x8000};
   a64_r = __builtin_mips_maq_s_w_phl(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.maq.s.w.phl
   a64_r = __builtin_mips_maq_s_w_phr(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.maq.s.w.phr
   a64_a = 0x7FFFFFF0;
   a64_r = __builtin_mips_maq_sa_w_phl(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.maq.sa.w.phl
   a64_r = __builtin_mips_maq_sa_w_phr(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.maq.sa.w.phr
   i32_a = 0x80000000;
   i32_b = 0x11112222;
   a64_r = __builtin_mips_mult(i32_a, i32_b);
+// CHECK: call i64 @llvm.mips.mult
   ui32_a = 0x80000000;
   ui32_b = 0x11112222;
   a64_r = __builtin_mips_multu(ui32_a, ui32_b);
+// CHECK: call i64 @llvm.mips.multu
 
   a64_a = 0;
   v4i8_b = (v4i8) {1, 2, 3, 4};
   v4i8_c = (v4i8) {4, 5, 6, 7};
   a64_r = __builtin_mips_dpau_h_qbl(a64_a, v4i8_b, v4i8_c);
+// CHECK: call i64 @llvm.mips.dpau.h.qbl
   a64_r = __builtin_mips_dpau_h_qbr(a64_a, v4i8_b, v4i8_c);
+// CHECK: call i64 @llvm.mips.dpau.h.qbr
   a64_r = __builtin_mips_dpsu_h_qbl(a64_a, v4i8_b, v4i8_c);
+// CHECK: call i64 @llvm.mips.dpsu.h.qbl
   a64_r = __builtin_mips_dpsu_h_qbr(a64_a, v4i8_b, v4i8_c);
+// CHECK: call i64 @llvm.mips.dpsu.h.qbr
   a64_a = 0;
   v2q15_b = (v2q15) {0x0001, 0x8000};
   v2q15_c = (v2q15) {0x0002, 0x8000};
   a64_r = __builtin_mips_dpaq_s_w_ph(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.dpaq.s.w.ph
   a64_r = __builtin_mips_dpsq_s_w_ph(a64_a, v2q15_b, v2q15_c);
+// CHECK: call i64 @llvm.mips.dpsq.s.w.ph
   a64_a = 0;
   q31_b = 0x80000000;
   q31_c = 0x80000000;
   a64_r = __builtin_mips_dpaq_sa_l_w(a64_a, q31_b, q31_c);
+// CHECK: call i64 @llvm.mips.dpaq.sa.l.w
   a64_r = __builtin_mips_dpsq_sa_l_w(a64_a, q31_b, q31_c);
+// CHECK: call i64 @llvm.mips.dpsq.sa.l.w
 
   v4i8_a = (v4i8) {1, 4, 10, 8};
   v4i8_b = (v4i8) {1, 2, 100, 8};
   __builtin_mips_cmpu_eq_qb(v4i8_a, v4i8_b);
+// CHECK: call void @llvm.mips.cmpu.eq.qb
   __builtin_mips_cmpu_lt_qb(v4i8_a, v4i8_b);
+// CHECK: call void @llvm.mips.cmpu.lt.qb
   __builtin_mips_cmpu_le_qb(v4i8_a, v4i8_b);
+// CHECK: call void @llvm.mips.cmpu.le.qb
   i32_r = __builtin_mips_cmpgu_eq_qb(v4i8_a, v4i8_b);
+// CHECK: call i32 @llvm.mips.cmpgu.eq.qb
   i32_r = __builtin_mips_cmpgu_lt_qb(v4i8_a, v4i8_b);
+// CHECK: call i32 @llvm.mips.cmpgu.lt.qb
   i32_r = __builtin_mips_cmpgu_le_qb(v4i8_a, v4i8_b);
+// CHECK: call i32 @llvm.mips.cmpgu.le.qb
   v2q15_a = (v2q15) {0x1111, 0x1234};
   v2q15_b = (v2q15) {0x4444, 0x1234};
   __builtin_mips_cmp_eq_ph(v2q15_a, v2q15_b);
+// CHECK: call void @llvm.mips.cmp.eq.ph
   __builtin_mips_cmp_lt_ph(v2q15_a, v2q15_b);
+// CHECK: call void @llvm.mips.cmp.lt.ph
   __builtin_mips_cmp_le_ph(v2q15_a, v2q15_b);
+// CHECK: call void @llvm.mips.cmp.le.ph
 
   a64_a = 0xFFFFF81230000000LL;
   i32_r = __builtin_mips_extr_s_h(a64_a, 4);
+// CHECK: call i32 @llvm.mips.extr.s.h
   a64_a = 0x8123456712345678LL;
   i32_r = __builtin_mips_extr_w(a64_a, 31);
+// CHECK: call i32 @llvm.mips.extr.w
   i32_r = __builtin_mips_extr_rs_w(a64_a, 31);
+// CHECK: call i32 @llvm.mips.extr.rs.w
   i32_r = __builtin_mips_extr_r_w(a64_a, 31);
+// CHECK: call i32 @llvm.mips.extr.r.w
   a64_a = 0x1234567887654321LL;
   i32_r = __builtin_mips_extp(a64_a, 3);
+// CHECK: call i32 @llvm.mips.extp
   a64_a = 0x123456789ABCDEF0LL;
   i32_r = __builtin_mips_extpdp(a64_a, 7);
+// CHECK: call i32 @llvm.mips.extpdp
 
   __builtin_mips_wrdsp(2052, 3);
+// CHECK: call void @llvm.mips.wrdsp
   i32_r = __builtin_mips_rddsp(3);
+// CHECK: call i32 @llvm.mips.rddsp
   i32_a = 0xFFFFFFFF;
   i32_b = 0x12345678;
   __builtin_mips_wrdsp((16<<7) + 4, 3);
+// CHECK: call void @llvm.mips.wrdsp
   i32_r = __builtin_mips_insv(i32_a, i32_b);
+// CHECK: call i32 @llvm.mips.insv
   i32_a = 0x1234;
   i32_r = __builtin_mips_bitrev(i32_a);
+// CHECK: call i32 @llvm.mips.bitrev
   v2q15_a = (v2q15) {0x1111, 0x2222};
   v2q15_b = (v2q15) {0x3333, 0x4444};
   v2q15_r = __builtin_mips_packrl_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.packrl.ph
   i32_a = 100;
   v4i8_r = __builtin_mips_repl_qb(i32_a);
+// CHECK: call <4 x i8> @llvm.mips.repl.qb
   i32_a = 0x1234;
   v2q15_r = __builtin_mips_repl_ph(i32_a);
+// CHECK: call <2 x i16> @llvm.mips.repl.ph
   v4i8_a = (v4i8) {1, 4, 10, 8};
   v4i8_b = (v4i8) {1, 2, 100, 8};
   __builtin_mips_cmpu_eq_qb(v4i8_a, v4i8_b);
+// CHECK: call void @llvm.mips.cmpu.eq.qb
   v4i8_r = __builtin_mips_pick_qb(v4i8_a, v4i8_b);
+// CHECK: call <4 x i8> @llvm.mips.pick.qb
   v2q15_a = (v2q15) {0x1111, 0x1234};
   v2q15_b = (v2q15) {0x4444, 0x1234};
   __builtin_mips_cmp_eq_ph(v2q15_a, v2q15_b);
+// CHECK: call void @llvm.mips.cmp.eq.ph
   v2q15_r = __builtin_mips_pick_ph(v2q15_a, v2q15_b);
+// CHECK: call <2 x i16> @llvm.mips.pick.ph
   a64_a = 0x1234567887654321LL;
   i32_b = 0x11112222;
   __builtin_mips_wrdsp(0, 1);
+// CHECK: call void @llvm.mips.wrdsp
   a64_r = __builtin_mips_mthlip(a64_a, i32_b);
+// CHECK: call i64 @llvm.mips.mthlip
   i32_r = __builtin_mips_bposge32();
+// CHECK: call i32 @llvm.mips.bposge32
   char array_a[100];
   i32_r = __builtin_mips_lbux(array_a, 20);
+// CHECK: call i32 @llvm.mips.lbux
   short array_b[100];
   i32_r = __builtin_mips_lhx(array_b, 20);
+// CHECK: call i32 @llvm.mips.lhx
   int array_c[100];
   i32_r = __builtin_mips_lwx(array_c, 20);
+// CHECK: call i32 @llvm.mips.lwx
 }
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index fca087e..65b9ad1 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -203,3 +203,9 @@
   __builtin_longjmp(buffer, 1);
   // CHECK-NEXT: unreachable
 }
+
+// CHECK: define i64 @test_builtin_readcyclecounter
+long long test_builtin_readcyclecounter() {
+  // CHECK: call i64 @llvm.readcyclecounter()
+  return __builtin_readcyclecounter();
+}
diff --git a/test/CodeGen/complex-builtints.c b/test/CodeGen/complex-builtints.c
new file mode 100644
index 0000000..09219cf
--- /dev/null
+++ b/test/CodeGen/complex-builtints.c
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 %s -O1 -emit-llvm -o - | FileCheck %s
+// rdar://8315199
+
+/* Test for builtin conj, creal, cimag.  */
+/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
+
+extern float _Complex conjf (float _Complex);
+extern double _Complex conj (double _Complex);
+extern long double _Complex conjl (long double _Complex);
+
+extern float crealf (float _Complex);
+extern double creal (double _Complex);
+extern long double creall (long double _Complex);
+
+extern float cimagf (float _Complex);
+extern double cimag (double _Complex);
+extern long double cimagl (long double _Complex);
+
+extern void abort (void);
+extern void link_error (void);
+
+int
+main ()
+{
+  /* For each type, test both runtime and compile time (constant folding)
+     optimization.  */
+  volatile float _Complex fc = 1.0F + 2.0iF;
+  volatile double _Complex dc = 1.0 + 2.0i;
+  volatile long double _Complex ldc = 1.0L + 2.0iL;
+  /* Test floats.  */
+  if (__builtin_conjf (fc) != 1.0F - 2.0iF)
+    abort ();
+  if (__builtin_conjf (1.0F + 2.0iF) != 1.0F - 2.0iF)
+    link_error ();
+  if (__builtin_crealf (fc) != 1.0F)
+    abort ();
+  if (__builtin_crealf (1.0F + 2.0iF) != 1.0F)
+    link_error ();
+  if (__builtin_cimagf (fc) != 2.0F)
+    abort ();
+  if (__builtin_cimagf (1.0F + 2.0iF) != 2.0F)
+    link_error ();
+  /* Test doubles.  */
+  if (__builtin_conj (dc) != 1.0 - 2.0i)
+    abort ();
+  if (__builtin_conj (1.0 + 2.0i) != 1.0 - 2.0i)
+    link_error ();
+  if (__builtin_creal (dc) != 1.0)
+    abort ();
+  if (__builtin_creal (1.0 + 2.0i) != 1.0)
+    link_error ();
+  if (__builtin_cimag (dc) != 2.0)
+    abort ();
+  if (__builtin_cimag (1.0 + 2.0i) != 2.0)
+    link_error ();
+  /* Test long doubles.  */
+  if (__builtin_conjl (ldc) != 1.0L - 2.0iL)
+    abort ();
+  if (__builtin_conjl (1.0L + 2.0iL) != 1.0L - 2.0iL)
+    link_error ();
+  if (__builtin_creall (ldc) != 1.0L)
+    abort ();
+  if (__builtin_creall (1.0L + 2.0iL) != 1.0L)
+    link_error ();
+  if (__builtin_cimagl (ldc) != 2.0L)
+    abort ();
+  if (__builtin_cimagl (1.0L + 2.0iL) != 2.0L)
+    link_error ();
+}
+
+// CHECK-NOT: link_error
diff --git a/test/CodeGen/const-init.c b/test/CodeGen/const-init.c
index 4f3f7ab..5f729b8 100644
--- a/test/CodeGen/const-init.c
+++ b/test/CodeGen/const-init.c
@@ -144,3 +144,18 @@
   static v12i16 b = (v2f80){1,2};
   static v2f80 c = (v12i16){0,0,0,-32768,16383,0,0,0,0,-32768,16384,0};
 }
+
+// PR13643
+void g29() {
+  typedef char DCC_PASSWD[2];
+  typedef struct
+  {
+      DCC_PASSWD passwd;
+  } DCC_SRVR_NM;
+  // CHECK: @g29.a = internal global %struct.DCC_SRVR_NM { [2 x i8] c"@\00" }, align 1
+  // CHECK: @g29.b = internal global [1 x i32] [i32 ptrtoint ([5 x i8]* @.str to i32)], align 4
+  // CHECK: @g29.c = internal global [1 x i32] [i32 97], align 4
+  static DCC_SRVR_NM a = { {"@"} };
+  static int b[1] = { "asdf" };
+  static int c[1] = { L"a" };
+}
diff --git a/test/CodeGen/mips-constraint-regs.c b/test/CodeGen/mips-constraint-regs.c
index 075be05..379dd4a 100644
--- a/test/CodeGen/mips-constraint-regs.c
+++ b/test/CodeGen/mips-constraint-regs.c
@@ -1,4 +1,5 @@
-// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s
+// RUN: %clang -target mipsel-unknown-linux -ccc-clang-archs mipsel -S -o - -emit-llvm %s \
+// RUN: | FileCheck %s
 
 // This checks that the frontend will accept inline asm constraints
 // c', 'l' and 'x'. Semantic checking will happen in the
@@ -10,6 +11,7 @@
   // 'c': 16 bit address register for Mips16, GPR for all others
   // I am using 'c' to constrain both the target and one of the source
   // registers. We are looking for syntactical correctness.
+  // CHECK: %{{[0-9]+}} = call i32 asm sideeffect "addi $0,$1,$2 \0A\09\09", "=c,c,I"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}}
   int __s, __v = 17;
   int __t;
   __asm__ __volatile__(
@@ -20,6 +22,7 @@
   // 'l': lo register
   // We are making it clear that destination register is lo with the
   // use of the 'l' constraint ("=l").
+  // CHECK:   %{{[0-9]+}} = call i32 asm sideeffect "mtlo $1 \0A\09\09", "=l,r,~{lo}"(i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}}
   int i_temp = 44;
   int i_result;
   __asm__ __volatile__(
@@ -31,6 +34,7 @@
   // 'x': Combined lo/hi registers
   // We are specifying that destination registers are the hi/lo pair with the
   // use of the 'x' constraint ("=x").
+  // CHECK:  %{{[0-9]+}} = call i64 asm sideeffect "mthi $1 \0A\09\09mtlo $2 \0A\09\09", "=x,r,r"(i32 %{{[0-9]+}}, i32 %{{[0-9]+}}) nounwind, !srcloc !{{[0-9]+}}
   int i_hi = 3;
   int i_lo = 2;
   long long ll_result = 0;
@@ -40,5 +44,6 @@
       : "=x" (ll_result)
         : "r" (i_hi), "r" (i_lo)
           : );
+
   return 0;
 }
diff --git a/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c
new file mode 100644
index 0000000..7680e3e
--- /dev/null
+++ b/test/CodeGen/ms-inline-asm.c
@@ -0,0 +1,114 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -O0 -fms-extensions -fenable-experimental-ms-inline-asm -w -emit-llvm -o - | FileCheck %s
+
+void t1() {
+// CHECK: @t1
+// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret void
+  __asm {}
+}
+
+void t2() {
+// CHECK: @t2
+// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "nop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret void
+  __asm nop
+  __asm nop
+  __asm nop
+}
+
+void t3() {
+// CHECK: @t3
+// CHECK: call void asm sideeffect "nop\0Anop\0Anop", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret void
+  __asm nop __asm nop __asm nop
+}
+
+void t4(void) {
+// CHECK: @t4
+// CHECK: call void asm sideeffect "mov ebx, eax", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "mov ecx, ebx", "~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret void
+  __asm mov ebx, eax
+  __asm mov ecx, ebx
+}
+
+void t5(void) {
+// CHECK: @t5
+// CHECK: call void asm sideeffect "mov ebx, eax\0Amov ecx, ebx", "~{ebx},~{ecx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret void
+  __asm mov ebx, eax __asm mov ecx, ebx
+}
+
+void t6(void) {
+  __asm int 0x2c
+// CHECK: t6
+// CHECK: call void asm sideeffect "int 0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+
+void t7() {
+  __asm {
+    int 0x2c ; } asm comments are fun! }{
+  }
+  __asm {}
+// CHECK: t7
+// CHECK: call void asm sideeffect "int 0x2c", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+int t8() {
+  __asm int 3 ; } comments for single-line asm
+  __asm {}
+  __asm int 4
+  return 10;
+// CHECK: t8
+// CHECK: call void asm sideeffect "int 3", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: call void asm sideeffect "int 4", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: ret i32 10
+}
+void t9() {
+  __asm {
+    push ebx
+    mov ebx, 0x07
+    pop ebx
+  }
+// CHECK: t9
+// CHECK: call void asm sideeffect "push ebx\0Amov ebx, 0x07\0Apop ebx", "~{ebx},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+}
+
+unsigned t10(void) {
+  unsigned i = 1, j;
+  __asm {
+    mov eax, i
+    mov j, eax
+  }
+  return j;
+// CHECK: t10
+// CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4
+// CHECK: store i32 1, i32* [[I]], align 4
+// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect
+// CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4
+// CHECK: ret i32 [[RET]]
+}
+
+void t11(void) {
+  __asm EVEN
+  __asm ALIGN
+}
+
+void t12(void) {
+  __asm {
+    _emit 0x4A
+    _emit 0x43
+    _emit 0x4B
+  }
+}
+
+void t13(void) {
+  unsigned arr[10];
+  __asm LENGTH arr ; sizeof(arr)/sizeof(arr[0])
+  __asm SIZE arr   ; sizeof(arr)
+  __asm TYPE arr   ; sizeof(arr[0])
+}
diff --git a/test/CodeGen/nobuiltin.c b/test/CodeGen/nobuiltin.c
new file mode 100644
index 0000000..0a8e8bb
--- /dev/null
+++ b/test/CodeGen/nobuiltin.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fno-builtin -O1 -S -o - %s | FileCheck %s
+
+void PR13497() {
+  char content[2];
+  // make sure we don't optimize this call to strcpy()
+  // CHECK: __strcpy_chk
+  __builtin___strcpy_chk(content, "", 1);
+}
diff --git a/test/CodeGen/regparm-flag.c b/test/CodeGen/regparm-flag.c
index 8ecf539..1330663 100644
--- a/test/CodeGen/regparm-flag.c
+++ b/test/CodeGen/regparm-flag.c
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown -mregparm 4 %s -emit-llvm -o %t
-// RUN: FileCheck < %t %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown -mregparm 4 %s -emit-llvm -o - | FileCheck %s
 
 void f1(int a, int b, int c, int d,
         int e, int f, int g, int h);
diff --git a/test/CodeGen/regparm-struct.c b/test/CodeGen/regparm-struct.c
new file mode 100644
index 0000000..b319012
--- /dev/null
+++ b/test/CodeGen/regparm-struct.c
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+
+__attribute__((regparm(3))) void f1(int a, int b, int c, int d);
+// CHECK: declare void @f1(i32 inreg, i32 inreg, i32 inreg, i32)
+void g1() {
+  f1(41, 42, 43, 44);
+}
+
+struct s1 {
+  int x1;
+};
+__attribute__((regparm(3))) void f2(int a, int b, struct s1 c, int d);
+// CHECK: declare void @f2(i32 inreg, i32 inreg, i32 inreg, i32)
+void g2() {
+  struct s1 x = {43};
+  f2(41, 42, x, 44);
+}
+
+struct s2 {
+  int x1;
+  int x2;
+};
+__attribute__((regparm(3))) void f3(int a, int b, struct s2 c, int d);
+// CHECK: declare void @f3(i32 inreg, i32 inreg, i32, i32, i32)
+void g3() {
+  struct s2 x = {43, 44};
+  f3(41, 42, x, 45);
+}
+__attribute__((regparm(3))) void f4(int a, struct s2 b, int c);
+// CHECK: declare void @f4(i32 inreg, i32 inreg, i32 inreg, i32)
+void g4() {
+  struct s2 x = {42, 43};
+  f4(41, x, 44);
+}
+
+struct s3 {
+  int x1;
+  int x2;
+  int x3;
+};
+__attribute__((regparm(3))) void f5(int a, struct s3 b, int c);
+// CHECK: declare void @f5(i32 inreg, i32, i32, i32, i32)
+void g5() {
+  struct s3 x = {42, 43, 44};
+  f5(41, x, 45);
+}
+__attribute__((regparm(3))) void f6(struct s3 a, int b);
+// CHECK: declare void @f6(i32 inreg, i32 inreg, i32 inreg, i32)
+void g6() {
+  struct s3 x = {41, 42, 43};
+  f6(x, 44);
+}
+
+struct s4 {
+  int x1;
+  int x2;
+  int x3;
+  int x4;
+};
+__attribute__((regparm(3))) void f7(struct s4 a, int b);
+// CHECK: declare void @f7(i32, i32, i32, i32, i32)
+void g7() {
+  struct s4 x = {41, 42, 43, 44};
+  f7(x, 45);
+}
+
+__attribute__((regparm(3))) void f8(float a, int b);
+// CHECK: declare void @f8(float, i32 inreg)
+void g8(void) {
+  f8(41, 42);
+}
+
+struct s5 {
+  float x1;
+};
+__attribute__((regparm(3))) void f9(struct s5 a, int b);
+// CHECK: declare void @f9(float, i32 inreg)
+void g9(void) {
+  struct s5 x = {41};
+  f9(x, 42);
+}
+
+struct s6 {
+  float x1;
+  int x2;
+};
+__attribute__((regparm(3))) void f10(struct s6 a, int b);
+// CHECK: declare void @f10(i32 inreg, i32 inreg, i32 inreg)
+void g10(void) {
+  struct s6 x = {41, 42};
+  f10(x, 43);
+}
+
+struct s7 {
+  float x1;
+  int x2;
+  float x3;
+};
+__attribute__((regparm(3))) void f11(struct s7 a, int b);
+// CHECK: declare void @f11(i32 inreg, i32 inreg, i32 inreg, i32)
+void g11(void) {
+  struct s7 x = {41, 42, 43};
+  f11(x, 44);
+}
+
+struct s8 {
+  float x1;
+  float x2;
+};
+__attribute__((regparm(3))) void f12(struct s8 a, int b);
+// CHECK: declare void @f12(i32 inreg, i32 inreg, i32 inreg)
+void g12(void) {
+  struct s8 x = {41, 42};
+  f12(x, 43);
+}
+
+struct s9 {
+  float x1;
+  float x2;
+  float x3;
+};
+__attribute__((regparm(3))) void f13(struct s9 a, int b);
+// CHECK: declare void @f13(i32 inreg, i32 inreg, i32 inreg, i32)
+void g13(void) {
+  struct s9 x = {41, 42, 43};
+  f13(x, 44);
+}
+
+struct s10 {
+  double x1;
+};
+__attribute__((regparm(3))) void f14(struct s10 a, int b, int c);
+// CHECK: declare void @f14(double, i32 inreg, i32 inreg)
+void g14(void) {
+  struct s10 x = { 41 };
+  f14(x, 42, 43);
+}
+
+struct s11 {
+  double x1;
+  double x2;
+};
+__attribute__((regparm(3))) void f15(struct s11 a, int b);
+// CHECK: declare void @f15(double, double, i32)
+void g15(void) {
+  struct s11 x = { 41, 42 };
+  f15(x, 43);
+}
+
+struct s12 {
+  double x1;
+  float x2;
+};
+__attribute__((regparm(3))) void f16(struct s12 a, int b);
+// CHECK: declare void @f16(i32 inreg, i32 inreg, i32 inreg, i32)
+void g16(void) {
+  struct s12 x = { 41, 42 };
+  f16(x, 43);
+}
+
+__attribute__((regparm(3))) struct s12 f17(int a, int b, int c);
+// CHECK: declare void @f17(%struct.s12* inreg sret, i32 inreg, i32 inreg, i32)
+void g17(void) {
+  f17(41, 42, 43);
+}
+
+struct s13 {
+  struct inner {
+    float x;
+  } y;
+};
+__attribute__((regparm(3))) void f18(struct s13 a, int b, int c, int d);
+// CHECK: declare void @f18(%struct.s13* byval align 4, i32 inreg, i32 inreg, i32 inreg)
+void g18(void) {
+  struct s13 x = {{41}};
+  f18(x, 42, 43, 44);
+}
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index a12ae53..8dc4f47 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -179,3 +179,13 @@
   };
   QueueEntry QE;
 }
+
+namespace PR13154 {
+  struct IndirectReferenceField {
+      struct {
+          float &x;
+      };
+      IndirectReferenceField(float &x);
+  };
+  IndirectReferenceField::IndirectReferenceField(float &xx) : x(xx) {}
+}
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp
index d2504d7..db1bb41 100644
--- a/test/CodeGenCXX/const-init-cxx11.cpp
+++ b/test/CodeGenCXX/const-init-cxx11.cpp
@@ -326,8 +326,8 @@
     S() = default;
   };
 
-  // CHECK: @_ZN7PR13273L1sE = {{.*}} zeroinitializer
-  const S s {};
+  // CHECK: @_ZN7PR132731sE = {{.*}} zeroinitializer
+  extern const S s {};
 }
 
 // Constant initialization tests go before this point,
diff --git a/test/CodeGenCXX/cxx11-vtable-key-function.cpp b/test/CodeGenCXX/cxx11-vtable-key-function.cpp
new file mode 100644
index 0000000..cd2ab59
--- /dev/null
+++ b/test/CodeGenCXX/cxx11-vtable-key-function.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -std=c++11 | FileCheck %s
+// PR13424
+
+namespace Test1 {
+struct X {
+  virtual ~X(); // Key function.
+  virtual void f(); // Not a key function.
+};
+
+X::~X() = default;
+
+// Verify that the vtable is emitted.
+// CHECK: @_ZTVN5Test11XE = unnamed_addr constant
+}
+
+namespace Test2 {
+struct X {
+  virtual ~X() = default; // Not a key function.
+  virtual void f(); // Key function.
+};
+
+void X::f() {}
+
+// Verify that the vtable is emitted.
+// CHECK: @_ZTVN5Test21XE = unnamed_addr constant
+}
+
+namespace Test3 {
+struct X {
+  virtual ~X() = delete; // Not a key function.
+  virtual void f(); // Key function.
+};
+
+void X::f() {}
+
+// Verify that the vtable is emitted.
+// CHECK: @_ZTVN5Test31XE = unnamed_addr constant
+}
diff --git a/test/CodeGenCXX/debug-info-cxx0x.cpp b/test/CodeGenCXX/debug-info-cxx0x.cpp
index 37ccdb0..9d30375 100644
--- a/test/CodeGenCXX/debug-info-cxx0x.cpp
+++ b/test/CodeGenCXX/debug-info-cxx0x.cpp
@@ -6,3 +6,13 @@
     return x;
   }
 }
+
+// Don't crash.
+namespace PR13570 {
+  template<typename T, typename U> struct P {};
+  template<typename T> struct A {
+    template<typename U> static P<T,U> isa(U);
+    decltype(isa(int())) f() {}
+  };
+  template struct A<int>;
+}
diff --git a/test/CodeGenCXX/debug-info-template-array.cpp b/test/CodeGenCXX/debug-info-template-array.cpp
new file mode 100644
index 0000000..305327b
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-array.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang -emit-llvm -g -S %s -o -
+// PR13531
+template <typename>
+struct unique_ptr {
+  unique_ptr() {}
+};
+
+template <unsigned>
+struct Vertex {};
+
+void crash() // Asserts
+{
+  unique_ptr<Vertex<2>[]> v = unique_ptr<Vertex<2>[]>();
+}
diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp
new file mode 100644
index 0000000..e5a9082
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-template-quals.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s
+
+template<typename _CharT>
+struct basic_string {
+
+  basic_string&
+  assign(const _CharT* __s)
+  {
+    return *this;
+  }
+};
+
+void foo (const char *c) {
+  basic_string<char> str;
+  str.assign(c);
+}
+
+// CHECK: [[P:.*]] = metadata !{i32 {{.*}}, metadata [[CON:.*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ]
+// CHECK: [[CON]] = metadata !{i32 {{.*}}, metadata [[CH:.*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char]
+// CHECK: [[CH]] = metadata !{i32 {{.*}}, metadata !"char", {{.*}}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char]
+// CHECK: metadata !{i32 {{.*}}, metadata !"_ZN12basic_stringIcE6assignEPKc", metadata !6, i32 7, metadata [[TYPE:.*]], i1 false, i1 true, i32 0, i32 0, null, i32 256, i1 false, %struct.basic_string* (%struct.basic_string*, i8*)* @_ZN12basic_stringIcE6assignEPKc, null, metadata !18, metadata !1, i32 8} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign]
+// CHECK: [[TYPE]] = metadata !{i32 {{.*}}, null, metadata [[ARGS:.*]], i32 0, i32 0}
+// CHECK: [[ARGS]] = metadata !{metadata !15, metadata !23, metadata [[P]]}
diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp
index aed3731..1c82399 100644
--- a/test/CodeGenCXX/debug-lambda-expressions.cpp
+++ b/test/CodeGenCXX/debug-lambda-expressions.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 -g | FileCheck %s
 
 auto var = [](int i) { return i+1; };
+void *use = &var;
 
 extern "C" auto cvar = []{};
 
@@ -13,7 +14,6 @@
 struct D { D(); D(const D&); int x; };
 int d(int x) { D y[10]; [x,y] { return y[x].x; }(); }
 
-
 // Randomness for file. -- 6
 // CHECK: [[FILE:.*]] = metadata !{i32 {{.*}}, metadata !{{.*}}debug-lambda-expressions.cpp{{.*}}; [ DW_TAG_file_type ]
 
@@ -32,8 +32,8 @@
 // Back to D. -- 24
 // CHECK: [[LAM_D:.*]] = metadata !{i32 {{.*}}, metadata [[D_FUNC]], metadata !"", metadata [[FILE]], i32 [[D_LINE]], i64 352, i64 32, i32 0, i32 0, null, metadata [[LAM_D_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
 // CHECK: [[LAM_D_ARGS]] = metadata !{metadata [[CAP_D_X:.*]], metadata [[CAP_D_Y:.*]], metadata [[CON_LAM_D:.*]]}
-// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 14, i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
-// CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"y", metadata [[FILE]], i32 14, i64 320, i64 32, i64 32, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
+// CHECK: [[CAP_D_X]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"x", metadata [[FILE]], i32 [[D_LINE]], i64 32, i64 32, i64 0, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
+// CHECK: [[CAP_D_Y]] = metadata !{i32 {{.*}}, metadata [[LAM_D]], metadata !"y", metadata [[FILE]], i32 [[D_LINE]], i64 320, i64 32, i64 32, i32 1, metadata {{.*}} ; [ DW_TAG_member ]
 // CHECK: [[CON_LAM_D]] = metadata {{.*}}[[LAM_D]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
 
 
@@ -58,12 +58,12 @@
 // CHECK: [[CON_LAM_A]] = metadata {{.*}}[[LAM_A]], metadata !"operator()", metadata !"operator()"{{.*}}[ DW_TAG_subprogram ]
 
 
-// VAR:
-// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata !"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata ![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var} ; [ DW_TAG_variable ]
-// CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
-// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}}
-
 // CVAR:
 // CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"cvar", metadata !"cvar", metadata !"", metadata [[FILE]], i32 [[CVAR_LINE:.*]], metadata ![[CVAR_T:.*]], i32 0, i32 1, %class.anon.0* @cvar} ; [ DW_TAG_variable ]
 // CHECK: [[CVAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[CVAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[CVAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
 // CHECK: [[CVAR_ARGS]] = metadata !{metadata !{{.*}}}
+
+// VAR:
+// CHECK: metadata !{i32 {{.*}}, i32 0, null, metadata !"var", metadata !"var", metadata !"", metadata [[FILE]], i32 [[VAR_LINE:.*]], metadata ![[VAR_T:.*]], i32 1, i32 1, %class.anon* @var} ; [ DW_TAG_variable ]
+// CHECK: [[VAR_T]] = metadata !{i32 {{.*}}, null, metadata !"", metadata [[FILE]], i32 [[VAR_LINE]], i64 8, i64 8, i32 0, i32 0, null, metadata ![[VAR_ARGS:.*]], i32 0, null, null} ; [ DW_TAG_class_type ]
+// CHECK: [[VAR_ARGS]] = metadata !{metadata !{{.*}}}
diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp
index 8c51809..9b15c68 100644
--- a/test/CodeGenCXX/derived-to-base-conv.cpp
+++ b/test/CodeGenCXX/derived-to-base-conv.cpp
@@ -1,85 +1,86 @@
-// REQUIRES: x86-registered-target,x86-64-registered-target
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s
-// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
-// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s
-// RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s
-
-extern "C" int printf(...);
-extern "C" void exit(int);
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o - | FileCheck %s
 
 struct A {
-  A (const A&) { printf("A::A(const A&)\n"); }
-  A() {};
-  ~A() { printf("A::~A()\n"); }
+  A(const A&);
+  A();
+  ~A();
 }; 
 
 struct B : public A {
-  B() {};
-  B(const B& Other) : A(Other) { printf("B::B(const B&)\n"); }
-  ~B() { printf("B::~B()\n"); }
+  B();
+  B(const B& Other);
+  ~B();
 };
 
 struct C : public B {
-  C() {};
-  C(const C& Other) : B(Other) { printf("C::C(const C&)\n"); }
-  ~C() { printf("C::~C()\n"); }
+  C();
+  C(const C& Other);
+  ~C();
 }; 
 
 struct X {
-	operator B&() {printf("X::operator B&()\n"); return b; }
-	operator C&() {printf("X::operator C&()\n"); return c; }
- 	X (const X&) { printf("X::X(const X&)\n"); }
- 	X () { printf("X::X()\n"); }
- 	~X () { printf("X::~X()\n"); }
-	B b;
-	C c;
+  operator B&();
+  operator C&();
+  X(const X&);
+  X();
+  ~X();
+  B b;
+  C c;
 };
 
-void f(A) {
-  printf("f(A)\n");
-}
-
-
-void func(X x) 
-{
-  f (x);
-}
-
-int main()
-{
-    X x;
-    func(x);
+void test0_helper(A);
+void test0(X x) {
+  test0_helper(x);
+  // CHECK:    define void @_Z5test01X(
+  // CHECK:      [[TMP:%.*]] = alloca [[A:%.*]], align
+  // CHECK-NEXT: [[T0:%.*]] = call [[B:%.*]]* @_ZN1XcvR1BEv(
+  // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
+  // CHECK-NEXT: call void @_ZN1AC1ERKS_([[A]]* [[TMP]], [[A]]* [[T1]])
+  // CHECK-NEXT: call void @_Z12test0_helper1A([[A]]* [[TMP]])
+  // CHECK-NEXT: call void @_ZN1AD1Ev([[A]]* [[TMP]])
+  // CHECK-NEXT: ret void
 }
 
 struct Base;
 
 struct Root {
-  operator Base&() { exit(1); }
+  operator Base&();
 };
 
 struct Derived;
 
 struct Base : Root {
-  Base(const Base&) { printf("Base::(const Base&)\n"); }
-  Base() { printf("Base::Base()\n"); }
-  operator Derived&() { exit(1); }
+  Base(const Base &);
+  Base();
+  operator Derived &();
 };
 
 struct Derived : Base {
 };
 
-void foo(Base) {}
-
-void test(Derived bb)
-{
-	// CHECK-LP64-NOT: callq    __ZN4BasecvR7DerivedEv
-	// CHECK-LP32-NOT: callq    L__ZN4BasecvR7DerivedEv
-        foo(bb);
+void test1_helper(Base);
+void test1(Derived bb) {
+  // CHECK:     define void @_Z5test17Derived(
+  // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv(
+  // CHECK:     call void @_ZN4BaseC1ERKS_(
+  // CHECK-NOT: call {{.*}} @_ZN4BasecvR7DerivedEv(
+  // CHECK:     call void @_Z12test1_helper4Base(
+  test1_helper(bb);
 }
-// CHECK-LP64: callq    __ZN1XcvR1BEv
-// CHECK-LP64: callq    __ZN1AC1ERKS_
 
-// CHECK-LP32: calll     L__ZN1XcvR1BEv
-// CHECK-LP32: calll     L__ZN1AC1ERKS_
-
-
+// Don't crash after devirtualizing a derived-to-base conversion
+// to an empty base allocated at offset zero.
+// rdar://problem/11993704
+class Test2a {};
+class Test2b final : public virtual Test2a {};
+void test2(Test2b &x) {
+  Test2a &y = x;
+  // CHECK:    define void @_Z5test2R6Test2b(
+  // CHECK:      [[X:%.*]] = alloca [[B:%.*]]*, align 8
+  // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]]*, align 8
+  // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]], align 8
+  // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]], align 8
+  // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]*
+  // CHECK-NEXT: store [[A]]* [[T1]], [[A]]** [[Y]], align 8
+  // CHECK-NEXT: ret void
+}
diff --git a/test/CodeGenCXX/destructor-exception-spec.cpp b/test/CodeGenCXX/destructor-exception-spec.cpp
new file mode 100644
index 0000000..579daef
--- /dev/null
+++ b/test/CodeGenCXX/destructor-exception-spec.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -emit-llvm-only %s -std=c++11
+
+// PR13479: don't crash with -fno-exceptions.
+namespace {
+  struct SchedulePostRATDList {
+    virtual ~SchedulePostRATDList();
+  };
+
+  SchedulePostRATDList::~SchedulePostRATDList() {}
+
+  SchedulePostRATDList Scheduler;
+}
diff --git a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
index c5a4094..7ef4864 100644
--- a/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
+++ b/test/CodeGenCXX/devirtualize-virtual-function-calls.cpp
@@ -83,3 +83,20 @@
     d.B::~B();
   }
 }
+
+namespace test4 {
+  struct Animal {
+    virtual void eat();
+  };
+  struct Fish : Animal {
+    virtual void eat();
+  };
+  struct Wrapper {
+    Fish fish;
+  };
+  extern Wrapper *p;
+  void test() {
+    // CHECK: call void @_ZN5test44Fish3eatEv
+    p->fish.eat();
+  }
+}
diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp
index 8e6ef77..2a53ad9 100644
--- a/test/CodeGenCXX/global-init.cpp
+++ b/test/CodeGenCXX/global-init.cpp
@@ -70,17 +70,17 @@
   const char *test() { return var; }
 }
 
-namespace test6 {
+namespace test4 {
   struct A {
     A();
   };
   extern int foo();
 
   // This needs an initialization function and guard variables.
-  // CHECK: load i8* bitcast (i64* @_ZGVN5test61xE
-  // CHECK: [[CALL:%.*]] = call i32 @_ZN5test63fooEv
-  // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test61xE
-  // CHECK-NEXT: store i64 1, i64* @_ZGVN5test61xE
+  // CHECK: load i8* bitcast (i64* @_ZGVN5test41xE
+  // CHECK: [[CALL:%.*]] = call i32 @_ZN5test43fooEv
+  // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test41xE
+  // CHECK-NEXT: store i64 1, i64* @_ZGVN5test41xE
   __attribute__((weak)) int x = foo();
 }
 
@@ -95,14 +95,6 @@
   A* a = &c;
   B* b = &c;
 }
-// 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
 
 // PR9570: the indirect field shouldn't crash IR gen.
 namespace test5 {
@@ -111,9 +103,98 @@
   };
 }
 
+namespace std { struct type_info; }
+
+namespace test6 {
+  struct A { virtual ~A(); };
+  struct B : A {};
+  extern A *p;
+
+  // We must emit a dynamic initializer for 'q', because it could throw.
+  B *const q = &dynamic_cast<B&>(*p);
+  // CHECK: call void @__cxa_bad_cast()
+  // CHECK: store {{.*}} @_ZN5test6L1qE
+
+  // We don't need to emit 'r' at all, because it has internal linkage, is
+  // unused, and its initialization has no side-effects.
+  B *const r = dynamic_cast<B*>(p);
+  // CHECK-NOT: call void @__cxa_bad_cast()
+  // CHECK-NOT: store {{.*}} @_ZN5test6L1rE
+
+  // This can throw, so we need to emit it.
+  const std::type_info *const s = &typeid(*p);
+  // CHECK: store {{.*}} @_ZN5test6L1sE
+
+  // This can't throw, so we don't.
+  const std::type_info *const t = &typeid(p);
+  // CHECK-NOT: @_ZN5test6L1tE
+
+  extern B *volatile v;
+  // CHECK: store {{.*}} @_ZN5test6L1wE
+  B *const w = dynamic_cast<B*>(v);
+
+  // CHECK: load volatile
+  // CHECK: store {{.*}} @_ZN5test6L1xE
+  const int x = *(volatile int*)0x1234;
+
+  namespace {
+    int a = int();
+    volatile int b = int();
+    int c = a;
+    int d = b;
+    // CHECK-NOT: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1aE
+    // CHECK-NOT: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1bE
+    // CHECK-NOT: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1cE
+    // CHECK: load volatile {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1bE
+    // CHECK: store {{.*}} @_ZN5test6{{[A-Za-z0-9_]*}}1dE
+  }
+}
+
+namespace test7 {
+  struct A { A(); };
+  struct B { ~B(); int n; };
+  struct C { C() = default; C(const C&); int n; };
+  struct D {};
+
+  // CHECK: call void @_ZN5test71AC1Ev({{.*}}@_ZN5test7L1aE)
+  const A a = A();
+
+  // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test71BD1Ev{{.*}} @_ZN5test7L2b1E
+  // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN5test71BD1Ev{{.*}} @_ZGRN5test72b2E
+  // CHECK: call void @_ZN5test71BD1Ev(
+  // CHECK: store {{.*}} @_ZN5test7L2b3E
+  const B b1 = B();
+  const B &b2 = B();
+  const int b3 = B().n;
+
+  // CHECK-NOT: @_ZN5test7L2c1E
+  // CHECK: @_ZN5test7L2c2E
+  // CHECK-NOT: @_ZN5test7L2c3E
+  // CHECK: @_ZN5test7L2c4E
+  const C c1 = C();
+  const C c2 = static_cast<const C&>(C());
+  const int c3 = C().n;
+  const int c4 = C(C()).n;
+
+  // CHECK-NOT: @_ZN5test7L1dE
+  const D d = D();
+
+  // CHECK: store {{.*}} @_ZN5test71eE
+  int f(), e = f();
+}
+
 
 // At the end of the file, we check that y is initialized before z.
 
+// 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
+
 // 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]]
diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp
index 797cbf43..e872cc4 100644
--- a/test/CodeGenCXX/lambda-expressions.cpp
+++ b/test/CodeGenCXX/lambda-expressions.cpp
@@ -1,7 +1,11 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -fexceptions -std=c++11 | FileCheck %s
 
-// CHECK: @var = internal global
-auto var = [](int i) { return i+1; };
+// CHECK-NOT: @unused
+auto unused = [](int i) { return i+1; };
+
+// CHECK: @used = internal global
+auto used = [](int i) { return i+1; };
+void *use = &used;
 
 // CHECK: @cvar = global
 extern "C" auto cvar = []{};
diff --git a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
index 9234e1c..27b4768 100644
--- a/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
+++ b/test/CodeGenCXX/mangle-ms-back-references-pr13207.cpp
@@ -35,6 +35,31 @@
 void foo_abc(N::A<char, N::B<char>, N::C<char> >) {}
 // CHECK: "\01?foo_abc@@YAXV?$A@DV?$B@D@N@@V?$C@D@2@@N@@@Z"
 
+N::A<char, N::B<char>, N::C<char> > abc_foo() {
+// CHECK: ?abc_foo@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@XZ
+  return N::A<char, N::B<char>, N::C<char> >();
+}
+
+N::Z z_foo(N::Z arg) {
+// CHECK: ?z_foo@@YA?AVZ@N@@V12@@Z
+  return arg;
+}
+
+N::B<char> b_foo(N::B<char> arg) {
+// CHECK: ?b_foo@@YA?AV?$B@D@N@@V12@@Z
+  return arg;
+}
+
+N::D<char, char> d_foo(N::D<char, char> arg) {
+// CHECK: ?d_foo@@YA?AV?$D@DD@N@@V12@@Z
+  return arg;
+}
+
+N::A<char, N::B<char>, N::C<char> > abc_foo_abc(N::A<char, N::B<char>, N::C<char> >) {
+// CHECK: ?abc_foo_abc@@YA?AV?$A@DV?$B@D@N@@V?$C@D@2@@N@@V12@@Z
+  return N::A<char, N::B<char>, N::C<char> >();
+}
+
 namespace NA {
 class X {};
 template<class T> class Y {};
diff --git a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
new file mode 100644
index 0000000..a5d03b3
--- /dev/null
+++ b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
+
+void a1() {}
+// CHECK: "\01?a1@@YAXXZ"
+
+int a2() { return 0; }
+// CHECK: "\01?a2@@YAHXZ"
+
+const int a3() { return 0; }
+// CHECK: "\01?a3@@YA?BHXZ"
+
+volatile int a4() { return 0; }
+// CHECK: "\01?a4@@YA?CHXZ"
+
+const volatile int a5() { return 0; }
+// CHECK: "\01?a5@@YA?DHXZ"
+
+float a6() { return 0.0f; }
+// CHECK: "\01?a6@@YAMXZ"
+
+int *b1() { return 0; }
+// CHECK: "\01?b1@@YAPAHXZ"
+
+const char *b2() { return 0; }
+// CHECK: "\01?b2@@YAPBDXZ"
+
+float *b3() { return 0; }
+// CHECK: "\01?b3@@YAPAMXZ"
+
+const float *b4() { return 0; }
+// CHECK: "\01?b4@@YAPBMXZ"
+
+volatile float *b5() { return 0; }
+// CHECK: "\01?b5@@YAPCMXZ"
+
+const volatile float *b6() { return 0; }
+// CHECK: "\01?b6@@YAPDMXZ"
+
+float &b7() { return *(float*)0; }
+// CHECK: "\01?b7@@YAAAMXZ"
+
+const float &b8() { return *(float*)0; }
+// CHECK: "\01?b8@@YAABMXZ"
+
+volatile float &b9() { return *(float*)0; }
+// CHECK: "\01?b9@@YAACMXZ"
+
+const volatile float &b10() { return *(float*)0; }
+// CHECK: "\01?b10@@YAADMXZ"
+
+const char** b11() { return 0; }
+// CHECK: "\01?b11@@YAPAPBDXZ"
+
+class A {};
+
+A c1() { return A(); }
+// CHECK: "\01?c1@@YA?AVA@@XZ"
+
+const A c2() { return A(); }
+// CHECK: "\01?c2@@YA?BVA@@XZ"
+
+volatile A c3() { return A(); }
+// CHECK: "\01?c3@@YA?CVA@@XZ"
+
+const volatile A c4() { return A(); }
+// CHECK: "\01?c4@@YA?DVA@@XZ"
+
+const A* c5() { return 0; }
+// CHECK: "\01?c5@@YAPBVA@@XZ"
+
+volatile A* c6() { return 0; }
+// CHECK: "\01?c6@@YAPCVA@@XZ"
+
+const volatile A* c7() { return 0; }
+// CHECK: "\01?c7@@YAPDVA@@XZ"
+
+A &c8() { return *(A*)0; }
+// CHECK: "\01?c8@@YAAAVA@@XZ"
+
+const A &c9() { return *(A*)0; }
+// CHECK: "\01?c9@@YAABVA@@XZ"
+
+volatile A &c10() { return *(A*)0; }
+// CHECK: "\01?c10@@YAACVA@@XZ"
+
+const volatile A &c11() { return *(A*)0; }
+// CHECK: "\01?c11@@YAADVA@@XZ"
+
+template<typename T> class B {};
+
+B<int> d1() { return B<int>(); }
+// CHECK: "\01?d1@@YA?AV?$B@H@@XZ"
+
+B<const char*> d2() {return B<const char*>(); }
+// CHECK: "\01?d2@@YA?AV?$B@PBD@@XZ"
+
+B<A> d3() {return B<A>(); }
+// CHECK: "\01?d3@@YA?AV?$B@VA@@@@XZ"
+
+B<A>* d4() { return 0; }
+// CHECK: "\01?d4@@YAPAV?$B@VA@@@@XZ"
+
+const B<A>* d5() { return 0; }
+// CHECK: "\01?d5@@YAPBV?$B@VA@@@@XZ"
+
+volatile B<A>* d6() { return 0; }
+// CHECK: "\01?d6@@YAPCV?$B@VA@@@@XZ"
+
+const volatile B<A>* d7() { return 0; }
+// CHECK: "\01?d7@@YAPDV?$B@VA@@@@XZ"
+
+B<A>& d8() { return *(B<A>*)0; }
+// CHECK: "\01?d8@@YAAAV?$B@VA@@@@XZ"
+
+const B<A>& d9() { return *(B<A>*)0; }
+// CHECK: "\01?d9@@YAABV?$B@VA@@@@XZ"
+
+volatile B<A>& d10() { return *(B<A>*)0; }
+// CHECK: "\01?d10@@YAACV?$B@VA@@@@XZ"
+
+const volatile B<A>& d11() { return *(B<A>*)0; }
+// CHECK: "\01?d11@@YAADV?$B@VA@@@@XZ"
+
+enum Enum { DEFAULT };
+
+Enum e1() { return DEFAULT; }
+// CHECK: "\01?e1@@YA?AW4Enum@@XZ"
+
+const Enum e2() { return DEFAULT; }
+// CHECK: "\01?e2@@YA?BW4Enum@@XZ"
+
+Enum* e3() { return 0; }
+// CHECK: "\01?e3@@YAPAW4Enum@@XZ"
+
+Enum& e4() { return *(Enum*)0; }
+// CHECK: "\01?e4@@YAAAW4Enum@@XZ"
+
+struct S {};
+
+struct S f1() { struct S s; return s; }
+// CHECK: "\01?f1@@YA?AUS@@XZ"
+
+const struct S f2() { struct S s; return s; }
+// CHECK: "\01?f2@@YA?BUS@@XZ"
+
+struct S* f3() { return 0; }
+// CHECK: "\01?f3@@YAPAUS@@XZ"
+
+const struct S* f4() { return 0; }
+// CHECK: "\01?f4@@YAPBUS@@XZ"
+
+const volatile struct S* f5() { return 0; }
+// CHECK: "\01?f5@@YAPDUS@@XZ"
+
+struct S& f6() { return *(struct S*)0; }
+// CHECK: "\01?f6@@YAAAUS@@XZ"
+
+typedef int (*function_pointer)(int);
+
+function_pointer g1() { return 0; }
+// CHECK: "\01?g1@@YAP6AHH@ZXZ"
+
+const function_pointer g2() { return 0; }
+// CHECK: "\01?g2@@YAQ6AHH@ZXZ"
+
+function_pointer* g3() { return 0; }
+// CHECK: "\01?g3@@YAPAP6AHH@ZXZ"
+
+const function_pointer* g4() { return 0; }
+// The mangling of g4 is currently "\01?g4@@YAPQ6AHH@ZXZ" which is wrong.
+// This looks related to http://llvm.org/PR13444
+// FIXME: replace CHECK-NOT with CHECK once it is fixed.
+// CHECK-NOT: "\01?g4@@YAPBQ6AHH@ZXZ"
diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp
index ce22931..f392c17 100644
--- a/test/CodeGenCXX/mangle-ms.cpp
+++ b/test/CodeGenCXX/mangle-ms.cpp
@@ -120,9 +120,13 @@
 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"
+void zeta(int (*)(int, int)) {}
+// CHECK: @"\01?zeta@@YAXP6AHHH@Z@Z"
+
+// Blocks mangling (Clang extension). A block should be mangled slightly
+// differently from a similar function pointer.
+void eta(int (^)(int, int)) {}
+// CHECK: @"\01?eta@@YAXP_EAHHH@Z@Z"
 
 void operator_new_delete() {
   char *ptr = new char;
diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp
index 05c3a58..488f6f3 100644
--- a/test/CodeGenCXX/mangle-template.cpp
+++ b/test/CodeGenCXX/mangle-template.cpp
@@ -170,3 +170,15 @@
     test<const int&, n>();
   }
 }
+
+// rdar://problem/12072531
+// Test the boundary condition of minimal signed integers.
+namespace test13 {
+  template <char c> char returnChar() { return c; }
+  template char returnChar<-128>();
+  // CHECK: @_ZN6test1310returnCharILcn128EEEcv()
+
+  template <short s> short returnShort() { return s; }
+  template short returnShort<-32768>();
+  // CHECK: @_ZN6test1311returnShortILsn32768EEEsv()
+}
diff --git a/test/CodeGenCXX/member-init-ctor.cpp b/test/CodeGenCXX/member-init-ctor.cpp
deleted file mode 100644
index 2172394..0000000
--- a/test/CodeGenCXX/member-init-ctor.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
-
-bool b();
-struct S {
-  int n = b() ? S().n + 1 : 0;
-};
-
-S s;
-
-// CHECK: define {{.*}} @_ZN1SC2Ev(
-// CHECK-NOT }
-// CHECK: call {{.*}} @_Z1bv()
-// CHECK-NOT }
-// CHECK: call {{.*}} @_ZN1SC1Ev(
diff --git a/test/CodeGenCXX/pr13396.cpp b/test/CodeGenCXX/pr13396.cpp
new file mode 100644
index 0000000..7d4e2ce
--- /dev/null
+++ b/test/CodeGenCXX/pr13396.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu %s -emit-llvm -o - | FileCheck %s
+struct foo {
+  template<typename T>
+  __attribute__ ((regparm (3))) foo(T x) {}
+  __attribute__ ((regparm (3))) foo();
+  __attribute__ ((regparm (3))) ~foo();
+};
+
+foo::foo() {
+  // CHECK: define void @_ZN3fooC1Ev(%struct.foo* inreg %this)
+  // CHECK: define void @_ZN3fooC2Ev(%struct.foo* inreg %this)
+}
+
+foo::~foo() {
+  // CHECK: define void @_ZN3fooD1Ev(%struct.foo* inreg %this)
+  // CHECK: define void @_ZN3fooD2Ev(%struct.foo* inreg %this)
+}
+
+void dummy() {
+  // FIXME: how can we explicitly instantiate a template constructor? Gcc and
+  // older clangs accept:
+  // template foo::foo(int x);
+  foo x(10);
+  // CHECK: define linkonce_odr void @_ZN3fooC1IiEET_(%struct.foo* inreg %this, i32 inreg %x)
+  // CHECK: define linkonce_odr void @_ZN3fooC2IiEET_(%struct.foo* inreg %this, i32 inreg %x)
+}
diff --git a/test/CodeGenCXX/rvalue-references.cpp b/test/CodeGenCXX/rvalue-references.cpp
index 1c25543..b8d47dc 100644
--- a/test/CodeGenCXX/rvalue-references.cpp
+++ b/test/CodeGenCXX/rvalue-references.cpp
@@ -10,7 +10,7 @@
 // CHECK: define %struct.A* @_Z4getAv()
 // CHECK: call %struct.B* @_Z4getBv()
 // CHECK-NEXT: bitcast %struct.B*
-// CHECK-NEXT: getelementptr i8*
+// CHECK-NEXT: getelementptr inbounds i8*
 // CHECK-NEXT: bitcast i8* {{.*}} to %struct.A*
 // CHECK-NEXT: ret %struct.A*
 A &&getA() { return static_cast<A&&>(getB()); }
diff --git a/test/CodeGenCXX/throw-expression-cleanup.cpp b/test/CodeGenCXX/throw-expression-cleanup.cpp
new file mode 100644
index 0000000..0c41bc6
--- /dev/null
+++ b/test/CodeGenCXX/throw-expression-cleanup.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s
+// PR13359
+
+struct X {
+  ~X();
+};
+struct Error {
+  Error(const X&) noexcept;
+};
+
+void f() {
+  try {
+    throw Error(X());
+  } catch (...) { }
+}
+
+// CHECK: define void @_Z1fv
+// CHECK: call void @_ZN5ErrorC1ERK1X
+// CHECK: invoke void @__cxa_throw
+// CHECK: landingpad
+// CHECK: call void @_ZN1XD1Ev
+// CHECK-NOT: __cxa_free_exception
diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp
index 590c06e..0145039 100644
--- a/test/CodeGenCXX/visibility.cpp
+++ b/test/CodeGenCXX/visibility.cpp
@@ -1077,3 +1077,38 @@
   // CHECK: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
   // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
 }
+
+namespace test59 {
+  DEFAULT int f();
+  HIDDEN int g();
+  typedef int (*foo)();
+  template<foo x, foo y>
+  void test() {}
+  void use() {
+    test<&g, &f>();
+    // CHECK: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
+    // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
+
+    test<&f, &g>();
+    // CHECK: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
+    // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
+  }
+}
+
+namespace test60 {
+  template<int i>
+  class __attribute__((visibility("hidden"))) a {};
+  template<int i>
+  class __attribute__((visibility("default"))) b {};
+  template<template<int> class x, template<int> class y>
+  void test() {}
+  void use() {
+    test<a, b>();
+    // CHECK: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
+    // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
+
+    test<b, a>();
+    // CHECK: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
+    // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
+  }
+}
diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m
index 6c5180b..68344b8 100644
--- a/test/CodeGenObjC/arc-property.m
+++ b/test/CodeGenObjC/arc-property.m
@@ -13,3 +13,75 @@
 // CHECK: @objc_msgSend
 // CHECK: call void @objc_release(
 // CHECK: call void @objc_release(
+
+struct S1 { Class isa; };
+@interface Test1
+@property (nonatomic, strong) __attribute__((NSObject)) struct S1 *pointer;
+@end
+@implementation Test1
+@synthesize pointer;
+@end
+//   The getter should be a simple load.
+// CHECK:    define internal [[S1:%.*]]* @"\01-[Test1 pointer]"(
+// CHECK:      [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test1.pointer"
+// CHECK-NEXT: [[T0:%.*]] = bitcast [[TEST1:%.*]]* {{%.*}} to i8*
+// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[S1]]**
+// CHECK-NEXT: [[T3:%.*]] = load [[S1]]** [[T2]], align 8
+// CHECK-NEXT: ret [[S1]]* [[T3]]
+
+//   The setter should be using objc_setProperty.
+// CHECK:    define internal void @"\01-[Test1 setPointer:]"(
+// CHECK:      [[T0:%.*]] = bitcast [[TEST1]]* {{%.*}} to i8*
+// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test1.pointer"
+// CHECK-NEXT: [[T1:%.*]] = load [[S1]]** {{%.*}}
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[S1]]* [[T1]] to i8*
+// CHECK-NEXT: call void @objc_setProperty(i8* [[T0]], i8* {{%.*}}, i64 [[OFFSET]], i8* [[T2]], i1 zeroext false, i1 zeroext false)
+// CHECK-NEXT: ret void
+
+
+// rdar://problem/12039404
+@interface Test2 {
+@private
+  Class _theClass;
+}
+@property (copy) Class theClass;
+@end
+
+static Class theGlobalClass;
+@implementation Test2
+@synthesize theClass = _theClass;
+- (void) test {
+  _theClass = theGlobalClass;
+}
+@end
+// CHECK:    define internal void @"\01-[Test2 test]"(
+// CHECK:      [[T0:%.*]] = load i8** @theGlobalClass, align 8
+// CHECK-NEXT: [[T1:%.*]] = load [[TEST2:%.*]]**
+// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2._theClass"
+// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST2]]* [[T1]] to i8*
+// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T4]], i8* [[T0]]) nounwind
+// CHECK-NEXT: ret void
+
+// CHECK:    define internal i8* @"\01-[Test2 theClass]"(
+// CHECK:      [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2._theClass"
+// CHECK-NEXT: [[T0:%.*]] = call i8* @objc_getProperty(i8* {{.*}}, i8* {{.*}}, i64 [[OFFSET]], i1 zeroext true)
+// CHECK-NEXT: ret i8* [[T0]]
+
+// CHECK:    define internal void @"\01-[Test2 setTheClass:]"(
+// CHECK:      [[T0:%.*]] = bitcast [[TEST2]]* {{%.*}} to i8*
+// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2._theClass"
+// CHECK-NEXT: [[T1:%.*]] = load i8** {{%.*}}
+// CHECK-NEXT: call void @objc_setProperty(i8* [[T0]], i8* {{%.*}}, i64 [[OFFSET]], i8* [[T1]], i1 zeroext true, i1 zeroext true)
+// CHECK-NEXT: ret void
+
+// CHECK:    define internal void @"\01-[Test2 .cxx_destruct]"(
+// CHECK:      [[T0:%.*]] = load [[TEST2]]**
+// CHECK-NEXT: [[OFFSET:%.*]] = load i64* @"OBJC_IVAR_$_Test2._theClass"
+// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST2]]* [[T0]] to i8*
+// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8* [[T1]], i64 [[OFFSET]]
+// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to i8**
+// CHECK-NEXT: call void @objc_storeStrong(i8** [[T3]], i8* null) nounwind
+// CHECK-NEXT: ret void
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index 2a98b10..66a6a2f 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -9,6 +9,9 @@
   // CHECK-NEXT: [[TMP:%.*]] = load i8** [[X]]
   // CHECK-NEXT: call void @objc_release(i8* [[TMP]])
   // CHECK-NEXT: ret void
+// rdar://12040837
+  // CHECK: declare extern_weak i8* @objc_retain(i8*) nonlazybind
+  // CHECK: declare extern_weak void @objc_release(i8*) nonlazybind
 }
 
 // CHECK: define i8* @test1(i8*
diff --git a/test/CodeGenObjC/instance-method-metadata.m b/test/CodeGenObjC/instance-method-metadata.m
index ec24c28..0d8c0e0 100644
--- a/test/CodeGenObjC/instance-method-metadata.m
+++ b/test/CodeGenObjC/instance-method-metadata.m
@@ -28,8 +28,8 @@
 @end
 
 // CHECK: l_OBJC_$_INSTANCE_METHODS_Bar:
-// CHECK-NEXT        .long   24
-// CHECK-NEXT        .long   2
-// CHECK-NEXT        .quad   L_OBJC_METH_VAR_NAME_
-// CHECK-NEXT        .quad   L_OBJC_METH_VAR_TYPE_
-// CHECK-NEXT        .quad   "-[Bar prop]"
+// CHECK-NEXT:        .long   24
+// CHECK-NEXT:        .long   2
+// CHECK-NEXT:        .quad   L_OBJC_METH_VAR_NAME_
+// CHECK-NEXT:        .quad   L_OBJC_METH_VAR_TYPE_
+// CHECK-NEXT:        .quad   "-[Bar prop]"
diff --git a/test/CodeGenObjC/ns_consume_null_check.m b/test/CodeGenObjC/ns_consume_null_check.m
index e3b6075..a8e5acd 100644
--- a/test/CodeGenObjC/ns_consume_null_check.m
+++ b/test/CodeGenObjC/ns_consume_null_check.m
@@ -17,7 +17,7 @@
         [x isEqual : obj];
 }
 
-// CHECK: [[TMP:%.*]] = alloca i8
+// CHECK: [[TMP:%.*]] = alloca i8{{$}}
 // CHECK: [[FIVE:%.*]] = call i8* @objc_retain
 // CHECK-NEXT:  [[SIX:%.*]] = bitcast
 // CHECK-NEXT:  [[SEVEN:%.*]]  = icmp eq i8* [[SIX]], null
@@ -25,8 +25,8 @@
 // CHECK:  [[FN:%.*]] = load i8** getelementptr inbounds
 // CHECK-NEXT:  [[EIGHT:%.*]] = bitcast i8* [[FN]]
 // CHECK-NEXT:  [[CALL:%.*]] = call signext i8 [[EIGHT]]
-// CHECK-NEXT  store i8 [[CALL]], i8* [[TMP]]
-// CHECK-NEXT  br label [[CONT:%.*]]
+// CHECK-NEXT:  store i8 [[CALL]], i8* [[TMP]]
+// CHECK-NEXT:  br label [[CONT:%.*]]
 // CHECK:   call void @objc_release(i8* [[FIVE]]) nounwind
 // CHECK-NEXT:   call void @llvm.memset
-// CHECK-NEXT  br label [[CONT]]
+// CHECK-NEXT:  br label [[CONT]]
diff --git a/test/CodeGenObjCXX/arc.mm b/test/CodeGenObjCXX/arc.mm
index 45211a2..f31b993 100644
--- a/test/CodeGenObjCXX/arc.mm
+++ b/test/CodeGenObjCXX/arc.mm
@@ -252,3 +252,19 @@
 };
 // CHECK: define weak_odr void @_ZN6Test38IiE4testEi(
 template class Test38<int>;
+
+// rdar://problem/11964832
+class Test39_base1 {
+  virtual void foo();
+};
+class Test39_base2 {
+  virtual id bar();
+};
+class Test39 : Test39_base1, Test39_base2 { // base2 is at non-zero offset
+  virtual id bar();
+};
+id Test39::bar() { return 0; }
+// Note lack of autorelease.
+// CHECK:    define i8* @_ZThn8_N6Test393barEv(
+// CHECK:      call i8* @_ZN6Test393barEv(
+// CHECK-NEXT: ret i8*
diff --git a/test/CodeGenObjCXX/encode.mm b/test/CodeGenObjCXX/encode.mm
index b2a4b8f..1b6a241 100644
--- a/test/CodeGenObjCXX/encode.mm
+++ b/test/CodeGenObjCXX/encode.mm
@@ -87,8 +87,8 @@
 
   typedef vector< float,  fixed<4> > vector4f;
 
-  // CHECK: @_ZN11rdar9357400L2ggE = internal constant [49 x i8] c"{vector<float, rdar9357400::fixed<4, -1> >=[4f]}\00"
-  const char gg[] = @encode(vector4f);
+  // CHECK: @_ZN11rdar93574002ggE = constant [49 x i8] c"{vector<float, rdar9357400::fixed<4, -1> >=[4f]}\00"
+  extern const char gg[] = @encode(vector4f);
 }
 
 // rdar://9624314
@@ -97,12 +97,12 @@
   struct B3 {};
   struct S : B2, B3 {};
 
-  // CHECK: @_ZN11rdar9624314L2ggE = internal constant [6 x i8] c"{S=i}\00"
-  const char gg[] = @encode(S);
+  // CHECK: @_ZN11rdar96243142ggE = constant [6 x i8] c"{S=i}\00"
+  extern const char gg[] = @encode(S);
 
   struct S2 { unsigned : 0; int x; unsigned : 0; };
-  // CHECK: @_ZN11rdar9624314L2g2E = internal constant [11 x i8] c"{S2=b0ib0}\00"
-  const char g2[] = @encode(S2);
+  // CHECK: @_ZN11rdar96243142g2E = constant [11 x i8] c"{S2=b0ib0}\00"
+  extern const char g2[] = @encode(S2);
 }
 
 namespace test {
@@ -122,8 +122,8 @@
    int y;
   };
 
-  // CHECK: @_ZN4testL3ecdE = internal constant [15 x i8] c"{Zoo=^^?ii^^?}\00"
-  const char ecd[] = @encode(Zoo);
+  // CHECK: @_ZN4test3ecdE = constant [15 x i8] c"{Zoo=^^?ii^^?}\00"
+  extern const char ecd[] = @encode(Zoo);
 }
 
 struct Base1 {
@@ -143,17 +143,17 @@
   float x;
 };
 
-// CHECK: @_ZL2g1 = internal constant [10 x i8] c"{Base1=c}\00"
-const char g1[] = @encode(Base1);
+// CHECK: @g1 = constant [10 x i8] c"{Base1=c}\00"
+extern const char g1[] = @encode(Base1);
 
-// CHECK: @_ZL2g2 = internal constant [14 x i8] c"{DBase=^^?cd}\00"
-const char g2[] = @encode(DBase);
+// CHECK: @g2 = constant [14 x i8] c"{DBase=^^?cd}\00"
+extern const char g2[] = @encode(DBase);
 
-// CHECK: @_ZL2g3 = internal constant [26 x i8] c"{Sub_with_virt=^^?q^^?cd}\00"
-const char g3[] = @encode(Sub_with_virt);
+// CHECK: @g3 = constant [26 x i8] c"{Sub_with_virt=^^?q^^?cd}\00"
+extern const char g3[] = @encode(Sub_with_virt);
 
-// CHECK: @_ZL2g4 = internal constant [19 x i8] c"{Sub2=^^?qcf^^?cd}\00"
-const char g4[] = @encode(Sub2);
+// CHECK: @g4 = constant [19 x i8] c"{Sub2=^^?qcf^^?cd}\00"
+extern const char g4[] = @encode(Sub2);
 
 // http://llvm.org/PR9927
 class allocator {
@@ -165,8 +165,8 @@
 _Alloc_hider _M_dataplus;
 };
 
-// CHECK: @_ZL2g5 = internal constant [32 x i8] c"{basic_string={_Alloc_hider=*}}\00"
-const char g5[] = @encode(basic_string);
+// CHECK: @g5 = constant [32 x i8] c"{basic_string={_Alloc_hider=*}}\00"
+extern const char g5[] = @encode(basic_string);
 
 
 // PR10990
@@ -175,8 +175,8 @@
 };
 class CefBrowser : public virtual CefBase {};
 class CefBrowserImpl : public CefBrowser {};
-// CHECK: @_ZL2g6 = internal constant [21 x i8] c"{CefBrowserImpl=^^?}\00"
-const char g6[] = @encode(CefBrowserImpl);
+// CHECK: @g6 = constant [21 x i8] c"{CefBrowserImpl=^^?}\00"
+extern const char g6[] = @encode(CefBrowserImpl);
 
 // PR10990_2
 class CefBase2 {
@@ -185,8 +185,8 @@
 };
 class CefBrowser2 : public virtual CefBase2 {};
 class CefBrowserImpl2 : public CefBrowser2 {};
-// CHECK: @_ZL2g7 = internal constant [26 x i8] c"{CefBrowserImpl2=^^?^^?i}\00"
-const char g7[] = @encode(CefBrowserImpl2);
+// CHECK: @g7 = constant [26 x i8] c"{CefBrowserImpl2=^^?^^?i}\00"
+extern const char g7[] = @encode(CefBrowserImpl2);
 
 // <rdar://problem/11324167>
 struct Empty {};
@@ -199,5 +199,5 @@
   X vec;
 };
 
-// CHECK: @_ZL2g8 = internal constant [14 x i8] c"{Y={X=[10i]}}\00"
-const char g8[] = @encode(Y);
+// CHECK: @g8 = constant [14 x i8] c"{Y={X=[10i]}}\00"
+extern const char g8[] = @encode(Y);
diff --git a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
index 29ec9ac..a5ce789 100644
--- a/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
+++ b/test/CodeGenObjCXX/implicit-copy-assign-operator.mm
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -fobjc-gc -emit-llvm -triple x86_64-apple-darwin10.0.0 -fobjc-runtime=macosx-fragile-10.5 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -fobjc-gc -emit-llvm -triple x86_64-apple-darwin10.0.0 -fobjc-runtime=macosx-fragile-10.5 -o - %s | FileCheck %s -check-prefix=CHECK-OBJ
+// RUN: %clang_cc1 -x c++    -emit-llvm -triple x86_64-apple-darwin10.0.0                                    -o - %s | FileCheck %s -check-prefix=CHECK-CPP
+#ifdef __OBJC__
 struct A { 
   A &operator=(const A&);
   A &operator=(A&);
@@ -41,17 +43,82 @@
   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
+// CHECK-OBJ: define linkonce_odr %struct.D* @_ZN1DaSERS_
+// CHECK-OBJ: {{call.*_ZN1AaSERS_}}
+// CHECK-OBJ: {{call.*_ZN1BaSERS_}}
+// CHECK-OBJ: {{call.*_ZN1CaSERKS_}}
+// CHECK-OBJ: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 24}}
+// CHECK-OBJ: {{call.*_ZN1BaSERS_}}
+// CHECK-OBJ: br
+// CHECK-OBJ: {{call.*_ZN1CaSERKS_}}
+// CHECK-OBJ: {{call.*@objc_memmove_collectable}}
+// CHECK-OBJ: {{call void @llvm.memcpy.p0i8.p0i8.i64.*i64 12}}
+// CHECK-OBJ: call void @_ZN11CopyByValueC1ERKS_
+// CHECK-OBJ: {{call.*_ZN11CopyByValueaSES_}}
+// CHECK-OBJ: ret
+#endif
 
+namespace PR13329 {
+#ifndef __OBJC__
+  typedef void* id;
+#endif
+  struct POD {
+    id    i;
+    short s;
+  };
+  
+  struct NonPOD {
+    id    i;
+    short s;
+    
+    NonPOD();
+  };
+  
+  struct DerivedNonPOD: NonPOD {
+    char  c;
+  };
+  
+  struct DerivedPOD: POD {
+    char  c;
+  };
+  
+  void testPOD() {
+    POD a;
+    POD b;
+    // CHECK-OBJ: @objc_memmove_collectable{{.*}}i64 16
+    // CHECK-CPP: @llvm.memcpy{{.*}}i64 16
+    b = a;
+  }
+  
+  void testNonPOD() {
+    NonPOD a;
+    NonPOD b;
+    // CHECK-OBJ: @objc_memmove_collectable{{.*}}i64 10
+    // CHECK-CPP: @llvm.memcpy{{.*}}i64 10
+    b = a;
+  }
+  
+  void testDerivedNonPOD() {
+    DerivedNonPOD a;
+    NonPOD        b;
+    DerivedNonPOD c;
+    // CHECK-OBJ: @objc_memmove_collectable{{.*}}i64 10
+    // CHECK-CPP: @llvm.memcpy{{.*}}i64 10
+    (NonPOD&) a = b;
+    // CHECK-OBJ: @objc_memmove_collectable{{.*}}i64 11
+    // CHECK-CPP: @llvm.memcpy{{.*}}i64 11
+    a = c;
+  };
+  
+  void testDerivedPOD() {
+    DerivedPOD a;
+    POD        b;
+    DerivedPOD c;
+    // CHECK-OBJ: @objc_memmove_collectable{{.*}}i64 16
+    // CHECK-CPP: @llvm.memcpy{{.*}}i64 16
+    (POD&) a = b;
+    // CHECK-OBJ: @objc_memmove_collectable{{.*}}i64 17
+    // CHECK-CPP: @llvm.memcpy{{.*}}i64 17
+    a = c;
+  };
+}
diff --git a/test/CodeGenOpenCL/kernel-attributes.cl b/test/CodeGenOpenCL/kernel-attributes.cl
index 014285f..de16a41 100644
--- a/test/CodeGenOpenCL/kernel-attributes.cl
+++ b/test/CodeGenOpenCL/kernel-attributes.cl
@@ -1,14 +1,12 @@
 // RUN: %clang_cc1 -emit-llvm -O0 -o - %s | FileCheck %s
 
-typedef float float4 __attribute__((ext_vector_type(4)));
-
 kernel __attribute__((reqd_work_group_size(1,2,4))) void kernel1(int a) {}
 
-kernel __attribute__((work_group_size_hint(8,16,32))) void kernel2(float4 a) {}
+kernel __attribute__((work_group_size_hint(8,16,32))) void kernel2(int a) {}
 
 // CHECK: opencl.kernels = !{[[MDNODE0:![0-9]+]], [[MDNODE3:![0-9]+]]}
 
 // CHECK: [[MDNODE0]] = metadata !{void (i32)* @kernel1, metadata [[MDNODE2:![0-9]+]]}
 // CHECK: [[MDNODE2]] = metadata !{metadata !"reqd_work_group_size", i32 1, i32 2, i32 4}
-// CHECK: [[MDNODE3]] = metadata !{void (<4 x float>)* @kernel2, metadata [[MDNODE5:![0-9]+]]}
+// CHECK: [[MDNODE3]] = metadata !{void (i32)* @kernel2, metadata [[MDNODE5:![0-9]+]]}
 // CHECK: [[MDNODE5]] = metadata !{metadata !"work_group_size_hint", i32 8, i32 16, i32 32}
diff --git a/test/CodeGenOpenCL/vectorLoadStore.cl b/test/CodeGenOpenCL/vectorLoadStore.cl
new file mode 100644
index 0000000..44bc7bd
--- /dev/null
+++ b/test/CodeGenOpenCL/vectorLoadStore.cl
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -emit-llvm -O0 -o - | FileCheck %s
+
+typedef char char3 __attribute((ext_vector_type(3)));;
+
+// Check for optimized vec3 load/store which treats vec3 as vec4.
+void foo(char3 *P, char3 *Q) {
+  *P = *Q;
+  // CHECK: %{{.*}} = shufflevector <4 x i8> %{{.*}}, <4 x i8> undef, <3 x i32> <i32 0, i32 1, i32 2>
+}
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/arm-linux-gnueabi/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/arm-linux-gnueabi/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/arm-linux-gnueabi/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/arm-linux-gnueabihf/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/arm-linux-gnueabihf/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/lib/arm-linux-gnueabihf/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/arm-linux-gnueabi/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/arm-linux-gnueabi/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/arm-linux-gnueabi/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/arm-linux-gnueabihf/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/arm-linux-gnueabihf/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/include/arm-linux-gnueabihf/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/.keep b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/.keep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/.keep
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crt1.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crt1.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crti.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crti.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crtn.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabi/crtn.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crt1.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crt1.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crt1.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crti.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crti.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crti.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crtn.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crtn.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/arm-linux-gnueabihf/crtn.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o
diff --git a/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/ubuntu_12.04_LTS_multiarch_tree/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o
diff --git a/test/Driver/Xlinker-args.c b/test/Driver/Xlinker-args.c
index b4e5a9b..d89d5ba 100644
--- a/test/Driver/Xlinker-args.c
+++ b/test/Driver/Xlinker-args.c
@@ -4,6 +4,13 @@
 // RUN: %clang -target i386-apple-darwin9 -### \
 // RUN:   -Xlinker one -Xlinker --no-demangle \
 // RUN:   -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
-// RUN: FileCheck < %t %s
+// RUN: FileCheck -check-prefix=DARWIN < %t %s
 //
-// CHECK: "one" "two" "three" "four"
+// RUN: %clang -target x86_64-pc-linux-gnu -### \
+// RUN:   -Xlinker one -Xlinker --no-demangle \
+// RUN:   -Wl,two,--no-demangle,three -Xlinker four %s 2> %t
+// RUN: FileCheck -check-prefix=LINUX < %t %s
+//
+// DARWIN-NOT: --no-demangle
+// DARWIN: "one" "two" "three" "four"
+// LINUX: "--no-demangle" "one" "two" "three" "four"
diff --git a/test/Driver/arc.c b/test/Driver/arc.c
index 5a5720c..1072e6b 100644
--- a/test/Driver/arc.c
+++ b/test/Driver/arc.c
@@ -8,10 +8,10 @@
 // Just to test clang is working.
 # foo
 
-// CHECK: error: -fobjc-arc is not supported with legacy abi
+// CHECK: error: -fobjc-arc is not supported on platforms using the legacy runtime
 // CHECK-NOT: invalid preprocessing directive
 
-// NOTOBJC-NOT: error: -fobjc-arc is not supported with legacy abi
+// NOTOBJC-NOT: error: -fobjc-arc is not supported on platforms using the legacy runtime
 // NOTOBJC: invalid preprocessing directive
 
-// UNSUPPORTED: error: -fobjc-arc is not supported on current deployment target
+// UNSUPPORTED: error: -fobjc-arc is not supported on versions of Mac OS prior to 10.6
diff --git a/test/Driver/arclite-link.c b/test/Driver/arclite-link.c
index 735555f..3471bf6 100644
--- a/test/Driver/arclite-link.c
+++ b/test/Driver/arclite-link.c
@@ -11,3 +11,7 @@
 // CHECK-ARCLITE-OSX: -lobjc
 // CHECK-NOARCLITE-NOT: libarclite
 // CHECK-NOSTDLIB-NOT: -lobjc
+
+// RUN: %clang -### -target x86_64-apple-darwin10 -fobjc-link-runtime -fobjc-arc -mmacosx-version-min=10.7 %s 2>&1 | FileCheck -check-prefix=CHECK-UNUSED %s
+
+// CHECK-UNUSED-NOT: warning: argument unused during compilation: '-fobjc-link-runtime'
diff --git a/test/Driver/ccc-as-cpp.c b/test/Driver/ccc-as-cpp.c
new file mode 100644
index 0000000..feead51
--- /dev/null
+++ b/test/Driver/ccc-as-cpp.c
@@ -0,0 +1,6 @@
+// REQUIRES: shell
+// RUN: ln -sf %clang %T/clang-cpp
+
+// PR13529: Don't crash.
+// RUN: %T/clang-cpp -lfoo -M %s 2>&1 | FileCheck --check-prefix=CHECK-PR13529 %s
+// CHECK-PR13529: warning: -lfoo: 'linker' input unused in cpp mode
diff --git a/test/Driver/clang_f_opts.h b/test/Driver/clang_f_opts.h
new file mode 100644
index 0000000..e48d0cf
--- /dev/null
+++ b/test/Driver/clang_f_opts.h
@@ -0,0 +1,2 @@
+// RUN: %clang -### -fsyntax-only %s 2>&1 | FileCheck %s
+// CHECK: -fsyntax-only
diff --git a/test/Driver/crash-report.c b/test/Driver/crash-report.c
index 9476ada..7adaf42 100644
--- a/test/Driver/crash-report.c
+++ b/test/Driver/crash-report.c
@@ -1,6 +1,10 @@
 // RUN: rm -rf %t
 // RUN: mkdir %t
-// RUN: env TMPDIR=%t TEMP=%t TMP=%t %clang -fsyntax-only %s -DFOO=BAR 2>&1 | FileCheck %s
+// RUN: env TMPDIR=%t TEMP=%t TMP=%t %clang -fsyntax-only %s \
+// RUN:  -F/tmp/ -I /tmp/ -idirafter /tmp/ -iquote /tmp/ -isystem /tmp/ \
+// RUN:  -iprefix /the/prefix -iwithprefix /tmp -iwithprefixbefore /tmp/ \
+// RUN:  -internal-isystem /tmp/ -internal-externc-isystem /tmp/ \
+// RUN:  -DFOO=BAR 2>&1 | FileCheck %s
 // RUN: cat %t/crash-report-*.c | FileCheck --check-prefix=CHECKSRC %s
 // RUN: cat %t/crash-report-*.sh | FileCheck --check-prefix=CHECKSH %s
 // REQUIRES: crash-recovery
@@ -10,4 +14,14 @@
 // CHECK-NEXT: note: diagnostic msg: {{.*}}.c
 FOO
 // CHECKSRC: FOO
-// CHECKSH: -D FOO=BAR
+// CHECKSH: -D "FOO=BAR"
+// CHECKSH-NOT: -F/tmp/
+// CHECKSH-NOT: -I /tmp/
+// CHECKSH-NOT: -idirafter /tmp/
+// CHECKSH-NOT: -iquote /tmp/
+// CHECKSH-NOT: -isystem /tmp/
+// CHECKSH-NOT: -iprefix /the/prefix
+// CHECKSH-NOT: -iwithprefix /tmp/
+// CHECKSH-NOT: -iwithprefixbefore /tmp/
+// CHECKSH-NOT: -internal-isystem /tmp/
+// CHECKSH-NOT: -internal-externc-isystem /tmp/
diff --git a/test/Driver/darwin-sdkroot.c b/test/Driver/darwin-sdkroot.c
new file mode 100644
index 0000000..5abf081
--- /dev/null
+++ b/test/Driver/darwin-sdkroot.c
@@ -0,0 +1,22 @@
+// Check that SDKROOT is used to define the default for -isysroot on Darwin.
+//
+// RUN: rm -rf %t.tmpdir
+// RUN: mkdir -p %t.tmpdir
+// RUN: env SDKROOT=%t.tmpdir %clang -target x86_64-apple-darwin10 \
+// RUN:   -c %s -### 2> %t.log
+// RUN: FileCheck --check-prefix=CHECK-BASIC < %t.log %s
+//
+// CHECK-BASIC: clang
+// CHECK-BASIC: "-cc1"
+// CHECK-BASIC: "-isysroot" "{{.*tmpdir}}"
+
+// Check that we don't use SDKROOT as the default if it is not a valid path.
+
+// RUN: rm -rf %t.nonpath
+// RUN: env SDKROOT=%t.nonpath %clang -target x86_64-apple-darwin10 \
+// RUN:   -c %s -### 2> %t.log
+// RUN: FileCheck --check-prefix=CHECK-NONPATH < %t.log %s
+//
+// CHECK-NONPATH: clang
+// CHECK-NONPATH: "-cc1"
+// CHECK-NONPATH-NOT: "-isysroot"
diff --git a/test/Driver/debug-options.c b/test/Driver/debug-options.c
index bdeb6ca..ca77abf 100644
--- a/test/Driver/debug-options.c
+++ b/test/Driver/debug-options.c
@@ -20,7 +20,7 @@
 // RUN: %clang -### -c -gline-tables-only -g0 %s 2>&1 \
 // RUN:             | FileCheck -check-prefix=GLTO_NO %s
 //
-// RUN: %clang -c -grecord-gcc-switches -gno-record-gcc-switches \
+// RUN: %clang -### -c -grecord-gcc-switches -gno-record-gcc-switches \
 // RUN:           -gstrict-dwarf -gno-strict-dwarf %s 2>&1 \
 // RUN:        | not grep "argument unused during compilation"
 //
diff --git a/test/Driver/freebsd.c b/test/Driver/freebsd.c
index 69da7c9..642c60c 100644
--- a/test/Driver/freebsd.c
+++ b/test/Driver/freebsd.c
@@ -32,7 +32,15 @@
 // Check that the new linker flags are passed to FreeBSD
 // RUN: %clang -no-canonical-prefixes -target x86_64-pc-freebsd8 -m32 %s \
 // RUN:   --sysroot=%S/Inputs/multiarch_freebsd64_tree -### 2>&1 \
-// RUN:   | FileCheck --check-prefix=CHECK-LDFLAGS %s
-// CHECK-LDFLAGS: --hash-style=both
-// CHECK-LDFLAGS: --enable-new-dtags
+// RUN:   | FileCheck --check-prefix=CHECK-LDFLAGS8 %s
+// RUN: %clang -no-canonical-prefixes -target x86_64-pc-freebsd9 -m32 %s \
+// RUN:   --sysroot=%S/Inputs/multiarch_freebsd64_tree -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LDFLAGS9 %s
+// RUN: %clang -no-canonical-prefixes -target x86_64-pc-freebsd10.0 -m32 %s \
+// RUN:   --sysroot=%S/Inputs/multiarch_freebsd64_tree -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-LDFLAGS9 %s
+// CHECK-LDFLAGS8-NOT: --hash-style=both
+// CHECK-LDFLAGS8: --enable-new-dtags
+// CHECK-LDFLAGS9: --hash-style=both
+// CHECK-LDFLAGS9: --enable-new-dtags
 
diff --git a/test/Driver/linux-ld.c b/test/Driver/linux-ld.c
index a9decfd..a6831b6 100644
--- a/test/Driver/linux-ld.c
+++ b/test/Driver/linux-ld.c
@@ -174,6 +174,39 @@
 // CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/lib"
 // CHECK-UBUNTU-11-04: "-L[[SYSROOT]]/usr/lib"
 //
+// Check multi arch support on Ubuntu 12.04 LTS.
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-unknown-linux-gnueabihf \
+// RUN:     --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM-HF %s
+// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf/crt1.o"
+// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf/crti.o"
+// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtbegin.o"
+// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabihf/4.6.3"
+// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf"
+// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/lib/arm-linux-gnueabihf"
+// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/arm-linux-gnueabihf"
+// CHECK-UBUNTU-12-04-ARM-HF: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../.."
+// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/crtend.o"
+// CHECK-UBUNTU-12-04-ARM-HF: "{{.*}}/usr/lib/gcc/arm-linux-gnueabihf/4.6.3/../../../arm-linux-gnueabihf/crtn.o"
+//
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-unknown-linux-gnueabi \
+// RUN:     --sysroot=%S/Inputs/ubuntu_12.04_LTS_multiarch_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBUNTU-12-04-ARM %s
+// CHECK-UBUNTU-12-04-ARM: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
+// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi/crt1.o"
+// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi/crti.o"
+// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o"
+// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabi/4.6.1"
+// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi"
+// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/lib/arm-linux-gnueabi"
+// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/arm-linux-gnueabi"
+// CHECK-UBUNTU-12-04-ARM: "-L[[SYSROOT]]/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../.."
+// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/crtend.o"
+// CHECK-UBUNTU-12-04-ARM: "{{.*}}/usr/lib/gcc/arm-linux-gnueabi/4.6.1/../../../arm-linux-gnueabi/crtn.o"
+//
 // Test the setup that shipped in SUSE 10.3 on ppc64.
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target powerpc64-suse-linux \
@@ -186,6 +219,21 @@
 // CHECK-SUSE-10-3-PPC64: "-L[[SYSROOT]]/lib/../lib64"
 // CHECK-SUSE-10-3-PPC64: "-L[[SYSROOT]]/usr/lib/../lib64"
 //
+// Check dynamic-linker for different archs
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-gnueabi \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM %s
+// CHECK-ARM: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ARM: "-m" "armelf_linux_eabi"
+// CHECK-ARM: "-dynamic-linker" "{{.*}}/lib/ld-linux.so.3"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-gnueabihf \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM-HF %s
+// CHECK-ARM-HF: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ARM-HF: "-m" "armelf_linux_eabi"
+// CHECK-ARM-HF: "-dynamic-linker" "{{.*}}/lib/ld-linux-armhf.so.3"
+//
 // Check that we do not pass --hash-style=gnu and --hash-style=both to linker
 // and provide correct path to the dynamic linker and emulation mode when build
 // for MIPS platforms.
diff --git a/test/Driver/stack-protector.c b/test/Driver/stack-protector.c
new file mode 100644
index 0000000..5f3d679
--- /dev/null
+++ b/test/Driver/stack-protector.c
@@ -0,0 +1,11 @@
+// RUN: %clang -fno-stack-protector -### %s 2>&1 | FileCheck %s -check-prefix=NOSSP
+// NOSSP-NOT: "-stack-protector" "1"
+// NOSSP-NOT: "-stack-protector-buffer-size" 
+
+// RUN: %clang -fstack-protector -### %s 2>&1 | FileCheck %s -check-prefix=SSP
+// SSP: "-stack-protector" "1"
+// SSP-NOT: "-stack-protector-buffer-size" 
+
+// RUN: %clang -fstack-protector --param ssp-buffer-size=16 -### %s 2>&1 | FileCheck %s -check-prefix=SSP-BUF
+// SSP-BUF: "-stack-protector" "1"
+// SSP-BUF: "-stack-protector-buffer-size" "16" 
diff --git a/test/Driver/warning-options.cpp b/test/Driver/warning-options.cpp
index ce434ab..ab0da42 100644
--- a/test/Driver/warning-options.cpp
+++ b/test/Driver/warning-options.cpp
@@ -3,7 +3,7 @@
 // RUN: %clang -### -Wlarge-by-value-copy=128 %s 2>&1 | FileCheck -check-prefix=LARGE_VALUE_COPY_JOINED %s
 // LARGE_VALUE_COPY_JOINED: -Wlarge-by-value-copy=128
 
-// RUN: %clang -c -Wmonkey -Wno-monkey -Wno-unused-command-line-arguments \
+// RUN: %clang -### -c -Wmonkey -Wno-monkey -Wno-unused-command-line-arguments \
 // RUN:        -Wno-unused-command-line-argument %s 2>&1 | FileCheck %s
 // CHECK: unknown warning option '-Wmonkey'
 // CHECK: unknown warning option '-Wno-monkey'
diff --git a/test/FixIt/fixit-vexing-parse.cpp b/test/FixIt/fixit-vexing-parse.cpp
index 8450590..dd0f873 100644
--- a/test/FixIt/fixit-vexing-parse.cpp
+++ b/test/FixIt/fixit-vexing-parse.cpp
@@ -7,6 +7,7 @@
 
 struct T {
   T();
+  T(S, S);
   int n;
 };
 
@@ -30,26 +31,44 @@
 
 namespace N {
   void test() {
-    // CHECK: fix-it:"{{.*}}":{34:9-34:11}:" = {}"
+    // CHECK: fix-it:"{{.*}}":{35:9-35:11}:" = {}"
     S s1(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{38:9-38:10}:";"
-    // CHECK: fix-it:"{{.*}}":{39:7-39:9}:" = {}"
+    // CHECK: fix-it:"{{.*}}":{39:9-39:10}:";"
+    // CHECK: fix-it:"{{.*}}":{40:7-40:9}:" = {}"
     S s2, // expected-note {{change this ',' to a ';' to call 'F2'}}
     F2(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{43:9-43:11}:""
     // CHECK: fix-it:"{{.*}}":{44:9-44:11}:""
+    // CHECK: fix-it:"{{.*}}":{45:9-45:11}:""
     T t1(), // expected-warning {{function declaration}} expected-note {{remove parentheses}}
       t2(); // expected-warning {{function declaration}} expected-note {{remove parentheses}}
 
-    // CHECK: fix-it:"{{.*}}":{47:8-47:10}:" = {}"
+    // Suggest parentheses only around the first argument.
+    // CHECK: fix-it:"{{.*}}":{50:10-50:10}:"("
+    // CHECK: fix-it:"{{.*}}":{50:13-50:13}:")"
+    T t3(S(), S()); // expected-warning {{disambiguated as a function declaration}} expected-note {{add a pair of parentheses}}
+
+    // Check fixit position for pathological case
+    // CHECK: fix-it:"{{.*}}":{56:11-56:11}:"("
+    // CHECK: fix-it:"{{.*}}":{56:20-56:20}:")"
+    float k[1];
+    int l(int(k[0])); // expected-warning {{disambiguated as a function declaration}} expected-note {{add a pair of parentheses}}
+
+    // Don't emit warning and fixit because this must be a function declaration due to void return type.
+    typedef void VO;
+    VO m(int (*p)[4]);
+
+    // Don't emit warning and fixit because direct initializer is not permitted here.
+    if (int n(int())){} // expected-error {{function type is not allowed here}} expected-error {{condition must have an initializer}}
+
+    // CHECK: fix-it:"{{.*}}":{66:8-66:10}:" = {}"
     U u(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{50:8-50:10}:""
+    // CHECK: fix-it:"{{.*}}":{69:8-69:10}:""
     V v(); // expected-warning {{function declaration}} expected-note {{remove parentheses}}
 
-    // CHECK: fix-it:"{{.*}}":{53:8-53:10}:""
+    // CHECK: fix-it:"{{.*}}":{72:8-72:10}:""
     W w(); // expected-warning {{function declaration}} expected-note {{remove parentheses}}
 
     // TODO: Removing the parens here would not initialize U::n.
@@ -57,33 +76,33 @@
     // Maybe suggest removing the parens anyway?
     X x(); // expected-warning {{function declaration}}
 
-    // CHECK: fix-it:"{{.*}}":{61:11-61:13}:" = 0"
+    // CHECK: fix-it:"{{.*}}":{80:11-80:13}:" = 0"
     int n1(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{65:11-65:12}:";"
-    // CHECK: fix-it:"{{.*}}":{66:7-66:9}:" = 0"
+    // CHECK: fix-it:"{{.*}}":{84:11-84:12}:";"
+    // CHECK: fix-it:"{{.*}}":{85:7-85:9}:" = 0"
     int n2, // expected-note {{change this ',' to a ';' to call 'F1'}}
     F1(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{69:13-69:15}:" = 0.0"
+    // CHECK: fix-it:"{{.*}}":{88:13-88:15}:" = 0.0"
     double d(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
     typedef void *Ptr;
 
-    // CHECK: fix-it:"{{.*}}":{74:10-74:12}:" = 0"
+    // CHECK: fix-it:"{{.*}}":{93:10-93:12}:" = 0"
     Ptr p(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
 #define NULL 0
-    // CHECK: fix-it:"{{.*}}":{78:10-78:12}:" = NULL"
+    // CHECK: fix-it:"{{.*}}":{97:10-97:12}:" = NULL"
     Ptr p(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{81:11-81:13}:" = false"
+    // CHECK: fix-it:"{{.*}}":{100:11-100:13}:" = false"
     bool b(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{84:11-84:13}:" = '\\0'"
+    // CHECK: fix-it:"{{.*}}":{103:11-103:13}:" = '\\0'"
     char c(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
 
-    // CHECK: fix-it:"{{.*}}":{87:15-87:17}:" = L'\\0'"
+    // CHECK: fix-it:"{{.*}}":{106:15-106:17}:" = L'\\0'"
     wchar_t wc(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}
   }
 }
diff --git a/test/Frontend/verify.c b/test/Frontend/verify.c
index 59a441d..f8d0f42 100644
--- a/test/Frontend/verify.c
+++ b/test/Frontend/verify.c
@@ -108,3 +108,18 @@
 // CHECK5-NEXT: 2 errors generated.
 #endif
 
+#if 0
+// RUN: %clang_cc1 -verify %t.invalid 2>&1 | FileCheck -check-prefix=CHECK6 %s
+
+//      CHECK6: error: 'error' diagnostics seen but not expected:
+// CHECK6-NEXT:   (frontend): error reading '{{.*}}verify.c.tmp.invalid'
+// CHECK6-NEXT: 1 error generated.
+
+// RUN: echo -e '//expected-error@2{{1}}\n#error 2' | %clang_cc1 -verify 2>&1 | FileCheck -check-prefix=CHECK7 %s
+
+//      CHECK7: error: 'error' diagnostics expected but not seen:
+// CHECK7-NEXT:   Line 2 (directive at <stdin>:1): 1
+// CHECK7-NEXT: error: 'error' diagnostics seen but not expected:
+// CHECK7-NEXT:   Line 2: 2
+// CHECK7-NEXT: 2 errors generated.
+#endif
diff --git a/test/Frontend/verify2.c b/test/Frontend/verify2.c
new file mode 100644
index 0000000..a1c7975
--- /dev/null
+++ b/test/Frontend/verify2.c
@@ -0,0 +1,19 @@
+#if 0
+// RUN: %clang_cc1 -verify %s 2>&1 | FileCheck %s
+
+// Please note that all comments are inside "#if 0" blocks so that
+// VerifyDiagnosticConsumer sees no comments while processing this
+// test-case.
+#endif
+
+#include "verify2.h"
+#error source
+
+#if 0
+// expected-error {{should be ignored}}
+
+//      CHECK: error: 'error' diagnostics seen but not expected:
+// CHECK-NEXT:   Line 1: header
+// CHECK-NEXT:   Line 10: source
+// CHECK-NEXT: 2 errors generated.
+#endif
diff --git a/test/Frontend/verify2.h b/test/Frontend/verify2.h
new file mode 100644
index 0000000..8acbf6e
--- /dev/null
+++ b/test/Frontend/verify2.h
@@ -0,0 +1,5 @@
+#error header
+
+#if 0
+// expected-error {{should be ignored}}
+#endif
diff --git a/test/Index/Inputs/CommentXML/invalid-function-01.xml b/test/Index/Inputs/CommentXML/invalid-function-01.xml
new file mode 100644
index 0000000..85f0669
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-01.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-02.xml b/test/Index/Inputs/CommentXML/invalid-function-02.xml
new file mode 100644
index 0000000..700711b
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-02.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-03.xml b/test/Index/Inputs/CommentXML/invalid-function-03.xml
new file mode 100644
index 0000000..0c4618f
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-03.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Term></Term>
+    <Definition><Para>Bbb.</Para></Definition>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-04.xml b/test/Index/Inputs/CommentXML/invalid-function-04.xml
new file mode 100644
index 0000000..88dd5a8
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-04.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Term> </Term>
+    <Definition><Para>Bbb.</Para></Definition>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-05.xml b/test/Index/Inputs/CommentXML/invalid-function-05.xml
new file mode 100644
index 0000000..ce96b7d
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-05.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Term>x1</Term>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-06.xml b/test/Index/Inputs/CommentXML/invalid-function-06.xml
new file mode 100644
index 0000000..5419c67
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-06.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa <monospaced></monospaced>.</Para></Abstract>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-07.xml b/test/Index/Inputs/CommentXML/invalid-function-07.xml
new file mode 100644
index 0000000..ce7ecce
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-07.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>-1</Index>
+    <Direction isExplicit="0">in</Direction>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-08.xml b/test/Index/Inputs/CommentXML/invalid-function-08.xml
new file mode 100644
index 0000000..66e69e8
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-08.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>0</Index>
+    <Direction isExplicit="aaa">in</Direction>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-09.xml b/test/Index/Inputs/CommentXML/invalid-function-09.xml
new file mode 100644
index 0000000..39617b6
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-09.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>0</Index>
+    <Direction isExplicit="0">aaa</Direction>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/invalid-function-10.xml b/test/Index/Inputs/CommentXML/invalid-function-10.xml
new file mode 100644
index 0000000..ccce4bb
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-10.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<TemplateParameters>
+  <Parameter>
+    <Name>x1</Name>
+  </Parameter>
+</TemplateParameters>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/invalid-function-11.xml b/test/Index/Inputs/CommentXML/invalid-function-11.xml
new file mode 100644
index 0000000..167911e
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-11.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<TemplateParameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>aaa</Index>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</TemplateParameters>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/invalid-function-12.xml b/test/Index/Inputs/CommentXML/invalid-function-12.xml
new file mode 100644
index 0000000..f5b5e03
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/invalid-function-12.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function templateKind="aaa">
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/valid-class-01.xml b/test/Index/Inputs/CommentXML/valid-class-01.xml
new file mode 100644
index 0000000..bd893e6
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-class-01.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Class>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Class>
diff --git a/test/Index/Inputs/CommentXML/valid-class-02.xml b/test/Index/Inputs/CommentXML/valid-class-02.xml
new file mode 100644
index 0000000..2e20a92
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-class-02.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Class templateKind="template">
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Class>
diff --git a/test/Index/Inputs/CommentXML/valid-class-03.xml b/test/Index/Inputs/CommentXML/valid-class-03.xml
new file mode 100644
index 0000000..2ce1a2c
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-class-03.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Class templateKind="specialization">
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Class>
diff --git a/test/Index/Inputs/CommentXML/valid-class-04.xml b/test/Index/Inputs/CommentXML/valid-class-04.xml
new file mode 100644
index 0000000..da1522d
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-class-04.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Class templateKind="partialSpecialization">
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Class>
diff --git a/test/Index/Inputs/CommentXML/valid-enum-01.xml b/test/Index/Inputs/CommentXML/valid-enum-01.xml
new file mode 100644
index 0000000..e346d73
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-enum-01.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Enum>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Enum>
+
diff --git a/test/Index/Inputs/CommentXML/valid-function-01.xml b/test/Index/Inputs/CommentXML/valid-function-01.xml
new file mode 100644
index 0000000..02060e7
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-01.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/valid-function-02.xml b/test/Index/Inputs/CommentXML/valid-function-02.xml
new file mode 100644
index 0000000..989d6a7
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-02.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa <bold>bbb</bold> <monospaced>ccc</monospaced> <emphasized>ddd</emphasized>.</Para></Abstract>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/valid-function-03.xml b/test/Index/Inputs/CommentXML/valid-function-03.xml
new file mode 100644
index 0000000..891211d
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-03.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Direction isExplicit="0">in</Direction>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/valid-function-04.xml b/test/Index/Inputs/CommentXML/valid-function-04.xml
new file mode 100644
index 0000000..b65b3e9
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-04.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>0</Index>
+    <Direction isExplicit="0">in</Direction>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</Parameters>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/valid-function-05.xml b/test/Index/Inputs/CommentXML/valid-function-05.xml
new file mode 100644
index 0000000..2dddbd7
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-05.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Discussion>
+  <Para>Ccc</Para>
+</Discussion>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/valid-function-06.xml b/test/Index/Inputs/CommentXML/valid-function-06.xml
new file mode 100644
index 0000000..1df3aa4
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-06.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<ResultDiscussion><Para>Ccc.</Para></ResultDiscussion>
+</Function>
diff --git a/test/Index/Inputs/CommentXML/valid-function-07.xml b/test/Index/Inputs/CommentXML/valid-function-07.xml
new file mode 100644
index 0000000..89b8a0c
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-07.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<Parameters>
+  <Parameter>
+    <Name>x2</Name>
+    <Index>0</Index>
+    <Direction isExplicit="0">in</Direction>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+  <Parameter>
+    <Name>x3</Name>
+    <Index>2</Index>
+    <Direction isExplicit="1">out</Direction>
+    <Discussion><Para>Ccc</Para></Discussion>
+  </Parameter>
+  <Parameter>
+    <Name>x1</Name>
+    <Direction isExplicit="1">in,out</Direction>
+    <Discussion><Para>Ddd</Para></Discussion>
+  </Parameter>
+</Parameters>
+<ResultDiscussion><Para>Eee.</Para></ResultDiscussion>
+<Discussion>
+  <Para>Fff</Para>
+  <Verbatim xml:space="preserve" kind="verbatim">Ggg</Verbatim>
+</Discussion>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/valid-function-08.xml b/test/Index/Inputs/CommentXML/valid-function-08.xml
new file mode 100644
index 0000000..481a6c0
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-08.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<TemplateParameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>0</Index>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+  <Parameter>
+    <Name>x2</Name>
+    <Discussion><Para>Ccc</Para></Discussion>
+  </Parameter>
+</TemplateParameters>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/valid-function-09.xml b/test/Index/Inputs/CommentXML/valid-function-09.xml
new file mode 100644
index 0000000..cf4cc8f
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-09.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function templateKind="template">
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/valid-function-10.xml b/test/Index/Inputs/CommentXML/valid-function-10.xml
new file mode 100644
index 0000000..4fadf30
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-function-10.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Function templateKind="specialization">
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Function>
+
diff --git a/test/Index/Inputs/CommentXML/valid-namespace-01.xml b/test/Index/Inputs/CommentXML/valid-namespace-01.xml
new file mode 100644
index 0000000..a73aad5
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-namespace-01.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Namespace>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Namespace>
+
diff --git a/test/Index/Inputs/CommentXML/valid-other-01.xml b/test/Index/Inputs/CommentXML/valid-other-01.xml
new file mode 100644
index 0000000..46b8a46
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-other-01.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Other>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Other>
diff --git a/test/Index/Inputs/CommentXML/valid-typedef-01.xml b/test/Index/Inputs/CommentXML/valid-typedef-01.xml
new file mode 100644
index 0000000..1b7da8d
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-typedef-01.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Typedef>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Typedef>
+
diff --git a/test/Index/Inputs/CommentXML/valid-typedef-02.xml b/test/Index/Inputs/CommentXML/valid-typedef-02.xml
new file mode 100644
index 0000000..2a32189
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-typedef-02.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Typedef>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+<TemplateParameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>0</Index>
+    <Discussion><Para>Bbb</Para></Discussion>
+  </Parameter>
+</TemplateParameters>
+<Parameters>
+  <Parameter>
+    <Name>x1</Name>
+    <Index>0</Index>
+    <Direction isExplicit="0">in</Direction>
+    <Discussion><Para>Ccc</Para></Discussion>
+  </Parameter>
+</Parameters>
+<ResultDiscussion><Para>Ddd.</Para></ResultDiscussion>
+<Discussion>
+  <Para>Eee.</Para>
+</Discussion>
+</Typedef>
+
diff --git a/test/Index/Inputs/CommentXML/valid-variable-01.xml b/test/Index/Inputs/CommentXML/valid-variable-01.xml
new file mode 100644
index 0000000..e17da91
--- /dev/null
+++ b/test/Index/Inputs/CommentXML/valid-variable-01.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Variable>
+<Name>aaa</Name>
+<Abstract><Para>Aaa.</Para></Abstract>
+</Variable>
+
diff --git a/test/Index/annotate-comments.cpp b/test/Index/annotate-comments.cpp
index 37ee0c8..f63525c 100644
--- a/test/Index/annotate-comments.cpp
+++ b/test/Index/annotate-comments.cpp
@@ -221,6 +221,32 @@
 /// \returns ddd IS_DOXYGEN_END
 void isdoxy50(int);
 
+// One of the following lines has trailing whitespace.  It is intended, don't
+// fix it.
+/**
+ * Aaa. IS_DOXYGEN_START
+ * 
+ * Bbb. IS_DOXYGEN_END
+ */
+void isdoxy51(int);
+
+// One of the following lines has trailing whitespace.  It is intended, don't
+// fix it.
+/**
+ * Aaa. IS_DOXYGEN_START
+ * Bbb.
+ *  
+ * Ccc. IS_DOXYGEN_END
+ */
+void isdoxy52(int);
+
+/**
+ * \fn isdoxy53
+ *
+ * Aaa. IS_DOXYGEN_START IS_DOXYGEN_END
+ */
+void isdoxy53(int);
+
 /// Aaa.
 void comment_to_html_conversion_1();
 
@@ -256,34 +282,68 @@
 /// \returns Bbb.
 void comment_to_html_conversion_8();
 
+/// Aaa.
+///
+/// \result Bbb.
+void comment_to_html_conversion_9();
+
 /// \returns Aaa.
 /// \returns Bbb.
-void comment_to_html_conversion_9();
+void comment_to_html_conversion_10();
 
 /// Aaa.
 ///
 /// Bbb.
 ///
 /// \returns Ccc.
-void comment_to_html_conversion_10();
+void comment_to_html_conversion_11();
 
 /// \param
-void comment_to_html_conversion_11(int x1);
-
-/// \param x1 Aaa.
 void comment_to_html_conversion_12(int x1);
 
-/// \param zzz Aaa.
+/// \param x1 Aaa.
 void comment_to_html_conversion_13(int x1);
 
+/// \param zzz Aaa.
+void comment_to_html_conversion_14(int x1);
+
 /// \param x2 Bbb.
 /// \param x1 Aaa.
-void comment_to_html_conversion_14(int x1, int x2);
+void comment_to_html_conversion_15(int x1, int x2);
 
 /// \param x2 Bbb.
 /// \param zzz Aaa.
 /// \param x1 Aaa.
-void comment_to_html_conversion_15(int x1, int x2);
+void comment_to_html_conversion_16(int x1, int x2);
+
+/// \tparam
+/// \param aaa Blah blah
+template<typename T>
+void comment_to_html_conversion_17(T aaa);
+
+/// \tparam T
+/// \param aaa Blah blah
+template<typename T>
+void comment_to_html_conversion_18(T aaa);
+
+/// \tparam T2 Bbb
+/// \tparam T1 Aaa
+template<typename T1, typename T2>
+void comment_to_html_conversion_19(T1 aaa, T2 bbb);
+
+/// \tparam T2 Bbb
+/// \tparam U Zzz
+/// \tparam V Ccc
+/// \tparam T1 Aaa
+template<typename T1, typename T2, int V>
+void comment_to_html_conversion_20(T1 aaa, T2 bbb);
+
+/// \tparam TTT Ddd
+/// \tparam C Ccc
+/// \tparam T Aaa
+/// \tparam TT Bbb
+template<template<template<typename T> class TT, class C> class TTT>
+void comment_to_html_conversion_21();
 
 /// \brief Aaa.
 ///
@@ -292,40 +352,135 @@
 /// \param x2 Ddd.
 /// \param x1 Ccc.
 /// \returns Eee.
-void comment_to_html_conversion_16(int x1, int x2);
+void comment_to_html_conversion_22(int x1, int x2);
 
 /// <br><a href="http://example.com/">Aaa</a>
-void comment_to_html_conversion_17();
+void comment_to_html_conversion_23();
 
 /// \verbatim
 /// <a href="http://example.com/">Aaa</a>
 /// <a href='http://example.com/'>Aaa</a>
 /// \endverbatim
-void comment_to_html_conversion_18();
+void comment_to_html_conversion_24();
+
+/// \function foo
+/// \class foo
+/// \method foo
+/// \interface foo
+/// Blah blah.
+void comment_to_html_conversion_25();
 
 /// \b Aaa
-void comment_to_html_conversion_19();
+void comment_to_html_conversion_26();
 
 /// \c Aaa \p Bbb
-void comment_to_html_conversion_20();
+void comment_to_html_conversion_27();
 
 /// \a Aaa \e Bbb \em Ccc
-void comment_to_html_conversion_21();
+void comment_to_html_conversion_28();
+
+/// \a 1<2 \e 3<4 \em 5<6 \param 7<8 aaa \tparam 9<10 bbb
+void comment_to_html_conversion_29();
 
 /// \\ \@ \& \$ \# \< \> \% \" \. \::
-void comment_to_html_conversion_22();
+void comment_to_html_conversion_30();
 
 /// &amp; &lt; &gt; &quot;
-void comment_to_html_conversion_23();
+void comment_to_html_conversion_31();
+
+/// <em>0&lt;i</em>
+void comment_to_html_conversion_32();
+
+/// Aaa.
+class comment_to_xml_conversion_01 {
+  /// \param aaa Blah blah.
+  comment_to_xml_conversion_01(int aaa);
+
+  /// Aaa.
+  ~comment_to_xml_conversion_01();
+
+  /// \param aaa Blah blah.
+  int comment_to_xml_conversion_02(int aaa);
+
+  /// \param aaa Blah blah.
+  static int comment_to_xml_conversion_03(int aaa);
+
+  /// Aaa.
+  int comment_to_xml_conversion_04;
+
+  /// Aaa.
+  static int comment_to_xml_conversion_05;
+
+  /// \param aaa Blah blah.
+  void operator()(int aaa);
+
+  /// Aaa.
+  operator bool();
+
+  /// Aaa.
+  typedef int comment_to_xml_conversion_06;
+
+  /// Aaa.
+  using comment_to_xml_conversion_07 = int;
+
+  template<typename T, typename U>
+  class comment_to_xml_conversion_08 { };
+
+  /// Aaa.
+  template<typename T>
+  using comment_to_xml_conversion_09 = comment_to_xml_conversion_08<T, int>;
+};
+
+/// Aaa.
+template<typename T, typename U>
+void comment_to_xml_conversion_10(T aaa, U bbb);
+
+/// Aaa.
+template<>
+void comment_to_xml_conversion_10(int aaa, int bbb);
+
+/// Aaa.
+template<typename T, typename U>
+class comment_to_xml_conversion_11 { };
+
+/// Aaa.
+template<typename T>
+class comment_to_xml_conversion_11<T, int> { };
+
+/// Aaa.
+template<>
+class comment_to_xml_conversion_11<int, int> { };
+
+/// Aaa.
+int comment_to_xml_conversion_12;
+
+/// Aaa.
+namespace comment_to_xml_conversion_13 {
+  /// Aaa.
+  namespace comment_to_xml_conversion_14 {
+  }
+}
+
+/// Aaa.
+enum comment_to_xml_conversion_15 {
+  /// Aaa.
+  comment_to_xml_conversion_16
+};
+
+/// Aaa.
+enum class comment_to_xml_conversion_17 {
+  /// Aaa.
+  comment_to_xml_conversion_18
+};
 
 #endif
 
 // RUN: rm -rf %t
 // RUN: mkdir %t
-// RUN: %clang_cc1 -x c++ -emit-pch -o %t/out.pch %s
-// RUN: %clang_cc1 -x c++ -include-pch %t/out.pch -fsyntax-only %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-pch -o %t/out.pch %s
+// RUN: %clang_cc1 -x c++ -std=c++11 -include-pch %t/out.pch -fsyntax-only %s
 
-// RUN: c-index-test -test-load-source all %s > %t/out.c-index-direct
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 > %t/out.c-index-direct
 // RUN: c-index-test -test-load-tu %t/out.pch all > %t/out.c-index-pch
 
 // RUN: FileCheck %s -check-prefix=WRONG < %t/out.c-index-direct
@@ -344,6 +499,9 @@
 // Ensure we don't pick up extra comments.
 // WRONG-NOT: IS_DOXYGEN_START{{.*}}IS_DOXYGEN_START{{.*}}BriefComment=
 // WRONG-NOT: IS_DOXYGEN_END{{.*}}IS_DOXYGEN_END{{.*}}BriefComment=
+//
+// Ensure that XML is not invalid
+// WRONG-NOT: CommentXMLInvalid
 
 // RUN: FileCheck %s < %t/out.c-index-direct
 // RUN: FileCheck %s < %t/out.c-index-pch
@@ -386,13 +544,15 @@
 // CHECK: annotate-comments.cpp:214:6: FunctionDecl=isdoxy48:{{.*}} BriefComment=[IS_DOXYGEN_START Aaa bbb]
 // CHECK: annotate-comments.cpp:218:6: FunctionDecl=isdoxy49:{{.*}} BriefComment=[IS_DOXYGEN_START Aaa]
 // CHECK: annotate-comments.cpp:222:6: FunctionDecl=isdoxy50:{{.*}} BriefComment=[Returns ddd IS_DOXYGEN_END]
+// CHECK: annotate-comments.cpp:231:6: FunctionDecl=isdoxy51:{{.*}} BriefComment=[Aaa. IS_DOXYGEN_START]
+// CHECK: annotate-comments.cpp:241:6: FunctionDecl=isdoxy52:{{.*}} BriefComment=[Aaa. IS_DOXYGEN_START Bbb.]
 
-// CHECK: annotate-comments.cpp:225:6: FunctionDecl=comment_to_html_conversion_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>]
+// CHECK: annotate-comments.cpp:251:6: FunctionDecl=comment_to_html_conversion_1:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="251" column="6"><Name>comment_to_html_conversion_1</Name><USR>c:@F@comment_to_html_conversion_1#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
 // CHECK-NEXT:         (CXComment_Text Text=[ Aaa.])))]
-// CHECK: annotate-comments.cpp:228:6: FunctionDecl=comment_to_html_conversion_2:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>]
+// CHECK: annotate-comments.cpp:254:6: FunctionDecl=comment_to_html_conversion_2:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="254" column="6"><Name>comment_to_html_conversion_2</Name><USR>c:@F@comment_to_html_conversion_2#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -400,7 +560,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[brief]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
-// CHECK: annotate-comments.cpp:231:6: FunctionDecl=comment_to_html_conversion_3:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>]
+// CHECK: annotate-comments.cpp:257:6: FunctionDecl=comment_to_html_conversion_3:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="257" column="6"><Name>comment_to_html_conversion_3</Name><USR>c:@F@comment_to_html_conversion_3#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -408,7 +568,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[short]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
-// CHECK: annotate-comments.cpp:236:6: FunctionDecl=comment_to_html_conversion_4:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p>]
+// CHECK: annotate-comments.cpp:262:6: FunctionDecl=comment_to_html_conversion_4:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="262" column="6"><Name>comment_to_html_conversion_4</Name><USR>c:@F@comment_to_html_conversion_4#</USR><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -418,7 +578,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[brief]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
-// CHECK: annotate-comments.cpp:243:6: FunctionDecl=comment_to_html_conversion_5:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p><p> Ccc.</p>]
+// CHECK: annotate-comments.cpp:269:6: FunctionDecl=comment_to_html_conversion_5:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Bbb.</p><p> Aaa.</p><p> Ccc.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="269" column="6"><Name>comment_to_html_conversion_5</Name><USR>c:@F@comment_to_html_conversion_5#</USR><Abstract><Para> Bbb.</Para></Abstract><Discussion><Para> Aaa.</Para><Para> Ccc.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -430,7 +590,7 @@
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.])))
 // CHECK-NEXT:       (CXComment_Paragraph
 // CHECK-NEXT:         (CXComment_Text Text=[ Ccc.])))]
-// CHECK: annotate-comments.cpp:247:6: FunctionDecl=comment_to_html_conversion_6:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa. </p><p class="para-brief"> Bbb.</p>]
+// CHECK: annotate-comments.cpp:273:6: FunctionDecl=comment_to_html_conversion_6:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa. </p><p class="para-brief"> Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="273" column="6"><Name>comment_to_html_conversion_6</Name><USR>c:@F@comment_to_html_conversion_6#</USR><Abstract><Para> Aaa. </Para></Abstract><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -442,7 +602,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[brief]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
-// CHECK: annotate-comments.cpp:252:6: FunctionDecl=comment_to_html_conversion_7:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p>]
+// CHECK: annotate-comments.cpp:278:6: FunctionDecl=comment_to_html_conversion_7:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="278" column="6"><Name>comment_to_html_conversion_7</Name><USR>c:@F@comment_to_html_conversion_7#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -452,7 +612,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[return]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
-// CHECK: annotate-comments.cpp:257:6: FunctionDecl=comment_to_html_conversion_8:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p>]
+// CHECK: annotate-comments.cpp:283:6: FunctionDecl=comment_to_html_conversion_8:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="283" column="6"><Name>comment_to_html_conversion_8</Name><USR>c:@F@comment_to_html_conversion_8#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -462,7 +622,17 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[returns]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
-// CHECK: annotate-comments.cpp:261:6: FunctionDecl=comment_to_html_conversion_9:{{.*}} FullCommentAsHTML=[<p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span>  Aaa. </p>]
+// CHECK: annotate-comments.cpp:288:6: FunctionDecl=comment_to_html_conversion_9:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="288" column="6"><Name>comment_to_html_conversion_9</Name><USR>c:@F@comment_to_html_conversion_9#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Bbb.</Para></ResultDiscussion></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ Aaa.]))
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_BlockCommand CommandName=[result]
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
+// CHECK: annotate-comments.cpp:292:6: FunctionDecl=comment_to_html_conversion_10:{{.*}} FullCommentAsHTML=[<p class="para-returns"><span class="word-returns">Returns</span>  Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span>  Aaa. </p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="292" column="6"><Name>comment_to_html_conversion_10</Name><USR>c:@F@comment_to_html_conversion_10#</USR><ResultDiscussion><Para> Aaa. </Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -474,7 +644,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[returns]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Bbb.]))))]
-// CHECK: annotate-comments.cpp:268:6: FunctionDecl=comment_to_html_conversion_10:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span>  Ccc.</p>]
+// CHECK: annotate-comments.cpp:299:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><p class="para-returns"><span class="word-returns">Returns</span>  Ccc.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="299" column="6"><Name>comment_to_html_conversion_11</Name><USR>c:@F@comment_to_html_conversion_11#</USR><Abstract><Para> Aaa.</Para></Abstract><ResultDiscussion><Para> Ccc.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -486,14 +656,14 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[returns]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Ccc.]))))]
-// CHECK: annotate-comments.cpp:271:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[]
+// CHECK: annotate-comments.cpp:302:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="302" column="6"><Name>comment_to_html_conversion_12</Name><USR>c:@F@comment_to_html_conversion_12#I#</USR></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
 // CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[] ParamIndex=Invalid
 // CHECK-NEXT:         (CXComment_Paragraph IsWhitespace)))]
-// CHECK: annotate-comments.cpp:274:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>]
+// CHECK: annotate-comments.cpp:305:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="305" column="6"><Name>comment_to_html_conversion_13</Name><USR>c:@F@comment_to_html_conversion_13#I#</USR><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -501,7 +671,7 @@
 // CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
-// CHECK: annotate-comments.cpp:277:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>]
+// CHECK: annotate-comments.cpp:308:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="308" column="6"><Name>comment_to_html_conversion_14</Name><USR>c:@F@comment_to_html_conversion_14#I#</USR><Parameters><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -509,7 +679,7 @@
 // CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[zzz] ParamIndex=Invalid
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
-// CHECK: annotate-comments.cpp:281:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>]
+// CHECK: annotate-comments.cpp:312:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="312" column="6"><Name>comment_to_html_conversion_15</Name><USR>c:@F@comment_to_html_conversion_15#I#I#</USR><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -521,7 +691,7 @@
 // CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
-// CHECK: annotate-comments.cpp:286:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>]
+// CHECK: annotate-comments.cpp:317:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="317" column="6"><Name>comment_to_html_conversion_16</Name><USR>c:@F@comment_to_html_conversion_16#I#I#</USR><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa.</Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Bbb. </Para></Discussion></Parameter><Parameter><Name>zzz</Name><Direction isExplicit="0">in</Direction><Discussion><Para> Aaa. </Para></Discussion></Parameter></Parameters></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -537,7 +707,81 @@
 // CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Aaa.]))))]
-// CHECK: annotate-comments.cpp:295:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><p class="para-returns"><span class="word-returns">Returns</span>  Eee.</p>]
+// CHECK: annotate-comments.cpp:322:6: FunctionTemplate=comment_to_html_conversion_17:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="322" column="6"><Name>comment_to_html_conversion_17</Name><USR>c:@FT@&gt;1#Tcomment_to_html_conversion_17#t0.0#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[] ParamPosition=Invalid
+// CHECK-NEXT:         (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[aaa] ParamIndex=0
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Blah blah]))))]
+// CHECK: annotate-comments.cpp:327:6: FunctionTemplate=comment_to_html_conversion_18:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">aaa</dt><dd class="param-descr-index-0"> Blah blah</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="327" column="6"><Name>comment_to_html_conversion_18</Name><USR>c:@FT@&gt;1#Tcomment_to_html_conversion_18#t0.0#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[T] ParamPosition={0}
+// CHECK-NEXT:         (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[aaa] ParamIndex=0
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Blah blah]))))]
+// CHECK: annotate-comments.cpp:332:6: FunctionTemplate=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="332" column="6"><Name>comment_to_html_conversion_19</Name><USR>c:@FT@&gt;2#T#Tcomment_to_html_conversion_19#t0.0#t0.1#</USR><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[T2] ParamPosition={1}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Bbb] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[T1] ParamPosition={0}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Aaa]))))]
+// CHECK: annotate-comments.cpp:339:6: FunctionTemplate=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">T1</dt><dd class="tparam-descr-index-0"> Aaa</dd><dt class="tparam-name-index-1">T2</dt><dd class="tparam-descr-index-1"> Bbb </dd><dt class="tparam-name-index-2">V</dt><dd class="tparam-descr-index-2"> Ccc </dd><dt class="tparam-name-index-invalid">U</dt><dd class="tparam-descr-index-invalid"> Zzz </dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="339" column="6"><Name>comment_to_html_conversion_20</Name><USR>c:@FT@&gt;3#T#T#NIcomment_to_html_conversion_20#t0.0#t0.1#</USR><TemplateParameters><Parameter><Name>T1</Name><Index>0</Index><Discussion><Para> Aaa</Para></Discussion></Parameter><Parameter><Name>T2</Name><Index>1</Index><Discussion><Para> Bbb </Para></Discussion></Parameter><Parameter><Name>V</Name><Index>2</Index><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>U</Name><Discussion><Para> Zzz </Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[T2] ParamPosition={1}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Bbb] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[U] ParamPosition=Invalid
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Zzz] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[V] ParamPosition={2}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Ccc] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[T1] ParamPosition={0}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Aaa]))))]
+// CHECK: annotate-comments.cpp:346:6: FunctionTemplate=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<dl><dt class="tparam-name-index-0">TTT</dt><dd class="tparam-descr-index-0"> Ddd </dd><dt class="tparam-name-index-other">C</dt><dd class="tparam-descr-index-other"> Ccc </dd><dt class="tparam-name-index-other">T</dt><dd class="tparam-descr-index-other"> Aaa </dd><dt class="tparam-name-index-other">TT</dt><dd class="tparam-descr-index-other"> Bbb</dd></dl>] FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="346" column="6"><Name>comment_to_html_conversion_21</Name><USR>c:@FT@&gt;1#t&gt;2#t&gt;1#T#Tcomment_to_html_conversion_21#</USR><TemplateParameters><Parameter><Name>TTT</Name><Index>0</Index><Discussion><Para> Ddd </Para></Discussion></Parameter><Parameter><Name>C</Name><Discussion><Para> Ccc </Para></Discussion></Parameter><Parameter><Name>T</Name><Discussion><Para> Aaa </Para></Discussion></Parameter><Parameter><Name>TT</Name><Discussion><Para> Bbb</Para></Discussion></Parameter></TemplateParameters></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[TTT] ParamPosition={0}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Ddd] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[C] ParamPosition={0, 1}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Ccc] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[T] ParamPosition={0, 0, 0}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Aaa] HasTrailingNewline)
+// CHECK-NEXT:           (CXComment_Text Text=[ ] IsWhitespace)))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[TT] ParamPosition={0, 0}
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ Bbb]))))]
+// CHECK: annotate-comments.cpp:355:6: FunctionDecl=comment_to_html_conversion_22:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><p class="para-returns"><span class="word-returns">Returns</span>  Eee.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="355" column="6"><Name>comment_to_html_conversion_22</Name><USR>c:@F@comment_to_html_conversion_22#I#I#</USR><Abstract><Para> Aaa.</Para></Abstract><Parameters><Parameter><Name>x1</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ccc. </Para></Discussion></Parameter><Parameter><Name>x2</Name><Index>1</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Ddd. </Para></Discussion></Parameter></Parameters><ResultDiscussion><Para> Eee.</Para></ResultDiscussion><Discussion><Para> Bbb.</Para></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -560,7 +804,7 @@
 // CHECK-NEXT:       (CXComment_BlockCommand CommandName=[returns]
 // CHECK-NEXT:         (CXComment_Paragraph
 // CHECK-NEXT:           (CXComment_Text Text=[ Eee.]))))]
-// CHECK: annotate-comments.cpp:298:6: FunctionDecl=comment_to_html_conversion_17:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <br><a href="http://example.com/">Aaa</a></p>]
+// CHECK: annotate-comments.cpp:358:6: FunctionDecl=comment_to_html_conversion_23:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <br><a href="http://example.com/">Aaa</a></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="358" column="6"><Name>comment_to_html_conversion_23</Name><USR>c:@F@comment_to_html_conversion_23#</USR><Abstract><Para> <rawHTML><![CDATA[<br>]]></rawHTML><rawHTML><![CDATA[<a href="http://example.com/">]]></rawHTML>Aaa<rawHTML>&lt;/a&gt;</rawHTML></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -569,7 +813,7 @@
 // CHECK-NEXT:         (CXComment_HTMLStartTag Name=[a] Attrs: href=http://example.com/)
 // CHECK-NEXT:         (CXComment_Text Text=[Aaa])
 // CHECK-NEXT:         (CXComment_HTMLEndTag Name=[a])))]
-// CHECK: annotate-comments.cpp:304:6: FunctionDecl=comment_to_html_conversion_18:{{.*}} FullCommentAsHTML=[<pre> &lt;a href=&quot;http:&#47;&#47;example.com&#47;&quot;&gt;Aaa&lt;&#47;a&gt;\n &lt;a href=&#39;http:&#47;&#47;example.com&#47;&#39;&gt;Aaa&lt;&#47;a&gt;</pre>]
+// CHECK: annotate-comments.cpp:364:6: FunctionDecl=comment_to_html_conversion_24:{{.*}} FullCommentAsHTML=[<pre> &lt;a href=&quot;http:&#47;&#47;example.com&#47;&quot;&gt;Aaa&lt;&#47;a&gt;\n &lt;a href=&#39;http:&#47;&#47;example.com&#47;&#39;&gt;Aaa&lt;&#47;a&gt;</pre>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="364" column="6"><Name>comment_to_html_conversion_24</Name><USR>c:@F@comment_to_html_conversion_24#</USR><Discussion><Verbatim xml:space="preserve" kind="verbatim"> &lt;a href=&quot;http://example.com/&quot;&gt;Aaa&lt;/a&gt;\n &lt;a href=&apos;http://example.com/&apos;&gt;Aaa&lt;/a&gt;</Verbatim></Discussion></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph IsWhitespace
@@ -577,13 +821,30 @@
 // CHECK-NEXT:       (CXComment_VerbatimBlockCommand CommandName=[verbatim]
 // CHECK-NEXT:         (CXComment_VerbatimBlockLine Text=[ <a href="http://example.com/">Aaa</a>])
 // CHECK-NEXT:         (CXComment_VerbatimBlockLine Text=[ <a href='http://example.com/'>Aaa</a>])))]
-// CHECK: annotate-comments.cpp:307:6: FunctionDecl=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <b>Aaa</b></p>]
+// CHECK: annotate-comments.cpp:371:6: FunctionDecl=comment_to_html_conversion_25:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Blah blah.</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="371" column="6"><Name>comment_to_html_conversion_25</Name><USR>c:@F@comment_to_html_conversion_25#</USR><Abstract><Para> Blah blah.</Para></Abstract></Function>]
+// CHECK:  CommentAST=[
+// CHECK:    (CXComment_FullComment
+// CHECK:       (CXComment_Paragraph IsWhitespace
+// CHECK:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK:       (CXComment_VerbatimLine Text=[ foo])
+// CHECK:       (CXComment_Paragraph IsWhitespace
+// CHECK:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK:       (CXComment_VerbatimLine Text=[ foo])
+// CHECK:       (CXComment_Paragraph IsWhitespace
+// CHECK:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK:       (CXComment_VerbatimLine Text=[ foo])
+// CHECK:       (CXComment_Paragraph IsWhitespace
+// CHECK:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK:       (CXComment_VerbatimLine Text=[ foo])
+// CHECK:       (CXComment_Paragraph
+// CHECK:         (CXComment_Text Text=[ Blah blah.])))]
+// CHECK: annotate-comments.cpp:374:6: FunctionDecl=comment_to_html_conversion_26:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <b>Aaa</b></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="374" column="6"><Name>comment_to_html_conversion_26</Name><USR>c:@F@comment_to_html_conversion_26#</USR><Abstract><Para> <bold>Aaa</bold></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[b] RenderBold Arg[0]=Aaa)))]
-// CHECK: annotate-comments.cpp:310:6: FunctionDecl=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>]
+// CHECK: annotate-comments.cpp:377:6: FunctionDecl=comment_to_html_conversion_27:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="377" column="6"><Name>comment_to_html_conversion_27</Name><USR>c:@F@comment_to_html_conversion_27#</USR><Abstract><Para> <monospaced>Aaa</monospaced> <monospaced>Bbb</monospaced></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -591,7 +852,7 @@
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=Aaa)
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[p] RenderMonospaced Arg[0]=Bbb)))]
-// CHECK: annotate-comments.cpp:313:6: FunctionDecl=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>]
+// CHECK: annotate-comments.cpp:380:6: FunctionDecl=comment_to_html_conversion_28:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="380" column="6"><Name>comment_to_html_conversion_28</Name><USR>c:@F@comment_to_html_conversion_28#</USR><Abstract><Para> <emphasized>Aaa</emphasized> <emphasized>Bbb</emphasized> <emphasized>Ccc</emphasized></Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -601,7 +862,24 @@
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[e] RenderEmphasized Arg[0]=Bbb)
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_InlineCommand CommandName=[em] RenderEmphasized Arg[0]=Ccc)))]
-// CHECK: annotate-comments.cpp:316:6: FunctionDecl=comment_to_html_conversion_22:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ &amp; $ # &lt; &gt; % &quot; . ::</p>]
+// CHECK: annotate-comments.cpp:383:6: FunctionDecl=comment_to_html_conversion_29:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>1&lt;2</em> <em>3&lt;4</em> <em>5&lt;6</em> </p><dl><dt class="tparam-name-index-invalid">9&lt;10</dt><dd class="tparam-descr-index-invalid"> bbb</dd></dl><dl><dt class="param-name-index-invalid">7&lt;8</dt><dd class="param-descr-index-invalid"> aaa </dd></dl>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="383" column="6"><Name>comment_to_html_conversion_29</Name><USR>c:@F@comment_to_html_conversion_29#</USR><Abstract><Para> <emphasized>1&lt;2</emphasized> <emphasized>3&lt;4</emphasized> <emphasized>5&lt;6</emphasized> </Para></Abstract><TemplateParameters><Parameter><Name>9&lt;10</Name><Discussion><Para> bbb</Para></Discussion></Parameter></TemplateParameters><Parameters><Parameter><Name>7&lt;8</Name><Direction isExplicit="0">in</Direction><Discussion><Para> aaa </Para></Discussion></Parameter></Parameters></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_InlineCommand CommandName=[a] RenderEmphasized Arg[0]=1<2)
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_InlineCommand CommandName=[e] RenderEmphasized Arg[0]=3<4)
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_InlineCommand CommandName=[em] RenderEmphasized Arg[0]=5<6)
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace))
+// CHECK-NEXT:       (CXComment_ParamCommand in implicitly ParamName=[7<8] ParamIndex=Invalid
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ aaa ])))
+// CHECK-NEXT:       (CXComment_TParamCommand ParamName=[9<10] ParamPosition=Invalid
+// CHECK-NEXT:         (CXComment_Paragraph
+// CHECK-NEXT:           (CXComment_Text Text=[ bbb]))))]
+// CHECK: annotate-comments.cpp:386:6: FunctionDecl=comment_to_html_conversion_30:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ &amp; $ # &lt; &gt; % &quot; . ::</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="386" column="6"><Name>comment_to_html_conversion_30</Name><USR>c:@F@comment_to_html_conversion_30#</USR><Abstract><Para> \ @ &amp; $ # &lt; &gt; % &quot; . ::</Para></Abstract></Function>]
 // CHECK-NEXT:  CommentAST=[
 // CHECK-NEXT:    (CXComment_FullComment
 // CHECK-NEXT:       (CXComment_Paragraph
@@ -627,9 +905,50 @@
 // CHECK-NEXT:         (CXComment_Text Text=[.])
 // CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
 // CHECK-NEXT:         (CXComment_Text Text=[::])))]
-// CHECK: annotate-comments.cpp:319:6: FunctionDecl=comment_to_html_conversion_23:{{.*}} FullCommentAsHTML=[<p class="para-brief"> &amp;amp; &amp;lt; &amp;gt; &amp;quot;</p>]
-// CHECK:  CommentAST=[
-// CHECK:    (CXComment_FullComment
-// CHECK:       (CXComment_Paragraph
-// CHECK:         (CXComment_Text Text=[ &amp; &lt; &gt; &quot;])))]
+// CHECK: annotate-comments.cpp:389:6: FunctionDecl=comment_to_html_conversion_31:{{.*}} FullCommentAsHTML=[<p class="para-brief"> &amp; &lt; &gt; &quot;</p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="389" column="6"><Name>comment_to_html_conversion_31</Name><USR>c:@F@comment_to_html_conversion_31#</USR><Abstract><Para> &amp; &lt; &gt; &quot;</Para></Abstract></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_Text Text=[&])
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_Text Text=[<])
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_Text Text=[>])
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_Text Text=["])))]
+// CHECK: annotate-comments.cpp:392:6: FunctionDecl=comment_to_html_conversion_32:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>0&lt;i</em></p>] FullCommentAsXML=[<Function file="{{[^"]+}}annotate-comments.cpp" line="392" column="6"><Name>comment_to_html_conversion_32</Name><USR>c:@F@comment_to_html_conversion_32#</USR><Abstract><Para> <rawHTML><![CDATA[<em>]]></rawHTML>0&lt;i<rawHTML>&lt;/em&gt;</rawHTML></Para></Abstract></Function>]
+// CHECK-NEXT:  CommentAST=[
+// CHECK-NEXT:    (CXComment_FullComment
+// CHECK-NEXT:       (CXComment_Paragraph
+// CHECK-NEXT:         (CXComment_Text Text=[ ] IsWhitespace)
+// CHECK-NEXT:         (CXComment_HTMLStartTag Name=[em])
+// CHECK-NEXT:         (CXComment_Text Text=[0])
+// CHECK-NEXT:         (CXComment_Text Text=[<])
+// CHECK-NEXT:         (CXComment_Text Text=[i])
+// CHECK-NEXT:         (CXComment_HTMLEndTag Name=[em])))]
 
+// CHECK: annotate-comments.cpp:395:7: ClassDecl=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments.cpp" line="395" column="7"><Name>comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:397:3: CXXConstructor=comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="397" column="3"><Name>comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01@F@comment_to_xml_conversion_01#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:400:3: CXXDestructor=~comment_to_xml_conversion_01:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="400" column="3"><Name>~comment_to_xml_conversion_01</Name><USR>c:@C@comment_to_xml_conversion_01@F@~comment_to_xml_conversion_01#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:403:7: CXXMethod=comment_to_xml_conversion_02:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="403" column="7"><Name>comment_to_xml_conversion_02</Name><USR>c:@C@comment_to_xml_conversion_01@F@comment_to_xml_conversion_02#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:406:14: CXXMethod=comment_to_xml_conversion_03:{{.*}} FullCommentAsXML=[<Function isClassMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="406" column="14"><Name>comment_to_xml_conversion_03</Name><USR>c:@C@comment_to_xml_conversion_01@F@comment_to_xml_conversion_03#I#S</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:409:7: FieldDecl=comment_to_xml_conversion_04:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="409" column="7"><Name>comment_to_xml_conversion_04</Name><USR>c:@C@comment_to_xml_conversion_01@FI@comment_to_xml_conversion_04</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:412:14: VarDecl=comment_to_xml_conversion_05:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="412" column="14"><Name>comment_to_xml_conversion_05</Name><USR>c:@C@comment_to_xml_conversion_01@comment_to_xml_conversion_05</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:415:8: CXXMethod=operator():{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="415" column="8"><Name>operator()</Name><USR>c:@C@comment_to_xml_conversion_01@F@operator()#I#</USR><Parameters><Parameter><Name>aaa</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> Blah blah.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: annotate-comments.cpp:418:3: CXXConversion=operator _Bool:{{.*}} FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}annotate-comments.cpp" line="418" column="3"><Name>operator _Bool</Name><USR>c:@C@comment_to_xml_conversion_01@F@operator _Bool#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:421:15: TypedefDecl=comment_to_xml_conversion_06:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="421" column="15"><Name>comment_to_xml_conversion_06</Name><USR>c:annotate-comments.cpp@8492@C@comment_to_xml_conversion_01@T@comment_to_xml_conversion_06</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
+// CHECK: annotate-comments.cpp:424:9: TypeAliasDecl=comment_to_xml_conversion_07:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="424" column="9"><Name>comment_to_xml_conversion_07</Name><USR>c:@C@comment_to_xml_conversion_01@comment_to_xml_conversion_07</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
+// CHECK: annotate-comments.cpp:431:3: UnexposedDecl=comment_to_xml_conversion_09:{{.*}} FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments.cpp" line="431" column="3"><Name>comment_to_xml_conversion_09</Name><USR>c:@C@comment_to_xml_conversion_01@comment_to_xml_conversion_09</USR><Abstract><Para> Aaa.</Para></Abstract></Typedef>]
+// CHECK: annotate-comments.cpp:436:6: FunctionTemplate=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="436" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@FT@&gt;2#T#Tcomment_to_xml_conversion_10#t0.0#t0.1#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:440:6: FunctionDecl=comment_to_xml_conversion_10:{{.*}} FullCommentAsXML=[<Function templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="440" column="6"><Name>comment_to_xml_conversion_10</Name><USR>c:@F@comment_to_xml_conversion_10&lt;#I#I&gt;#I#I#</USR><Abstract><Para> Aaa.</Para></Abstract></Function>]
+// CHECK: annotate-comments.cpp:444:7: ClassTemplate=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="template" file="{{[^"]+}}annotate-comments.cpp" line="444" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CT&gt;2#T#T@comment_to_xml_conversion_11</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:448:7: ClassTemplatePartialSpecialization=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="partialSpecialization" file="{{[^"]+}}annotate-comments.cpp" line="448" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@CP&gt;1#T@comment_to_xml_conversion_11&gt;#t0.0#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:452:7: ClassDecl=comment_to_xml_conversion_11:{{.*}} FullCommentAsXML=[<Class templateKind="specialization" file="{{[^"]+}}annotate-comments.cpp" line="452" column="7"><Name>comment_to_xml_conversion_11</Name><USR>c:@C@comment_to_xml_conversion_11&gt;#I#I</USR><Abstract><Para> Aaa.</Para></Abstract></Class>]
+// CHECK: annotate-comments.cpp:455:5: VarDecl=comment_to_xml_conversion_12:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="455" column="5"><Name>comment_to_xml_conversion_12</Name><USR>c:@comment_to_xml_conversion_12</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:458:11: Namespace=comment_to_xml_conversion_13:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="458" column="11"><Name>comment_to_xml_conversion_13</Name><USR>c:@N@comment_to_xml_conversion_13</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>]
+// CHECK: annotate-comments.cpp:460:13: Namespace=comment_to_xml_conversion_14:{{.*}} FullCommentAsXML=[<Namespace file="{{[^"]+}}annotate-comments.cpp" line="460" column="13"><Name>comment_to_xml_conversion_14</Name><USR>c:@N@comment_to_xml_conversion_13@N@comment_to_xml_conversion_14</USR><Abstract><Para> Aaa.</Para></Abstract></Namespace>]
+// CHECK: annotate-comments.cpp:465:6: EnumDecl=comment_to_xml_conversion_15:{{.*}} FullCommentAsXML=[<Enum file="{{[^"]+}}annotate-comments.cpp" line="465" column="6"><Name>comment_to_xml_conversion_15</Name><USR>c:@E@comment_to_xml_conversion_15</USR><Abstract><Para> Aaa.</Para></Abstract></Enum>]
+// CHECK: annotate-comments.cpp:467:3: EnumConstantDecl=comment_to_xml_conversion_16:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="467" column="3"><Name>comment_to_xml_conversion_16</Name><USR>c:@E@comment_to_xml_conversion_15@comment_to_xml_conversion_16</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
+// CHECK: annotate-comments.cpp:471:12: EnumDecl=comment_to_xml_conversion_17:{{.*}} FullCommentAsXML=[<Enum file="{{[^"]+}}annotate-comments.cpp" line="471" column="12"><Name>comment_to_xml_conversion_17</Name><USR>c:@E@comment_to_xml_conversion_17</USR><Abstract><Para> Aaa.</Para></Abstract></Enum>]
+// CHECK: annotate-comments.cpp:473:3: EnumConstantDecl=comment_to_xml_conversion_18:{{.*}} FullCommentAsXML=[<Variable file="{{[^"]+}}annotate-comments.cpp" line="473" column="3"><Name>comment_to_xml_conversion_18</Name><USR>c:@E@comment_to_xml_conversion_17@comment_to_xml_conversion_18</USR><Abstract><Para> Aaa.</Para></Abstract></Variable>]
diff --git a/test/Index/comment-xml-schema.c b/test/Index/comment-xml-schema.c
new file mode 100644
index 0000000..1166e78
--- /dev/null
+++ b/test/Index/comment-xml-schema.c
@@ -0,0 +1,43 @@
+// REQUIRES: xmllint
+
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-other-01.xml
+//
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-01.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-02.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-03.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-04.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-05.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-06.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-07.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-08.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-function-09.xml
+//
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-01.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-02.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-03.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-class-04.xml
+//
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-variable-01.xml
+//
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-namespace-01.xml
+//
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-typedef-01.xml
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-typedef-02.xml
+//
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/valid-enum-01.xml
+
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-01.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-02.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-03.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-04.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-05.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-06.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-07.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-08.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-09.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-10.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-11.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+// RUN: xmllint --noout --relaxng %S/../../bindings/xml/comment-xml-schema.rng %S/Inputs/CommentXML/invalid-function-12.xml 2>&1 | FileCheck %s -check-prefix=INVALID
+
+// CHECK-INVALID: fails to validate
+
diff --git a/test/Index/complete-documentation.cpp b/test/Index/complete-documentation.cpp
index 6cb7ca6..a64e62f 100644
--- a/test/Index/complete-documentation.cpp
+++ b/test/Index/complete-documentation.cpp
@@ -17,17 +17,35 @@
 namespace T5 {
 }
 
-void test() {
+struct T6 {
+ /// \brief Fff.
+ void T7();
 
-  T2 t2;
-  t2.
+ /// \brief Ggg.
+ void T8();
+};
+
+void T6::T7() {
 }
 
-// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:21:1 %s | FileCheck -check-prefix=CC1 %s
+void test1() {
+
+  T2 t2;
+  t2.T4;
+
+  T6 t6;
+  t6.T8();
+}
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:32:1 %s | FileCheck -check-prefix=CC1 %s
 // CHECK-CC1: FunctionDecl:{ResultType void}{TypedText T1}{{.*}}(brief comment: Aaa.)
 // CHECK-CC1: ClassDecl:{TypedText T2}{{.*}}(brief comment: Bbb.)
 // CHECK-CC1: Namespace:{TypedText T5}{{.*}}(brief comment: Eee.)
 
-// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:23:6 %s | FileCheck -check-prefix=CC2 %s
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:34:6 %s | FileCheck -check-prefix=CC2 %s
 // CHECK-CC2: CXXMethod:{ResultType void}{TypedText T3}{{.*}}(brief comment: Ccc.)
 // CHECK-CC2: FieldDecl:{ResultType int}{TypedText T4}{{.*}}(brief comment: Ddd.)
+
+// RUN: env CINDEXTEST_COMPLETION_BRIEF_COMMENTS=1 c-index-test -code-completion-at=%s:37:6 %s | FileCheck -check-prefix=CC3 %s
+// CHECK-CC3: CXXMethod:{ResultType void}{TypedText T7}{LeftParen (}{RightParen )} (34) (parent: StructDecl 'T6')(brief comment: Fff.)
+// CHECK-CC3: CXXMethod:{ResultType void}{TypedText T8}{LeftParen (}{RightParen )} (34) (parent: StructDecl 'T6')(brief comment: Ggg.)
diff --git a/test/Index/complete-enums.cpp b/test/Index/complete-enums.cpp
index 49a8932..23c60ac 100644
--- a/test/Index/complete-enums.cpp
+++ b/test/Index/complete-enums.cpp
@@ -1,6 +1,6 @@
 // Note: the run lines follow their respective tests, since line/column
 // matter in this test.
-
+struct X { X(); ~X(); };
 enum class Color {
   Red = 17,
   Green,
@@ -9,7 +9,7 @@
 int Greeby();
 void f(Color color) {
   switch (color) {
-  case Color::Green:
+  case Color::Green: { X x; }
   case Color::Red;
   }
 }
diff --git a/test/Index/complete-exprs.m b/test/Index/complete-exprs.m
index 3fb1540..16eeda9 100644
--- a/test/Index/complete-exprs.m
+++ b/test/Index/complete-exprs.m
@@ -21,7 +21,7 @@
 // CHECK-CC1: NotImplemented:{ResultType NSString *}{TypedText @"}{Placeholder string}{Text "} (40)
 // CHECK-CC1: NotImplemented:{ResultType id}{TypedText @(}{Placeholder expression}{RightParen )} (40)
 // CHECK-CC1: NotImplemented:{ResultType NSArray *}{TypedText @[}{Placeholder objects, ...}{RightBracket ]} (40)
-// CHECK-CC1: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{HorizontalSpace  }{Colon :}{HorizontalSpace  }{Placeholder object, ...}{RightBrace }} (40)
+// CHECK-CC1: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{Colon :}{HorizontalSpace  }{Placeholder object, ...}{RightBrace }} (40)
 // CHECK-CC1: NotImplemented:{ResultType SEL}{TypedText _cmd} (80)
 // CHECK-CC1: TypedefDecl:{TypedText BOOL} (50)
 // CHECK-CC1: macro definition:{TypedText bool} (51)
@@ -43,7 +43,7 @@
 // RUN: c-index-test -code-completion-at=%s:16:5 %s | FileCheck -check-prefix=CHECK-CC4 %s
 // RUN: c-index-test -code-completion-at=%s:16:14 %s | FileCheck -check-prefix=CHECK-CC4 %s
 // CHECK-CC4: NotImplemented:{ResultType NSArray *}{TypedText @[}{Placeholder objects, ...}{RightBracket ]} (40)
-// CHECK-CC4: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{HorizontalSpace  }{Colon :}{HorizontalSpace  }{Placeholder object, ...}{RightBrace }} (40)
+// CHECK-CC4: NotImplemented:{ResultType NSDictionary *}{TypedText @{}{Placeholder key}{Colon :}{HorizontalSpace  }{Placeholder object, ...}{RightBrace }} (40)
 // CHECK-CC4: NotImplemented:{ResultType SEL}{TypedText _cmd} (80)
 // CHECK-CC4: macro definition:{TypedText bool} (51)
 // CHECK-CC4: macro definition:{TypedText NO} (65)
diff --git a/test/Index/complete-lambdas.mm b/test/Index/complete-lambdas.mm
new file mode 100644
index 0000000..3f77dd2
--- /dev/null
+++ b/test/Index/complete-lambdas.mm
@@ -0,0 +1,51 @@
+// This test is line- and column-sensitive. See below for run lines.
+
+
+@interface A
+- instanceMethod:(int)value withOther:(int)other;
++ classMethod;
+@end
+
+@interface B : A
+@end
+
+@implementation B
+- someMethod:(A*)a {
+  [a classMethod];
+  [A classMethod];
+  [a instanceMethod:0 withOther:1];
+  [self someMethod:a];
+  [super instanceMethod];
+  [&,a ]{};
+  [a,self instanceMethod:0 withOther:1]{};  
+}
+
+@end
+
+// RUN: c-index-test -code-completion-at=%s:14:6 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// CHECK-CC1: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod:}{Placeholder (int)}{HorizontalSpace  }{TypedText withOther:}{Placeholder (int)} (35) (parent: ObjCInterfaceDecl 'A')
+
+// RUN: c-index-test -code-completion-at=%s:15:6 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC2 %s
+// CHECK-CC2: ObjCClassMethodDecl:{ResultType id}{TypedText classMethod} (35) (parent: ObjCInterfaceDecl 'A')
+
+// RUN: c-index-test -code-completion-at=%s:16:4 -std=c++11 %s | FileCheck -check-prefix=CHECK-CC3 %s
+// CHECK-CC3: ObjCInterfaceDecl:{TypedText A} (50) (parent: TranslationUnit '(null)')
+// CHECK-CC3: ParmDecl:{ResultType A *}{TypedText a} (34)
+// CHECK-CC3: ObjCInterfaceDecl:{TypedText B} (50) (parent: TranslationUnit '(null)')
+// CHECK-CC3: TypedefDecl:{TypedText Class} (50) (parent: TranslationUnit '(null)')
+
+
+// RUN: c-index-test -code-completion-at=%s:16:21 -x objective-c++ -std=c++11 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: NotImplemented:{ResultType B *}{TypedText self} (34)
+// CHECK-CC4: NotImplemented:{ResultType A *}{TypedText super} (40)
+
+// RUN: c-index-test -code-completion-at=%s:18:10 -x objective-c++ -std=c++11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+
+// RUN: c-index-test -code-completion-at=%s:19:8 -x objective-c++ -std=c++11 %s | FileCheck -check-prefix=CHECK-CC5 %s
+// CHECK-CC5: NotImplemented:{ResultType SEL}{TypedText _cmd} (80)
+// CHECK-CC5-NEXT: NotImplemented:{ResultType B *}{TypedText self} (34)
+
+// RUN: c-index-test -code-completion-at=%s:20:11 -x objective-c++ -std=c++11 %s | FileCheck -check-prefix=CHECK-CC6 %s
+// CHECK-CC6: ObjCInstanceMethodDecl:{ResultType id}{TypedText instanceMethod:}{Placeholder (int)}{HorizontalSpace  }{TypedText withOther:}{Placeholder (int)} (37) (parent: ObjCInterfaceDecl 'A')
+// CHECK-CC6-NEXT: ObjCInstanceMethodDecl:{ResultType id}{TypedText someMethod:}{Placeholder (A *)} (32) (parent: ObjCImplementationDecl 'B')
+
diff --git a/test/Index/complete-preamble.cpp b/test/Index/complete-preamble.cpp
new file mode 100644
index 0000000..8f48105
--- /dev/null
+++ b/test/Index/complete-preamble.cpp
@@ -0,0 +1,8 @@
+#include "complete-preamble.h"
+void f() {
+  std::
+}
+
+// RUN: env CINDEXTEST_EDITING=1 c-index-test -code-completion-at=%s:3:8 %s -o - | FileCheck -check-prefix=CC1 %s
+// CHECK-CC1: {ResultType void}{TypedText wibble}{LeftParen (}{RightParen )} (50) (parent: Namespace 'std')
+
diff --git a/test/Index/complete-preamble.h b/test/Index/complete-preamble.h
new file mode 100644
index 0000000..e696284
--- /dev/null
+++ b/test/Index/complete-preamble.h
@@ -0,0 +1,6 @@
+namespace std {
+  void wibble();
+}
+
+namespace std {
+}
diff --git a/test/Index/complete-property-flags.m b/test/Index/complete-property-flags.m
index f2e08c3..86ee8e2 100644
--- a/test/Index/complete-property-flags.m
+++ b/test/Index/complete-property-flags.m
@@ -6,7 +6,8 @@
 }
 @property(copy) Foo *myprop;
 @property(retain, nonatomic) id xx;
-// RUN: c-index-test -code-completion-at=%s:7:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
+
+// RUN: c-index-test -code-completion-at=%s:7:11 %s -fno-objc-arc | FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: {TypedText assign}
 // CHECK-CC1-NEXT: {TypedText atomic}
 // CHECK-CC1-NEXT: {TypedText copy}
@@ -18,9 +19,26 @@
 // CHECK-CC1-NEXT: {TypedText setter}{Text  = }{Placeholder method}
 // CHECK-CC1-NEXT: {TypedText strong}
 // CHECK-CC1-NEXT: {TypedText unsafe_unretained}
+// CHECK-CC1-NOT: {TypedText weak}
+
+// RUN: c-index-test -code-completion-at=%s:7:11 %s -fobjc-arc -fobjc-runtime=macosx-10.7 | FileCheck -check-prefix=CHECK-CC1-ARC %s
+// CHECK-CC1-ARC: {TypedText assign}
+// CHECK-CC1-ARC-NEXT: {TypedText atomic}
+// CHECK-CC1-ARC-NEXT: {TypedText copy}
+// CHECK-CC1-ARC-NEXT: {TypedText getter}{Text  = }{Placeholder method}
+// CHECK-CC1-ARC-NEXT: {TypedText nonatomic}
+// CHECK-CC1-ARC-NEXT: {TypedText readonly}
+// CHECK-CC1-ARC-NEXT: {TypedText readwrite}
+// CHECK-CC1-ARC-NEXT: {TypedText retain}
+// CHECK-CC1-ARC-NEXT: {TypedText setter}{Text  = }{Placeholder method}
+// CHECK-CC1-ARC-NEXT: {TypedText strong}
+// CHECK-CC1-ARC-NEXT: {TypedText unsafe_unretained}
+// CHECK-CC1-ARC-NEXT: {TypedText weak}
+
 // RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
 // CHECK-CC2: {TypedText getter}{Text  = }{Placeholder method}
 // CHECK-CC2-NEXT: {TypedText nonatomic}
+// CHECK-CC2-NEXT: {TypedText readonly}
 // CHECK-CC2-NEXT: {TypedText readwrite}
 // CHECK-CC2-NEXT: {TypedText setter}{Text  = }{Placeholder method}
 @end
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index f7c23df..06c70eb 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -1,4 +1,5 @@
-RUN: diagtool list-warnings | FileCheck %s
+RUN: diagtool list-warnings > %t 2>&1
+RUN: FileCheck --input-file=%t %s
 
 This test serves two purposes:
 
@@ -17,7 +18,27 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (131):
+CHECK: Warnings without flags (159):
+CHECK-NEXT:   ext_delete_void_ptr_operand
+CHECK-NEXT:   ext_enum_friend
+CHECK-NEXT:   ext_expected_semi_decl_list
+CHECK-NEXT:   ext_explicit_specialization_storage_class
+CHECK-NEXT:   ext_implicit_lib_function_decl
+CHECK-NEXT:   ext_missing_declspec
+CHECK-NEXT:   ext_missing_whitespace_after_macro_name
+CHECK-NEXT:   ext_new_paren_array_nonconst
+CHECK-NEXT:   ext_plain_complex
+CHECK-NEXT:   ext_pp_macro_redef
+CHECK-NEXT:   ext_template_arg_extra_parens
+CHECK-NEXT:   ext_typecheck_comparison_of_distinct_pointers
+CHECK-NEXT:   ext_typecheck_comparison_of_distinct_pointers_nonstandard
+CHECK-NEXT:   ext_typecheck_comparison_of_pointer_integer
+CHECK-NEXT:   ext_typecheck_cond_incompatible_operands
+CHECK-NEXT:   ext_typecheck_cond_incompatible_operands_nonstandard
+CHECK-NEXT:   ext_typecheck_ordered_comparison_of_function_pointers
+CHECK-NEXT:   ext_typecheck_ordered_comparison_of_pointer_integer
+CHECK-NEXT:   ext_unknown_escape
+CHECK-NEXT:   ext_using_undefined_std
 CHECK-NEXT:   pp_include_next_absolute_path
 CHECK-NEXT:   pp_include_next_in_primary
 CHECK-NEXT:   pp_invalid_string_literal
@@ -50,35 +71,41 @@
 CHECK-NEXT:   warn_double_const_requires_fp64
 CHECK-NEXT:   warn_drv_assuming_mfloat_abi_is
 CHECK-NEXT:   warn_drv_clang_unsupported
-CHECK-NEXT:   warn_drv_input_file_unused
 CHECK-NEXT:   warn_drv_not_using_clang_arch
 CHECK-NEXT:   warn_drv_not_using_clang_cpp
 CHECK-NEXT:   warn_drv_not_using_clang_cxx
 CHECK-NEXT:   warn_drv_objc_gc_unsupported
 CHECK-NEXT:   warn_drv_pch_not_first_include
-CHECK-NEXT:   warn_drv_preprocessed_input_file_unused
 CHECK-NEXT:   warn_dup_category_def
 CHECK-NEXT:   warn_duplicate_protocol_def
 CHECK-NEXT:   warn_enum_too_large
 CHECK-NEXT:   warn_enum_value_overflow
 CHECK-NEXT:   warn_enumerator_too_large
 CHECK-NEXT:   warn_exception_caught_by_earlier_handler
+CHECK-NEXT:   warn_excess_initializers
+CHECK-NEXT:   warn_excess_initializers_in_char_array_initializer
+CHECK-NEXT:   warn_expected_qualified_after_typename
 CHECK-NEXT:   warn_extraneous_char_constant
 CHECK-NEXT:   warn_fe_cc_log_diagnostics_failure
 CHECK-NEXT:   warn_fe_cc_print_header_failure
 CHECK-NEXT:   warn_fe_macro_contains_embedded_newline
 CHECK-NEXT:   warn_file_asm_volatile
+CHECK-NEXT:   warn_hex_escape_too_large
 CHECK-NEXT:   warn_ignoring_ftabstop_value
 CHECK-NEXT:   warn_implements_nscopying
 CHECK-NEXT:   warn_incompatible_qualified_id
+CHECK-NEXT:   warn_initializer_string_for_char_array_too_long
 CHECK-NEXT:   warn_inline_namespace_reopened_noninline
 CHECK-NEXT:   warn_integer_too_large
 CHECK-NEXT:   warn_integer_too_large_for_signed
 CHECK-NEXT:   warn_invalid_asm_cast_lvalue
+CHECK-NEXT:   warn_many_braces_around_scalar_init
 CHECK-NEXT:   warn_maynot_respond
 CHECK-NEXT:   warn_member_extra_qualification
 CHECK-NEXT:   warn_method_param_redefinition
+CHECK-NEXT:   warn_mismatched_exception_spec
 CHECK-NEXT:   warn_missing_case_for_condition
+CHECK-NEXT:   warn_missing_dependent_template_keyword
 CHECK-NEXT:   warn_missing_exception_specification
 CHECK-NEXT:   warn_missing_whitespace_after_macro_name
 CHECK-NEXT:   warn_multiple_method_decl
@@ -87,8 +114,10 @@
 CHECK-NEXT:   warn_not_compound_assign
 CHECK-NEXT:   warn_objc_property_copy_missing_on_block
 CHECK-NEXT:   warn_objc_protocol_qualifier_missing_id
+CHECK-NEXT:   warn_octal_escape_too_large
 CHECK-NEXT:   warn_odr_tag_type_inconsistent
 CHECK-NEXT:   warn_on_superclass_use
+CHECK-NEXT:   warn_param_default_argument_redefinition
 CHECK-NEXT:   warn_partial_specs_not_deducible
 CHECK-NEXT:   warn_pp_convert_lhs_to_positive
 CHECK-NEXT:   warn_pp_convert_rhs_to_positive
@@ -135,6 +164,7 @@
 CHECK-NEXT:   warn_second_parameter_to_va_arg_never_compatible
 CHECK-NEXT:   warn_standalone_specifier
 CHECK-NEXT:   warn_static_inline_explicit_inst_ignored
+CHECK-NEXT:   warn_static_non_static
 CHECK-NEXT:   warn_template_export_unsupported
 CHECK-NEXT:   warn_template_spec_extra_headers
 CHECK-NEXT:   warn_tentative_incomplete_array
@@ -144,7 +174,6 @@
 CHECK-NEXT:   warn_undef_interface_suggest
 CHECK-NEXT:   warn_undef_protocolref
 CHECK-NEXT:   warn_undefined_internal
-CHECK-NEXT:   warn_unknown_analyzer_checker
 CHECK-NEXT:   warn_unknown_method_family
 CHECK-NEXT:   warn_use_out_of_scope_declaration
 CHECK-NEXT:   warn_weak_identifier_undeclared
@@ -152,4 +181,4 @@
 
 The list of warnings in -Wpedantic should NEVER grow.
 
-CHECK: Number in -Wpedantic (not covered by other -W flags): 70
+CHECK: Number in -Wpedantic (not covered by other -W flags): 39
diff --git a/test/Modules/Inputs/category_right.h b/test/Modules/Inputs/category_right.h
index d993b50..812a840 100644
--- a/test/Modules/Inputs/category_right.h
+++ b/test/Modules/Inputs/category_right.h
@@ -8,5 +8,5 @@
 -(void)right2;
 @end
 
-@interface Foo(Duplicate) // expected-warning {{duplicate definition of category}}
+@interface Foo(Duplicate)
 @end
diff --git a/test/Modules/lookup.cpp b/test/Modules/lookup.cpp
index 9839035..70d2107 100644
--- a/test/Modules/lookup.cpp
+++ b/test/Modules/lookup.cpp
@@ -5,6 +5,8 @@
 #define IMPORT(X) @__experimental_modules_import X
 IMPORT(lookup_right_cxx);
 
+// in lookup_left.hpp: expected-warning@3 {{weak identifier 'weak_identifier' never declared}}
+
 void test(int i, float f) {
   // unqualified lookup
   f0(&i);
diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m
index 340f279..b267592 100644
--- a/test/Modules/objc-categories.m
+++ b/test/Modules/objc-categories.m
@@ -12,6 +12,7 @@
 
 
 // in category_left.h: expected-note {{previous definition}}
+// in category_right.h: expected-warning@11 {{duplicate definition of category}}
 
 @interface Foo(Source)
 -(void)source; 
diff --git a/test/PCH/objc_methods.m b/test/PCH/objc_methods.m
index e90a463..e8aab84 100644
--- a/test/PCH/objc_methods.m
+++ b/test/PCH/objc_methods.m
@@ -1,5 +1,5 @@
 // Test this without pch.
-// RUN: %clang_cc1 -include %S/objc_methods.h -fsyntax-only -verify %s
+// RUN: %clang_cc1 -include %S/objc_methods.h -fsyntax-only -Wno-objc-root-class -verify %s
 
 // Test with pch.
 // RUN: %clang_cc1 -x objective-c -emit-pch -o %t %S/objc_methods.h
diff --git a/test/PCH/objc_stmts.m b/test/PCH/objc_stmts.m
index 3bc728c..b9b10c5 100644
--- a/test/PCH/objc_stmts.m
+++ b/test/PCH/objc_stmts.m
@@ -1,11 +1,11 @@
 // Test this without pch.
 // RUN: %clang_cc1 -include %S/objc_stmts.h -emit-llvm -fobjc-exceptions -o - %s
-// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-dump -fobjc-exceptions -o - %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-dump -fobjc-exceptions -o - %s | FileCheck %s
 
 // Test with pch.
 // RUN: %clang_cc1 -x objective-c -emit-pch -fobjc-exceptions -o %t %S/objc_stmts.h
 // RUN: %clang_cc1 -include-pch %t -emit-llvm -fobjc-exceptions -o - %s 
-// RUN: %clang_cc1 -include-pch %t -ast-dump -fobjc-exceptions -o - %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -include-pch %t -ast-dump -fobjc-exceptions -o - %s | FileCheck %s
 
 // CHECK: catch parm = "A *a"
 // CHECK: catch parm = "B *b"
diff --git a/test/Parser/MicrosoftExtensions.c b/test/Parser/MicrosoftExtensions.c
index fd0c543..7703999 100644
--- a/test/Parser/MicrosoftExtensions.c
+++ b/test/Parser/MicrosoftExtensions.c
@@ -54,8 +54,8 @@
 typedef enum E { e1 };
 
 
-enum __declspec(deprecated) E2 { i, j, k };
-__declspec(deprecated) enum E3 { a, b, c } e;
+enum __declspec(deprecated) E2 { i, j, k }; // expected-note {{declared here}}
+__declspec(deprecated) enum E3 { a, b, c } e; // expected-note {{declared here}}
 
 void deprecated_enum_test(void)
 {
@@ -94,7 +94,7 @@
 
 struct S7 {
 	int foo() { return 12; }
-	__declspec(property(get=foo) deprecated) int t;
+	__declspec(property(get=foo) deprecated) int t; // expected-note {{declared here}}
 };
 
 /* Technically, this is legal (though it does nothing) */
diff --git a/test/Parser/cxx-casting.cpp b/test/Parser/cxx-casting.cpp
index 42ad12e..01980d3 100644
--- a/test/Parser/cxx-casting.cpp
+++ b/test/Parser/cxx-casting.cpp
@@ -58,9 +58,9 @@
               expected-error {{expected ']'}}
 #define LC <:
 #define C :
-  test1::A LC:B> c; // expected-error {{cannot refer to class template 'A' without a template argument list}} expected-error 2{{}} expected-note{{}}
+  test1::A LC:B> c; // expected-error {{class template test1::A requires template arguments}} expected-error 2{{}}
   (void)static_cast LC:c>(&x); // expected-error {{expected '<' after 'static_cast'}} expected-error 2{{}} expected-note{{}}
-  test1::A<:C B> d; // expected-error {{cannot refer to class template 'A' without a template argument list}} expected-error 2{{}} expected-note{{}}
+  test1::A<:C B> d; // expected-error {{class template test1::A requires template arguments}} expected-error 2{{}}
   (void)static_cast<:C c>(&x); // expected-error {{expected '<' after 'static_cast'}} expected-error 2{{}} expected-note{{}}
 
 #define LCC <::
@@ -85,8 +85,10 @@
   E< ::F>();
 
   // Make sure that parser doesn't expand '[:' to '< ::'
-  ::D[:F> A5; // expected-error {{cannot refer to class template 'D' without a template argument list}} \
+  ::D[:F> A5; // expected-error {{class template ::D requires template arguments}} \
               // expected-error {{expected expression}} \
-              // expected-error {{expected ']'}} \
-              // expected-note {{to match this '['}}
+              // expected-error {{expected unqualified-id}}
 }
+
+// PR13619. Must be at end of file.
+int n = reinterpret_cast // expected-error {{expected '<'}} expected-error {{expected ';'}}
diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp
index 951cd3d..30ac279 100644
--- a/test/Parser/cxx-decl.cpp
+++ b/test/Parser/cxx-decl.cpp
@@ -119,6 +119,9 @@
 
 ;
 
+// PR4111
+void f(sqrgl); // expected-error {{unknown type name 'sqrgl'}}
+
 // PR8380
 extern ""      // expected-error {{unknown linkage language}}
 test6a { ;// expected-error {{C++ requires a type specifier for all declarations}} \
diff --git a/test/Parser/cxx-template-argument.cpp b/test/Parser/cxx-template-argument.cpp
index 5479961..afe318d 100644
--- a/test/Parser/cxx-template-argument.cpp
+++ b/test/Parser/cxx-template-argument.cpp
@@ -25,3 +25,20 @@
     (void)(&t<S<int>>==p); // expected-error {{use '> >'}} expected-error {{use '> ='}}
   }
 }
+
+namespace PR5925 {
+  template <typename x>
+  class foo { // expected-note {{here}}
+  };
+  void bar(foo *X) { // expected-error {{requires template arguments}}
+  }
+}
+
+namespace PR13210 {
+  template <class T>
+  class C {}; // expected-note {{here}}
+
+  void f() {
+    new C(); // expected-error {{requires template arguments}}
+  }
+}
diff --git a/test/Parser/cxx0x-decl.cpp b/test/Parser/cxx0x-decl.cpp
index 9a220ca..a6fc49c 100644
--- a/test/Parser/cxx0x-decl.cpp
+++ b/test/Parser/cxx0x-decl.cpp
@@ -25,3 +25,6 @@
   void h() = delete;; // ok
   void i() = delete;;; // expected-warning {{extra ';' after member function definition}}
 };
+
+int *const const p = 0; // ok
+const const int *q = 0; // expected-warning {{duplicate 'const' declaration specifier}}
diff --git a/test/Parser/cxx0x-lambda-expressions.cpp b/test/Parser/cxx0x-lambda-expressions.cpp
index 9c71941..7e9d475 100644
--- a/test/Parser/cxx0x-lambda-expressions.cpp
+++ b/test/Parser/cxx0x-lambda-expressions.cpp
@@ -40,4 +40,11 @@
     int a5[3] = { []{return 0;}() };
     int a6[1] = {[this] = 1 }; // expected-error{{integral constant expression must have integral or unscoped enumeration type, not 'C *'}}
   }
+
+  void delete_lambda(int *p) {
+    delete [] p;
+    delete [] (int*) { new int }; // ok, compound-literal, not lambda
+    delete [] { return new int; } (); // expected-error{{expected expression}}
+    delete [&] { return new int; } (); // ok, lambda
+  }
 };
diff --git a/test/Parser/missing-selector-name.mm b/test/Parser/missing-selector-name.mm
new file mode 100644
index 0000000..d5554c5
--- /dev/null
+++ b/test/Parser/missing-selector-name.mm
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://11939584
+
+@interface PodiumWalkerController
+@property (assign) id PROP;
+- (void) // expected-error {{expected ';' after method prototype}}
+@end // expected-error {{expected selector for Objective-C method}}
+
+
+id GVAR;
+
+id StopProgressAnimation()
+{
+
+    PodiumWalkerController *controller;
+    return controller.PROP;
+}
+
+@interface P1
+@property (assign) id PROP;
+- (void); // expected-error {{expected selector for Objective-C method}}
+@end
+
+id GG=0;
+
+id Stop1()
+{
+
+    PodiumWalkerController *controller;
+    return controller.PROP;
+}
+
+@interface P2
+@property (assign) id PROP;
+- (void)Meth {} // expected-error {{expected ';' after method prototype}}
+@end
+
+@interface P3
+@property (assign) id PROP;
+- (void)
+- (void)Meth {} // expected-error {{expected selector for Objective-C method}} \
+                // expected-error {{expected ';' after method prototype}}
+@end
+
+id HH=0;
+
+id Stop2()
+{
+
+    PodiumWalkerController *controller;
+    return controller.PROP;
+}
diff --git a/test/Parser/ms-inline-asm.c b/test/Parser/ms-inline-asm.c
index 2d18195..5326ce4 100644
--- a/test/Parser/ms-inline-asm.c
+++ b/test/Parser/ms-inline-asm.c
@@ -11,13 +11,13 @@
   __asm { // expected-warning {{MS-style inline assembly is not supported}}
     int 0x2c ; } asm comments are fun! }{
   }
-  __asm {}  // no warning as this gets merged with the previous inline asm
+  __asm {} // expected-warning {{MS-style inline assembly is not supported}}
 }
 int t6() {
   __asm int 3 ; } comments for single-line asm // expected-warning {{MS-style inline assembly is not supported}}
-  __asm {} // no warning as this gets merged with the previous inline asm
+  __asm {} // expected-warning {{MS-style inline assembly is not supported}}
 
-  __asm int 4 // no warning as this gets merged with the previous inline asm
+  __asm int 4 // expected-warning {{MS-style inline assembly is not supported}}
   return 10;
 }
 int t7() {
diff --git a/test/Parser/objcxx11-attributes.mm b/test/Parser/objcxx11-attributes.mm
index 0c91392..1b9bf66 100644
--- a/test/Parser/objcxx11-attributes.mm
+++ b/test/Parser/objcxx11-attributes.mm
@@ -35,7 +35,8 @@
   [[class, test(foo 'x' bar),,,]];
   [[bitand, noreturn]]; // expected-warning {{attribute noreturn cannot be specified on a statement}}
 
-  [[noreturn]]int(e)();
+  // FIXME: Suppress vexing parse warning
+  [[noreturn]]int(e)(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}} 
   int e2(); // expected-warning {{interpreted as a function declaration}} expected-note{{}}
 
   // A function taking a noreturn function.
diff --git a/test/Preprocessor/has_attribute.c b/test/Preprocessor/has_attribute.c
index 80f53a5..711cf67 100644
--- a/test/Preprocessor/has_attribute.c
+++ b/test/Preprocessor/has_attribute.c
@@ -24,3 +24,13 @@
 #if !__has_attribute(something_we_dont_have)
 int has_something_we_dont_have();
 #endif
+
+// rdar://10253857
+#if __has_attribute(__const)
+ int fn3() __attribute__ ((__const));
+#endif
+
+#if __has_attribute(const)
+ static int constFunction() __attribute__((const));
+#endif
+
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 83028b7..e7321e0 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -48,6 +48,9 @@
 // COMMON:#define __GNUC_STDC_INLINE__ 1
 // COMMON:#define __GNUC__
 // COMMON:#define __GXX_ABI_VERSION
+// COMMON:#define __ORDER_BIG_ENDIAN__ 4321
+// COMMON:#define __ORDER_LITTLE_ENDIAN__ 1234
+// COMMON:#define __ORDER_PDP_ENDIAN__ 3412
 // COMMON:#define __STDC_HOSTED__ 1
 // COMMON:#define __STDC_VERSION__
 // COMMON:#define __STDC__ 1
@@ -108,12 +111,39 @@
 // NONFRAGILE:#define OBJC_ZEROCOST_EXCEPTIONS 1
 // NONFRAGILE:#define __OBJC2__ 1
 //
-// 
+//
+// RUN: %clang_cc1 -O0 -E -dM < /dev/null | FileCheck -check-prefix O0 %s
+//
+// O0:#define __NO_INLINE__ 1
+// O0-NOT:#define __OPTIMIZE_SIZE__
+// O0-NOT:#define __OPTIMIZE__
+//
+//
+// RUN: %clang_cc1 -fno-inline -O3 -E -dM < /dev/null | FileCheck -check-prefix NO_INLINE %s
+//
+// NO_INLINE:#define __NO_INLINE__ 1
+// NO_INLINE-NOT:#define __OPTIMIZE_SIZE__
+// NO_INLINE:#define __OPTIMIZE__
+//
+//
 // RUN: %clang_cc1 -O1 -E -dM < /dev/null | FileCheck -check-prefix O1 %s
 //
+// O1-NOT:#define __OPTIMIZE_SIZE__
 // O1:#define __OPTIMIZE__ 1
 //
-// 
+//
+// RUN: %clang_cc1 -Os -E -dM < /dev/null | FileCheck -check-prefix Os %s
+//
+// Os:#define __OPTIMIZE_SIZE__ 1
+// Os:#define __OPTIMIZE__ 1
+//
+//
+// RUN: %clang_cc1 -Oz -E -dM < /dev/null | FileCheck -check-prefix Oz %s
+//
+// Oz:#define __OPTIMIZE_SIZE__ 1
+// Oz:#define __OPTIMIZE__ 1
+//
+//
 // RUN: %clang_cc1 -fpascal-strings -E -dM < /dev/null | FileCheck -check-prefix PASCAL %s
 //
 // PASCAL:#define __PASCAL_STRINGS__ 1
@@ -134,9 +164,11 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=arm-none-none < /dev/null | FileCheck -check-prefix ARM %s
 //
+// ARM-NOT:#define _LP64
 // ARM:#define __APCS_32__ 1
 // ARM:#define __ARMEL__ 1
 // ARM:#define __ARM_ARCH_6J__ 1
+// ARM:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // ARM:#define __CHAR16_TYPE__ unsigned short
 // ARM:#define __CHAR32_TYPE__ unsigned int
 // ARM:#define __CHAR_BIT__ 8
@@ -196,7 +228,7 @@
 // ARM:#define __LITTLE_ENDIAN__ 1
 // ARM:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // ARM:#define __LONG_MAX__ 2147483647L
-// ARM:#define __NO_INLINE__ 1
+// ARM-NOT:#define __LP64__
 // ARM:#define __POINTER_WIDTH__ 32
 // ARM:#define __PTRDIFF_TYPE__ int
 // ARM:#define __PTRDIFF_WIDTH__ 32
@@ -231,6 +263,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-none-none < /dev/null | FileCheck -check-prefix I386 %s
 //
+// I386-NOT:#define _LP64
+// I386:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // I386:#define __CHAR16_TYPE__ unsigned short
 // I386:#define __CHAR32_TYPE__ unsigned int
 // I386:#define __CHAR_BIT__ 8
@@ -290,7 +324,7 @@
 // I386:#define __LITTLE_ENDIAN__ 1
 // I386:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // I386:#define __LONG_MAX__ 2147483647L
-// I386:#define __NO_INLINE__ 1
+// I386-NOT:#define __LP64__
 // I386:#define __NO_MATH_INLINES 1
 // I386:#define __POINTER_WIDTH__ 32
 // I386:#define __PTRDIFF_TYPE__ int
@@ -326,6 +360,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=i386-pc-linux-gnu -target-cpu pentium4 < /dev/null | FileCheck -check-prefix I386-LINUX %s
 //
+// I386-LINUX-NOT:#define _LP64
+// I386-LINUX:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // I386-LINUX:#define __CHAR16_TYPE__ unsigned short
 // I386-LINUX:#define __CHAR32_TYPE__ unsigned int
 // I386-LINUX:#define __CHAR_BIT__ 8
@@ -385,7 +421,7 @@
 // I386-LINUX:#define __LITTLE_ENDIAN__ 1
 // I386-LINUX:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // I386-LINUX:#define __LONG_MAX__ 2147483647L
-// I386-LINUX:#define __NO_INLINE__ 1
+// I386-LINUX-NOT:#define __LP64__
 // I386-LINUX:#define __NO_MATH_INLINES 1
 // I386-LINUX:#define __POINTER_WIDTH__ 32
 // I386-LINUX:#define __PTRDIFF_TYPE__ int
@@ -423,11 +459,13 @@
 //
 // MIPS32BE:#define MIPSEB 1
 // MIPS32BE:#define _ABIO32 1
+// MIPS32BE-NOT:#define _LP64
 // MIPS32BE:#define _MIPSEB 1
 // MIPS32BE:#define _MIPS_SIM _ABIO32
 // MIPS32BE:#define _MIPS_SZINT 32
 // MIPS32BE:#define _MIPS_SZLONG 32
 // MIPS32BE:#define _MIPS_SZPTR 32
+// MIPS32BE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // MIPS32BE:#define __CHAR16_TYPE__ unsigned short
 // MIPS32BE:#define __CHAR32_TYPE__ unsigned int
 // MIPS32BE:#define __CHAR_BIT__ 8
@@ -487,9 +525,9 @@
 // MIPS32BE:#define __LDBL_MIN__ 2.2250738585072014e-308
 // MIPS32BE:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MIPS32BE:#define __LONG_MAX__ 2147483647L
+// MIPS32BE-NOT:#define __LP64__
 // MIPS32BE:#define __MIPSEB 1
 // MIPS32BE:#define __MIPSEB__ 1
-// MIPS32BE:#define __NO_INLINE__ 1
 // MIPS32BE:#define __POINTER_WIDTH__ 32
 // MIPS32BE:#define __PRAGMA_REDEFINE_EXTNAME 1
 // MIPS32BE:#define __PTRDIFF_TYPE__ int
@@ -535,11 +573,13 @@
 //
 // MIPS32EL:#define MIPSEL 1
 // MIPS32EL:#define _ABIO32 1
+// MIPS32EL-NOT:#define _LP64
 // MIPS32EL:#define _MIPSEL 1
 // MIPS32EL:#define _MIPS_SIM _ABIO32
 // MIPS32EL:#define _MIPS_SZINT 32
 // MIPS32EL:#define _MIPS_SZLONG 32
 // MIPS32EL:#define _MIPS_SZPTR 32
+// MIPS32EL:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // MIPS32EL:#define __CHAR16_TYPE__ unsigned short
 // MIPS32EL:#define __CHAR32_TYPE__ unsigned int
 // MIPS32EL:#define __CHAR_BIT__ 8
@@ -599,9 +639,9 @@
 // MIPS32EL:#define __LDBL_MIN__ 2.2250738585072014e-308
 // MIPS32EL:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MIPS32EL:#define __LONG_MAX__ 2147483647L
+// MIPS32EL-NOT:#define __LP64__
 // MIPS32EL:#define __MIPSEL 1
 // MIPS32EL:#define __MIPSEL__ 1
-// MIPS32EL:#define __NO_INLINE__ 1
 // MIPS32EL:#define __POINTER_WIDTH__ 32
 // MIPS32EL:#define __PRAGMA_REDEFINE_EXTNAME 1
 // MIPS32EL:#define __PTRDIFF_TYPE__ int
@@ -644,11 +684,13 @@
 //
 // MIPS64BE:#define MIPSEB 1
 // MIPS64BE:#define _ABI64 3
+// MIPS64BE:#define _LP64 1
 // MIPS64BE:#define _MIPSEB 1
 // MIPS64BE:#define _MIPS_SIM _ABI64
 // MIPS64BE:#define _MIPS_SZINT 32
 // MIPS64BE:#define _MIPS_SZLONG 64
 // MIPS64BE:#define _MIPS_SZPTR 64
+// MIPS64BE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // MIPS64BE:#define __CHAR16_TYPE__ unsigned short
 // MIPS64BE:#define __CHAR32_TYPE__ unsigned int
 // MIPS64BE:#define __CHAR_BIT__ 8
@@ -708,9 +750,9 @@
 // MIPS64BE:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
 // MIPS64BE:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MIPS64BE:#define __LONG_MAX__ 9223372036854775807L
+// MIPS64BE:#define __LP64__ 1
 // MIPS64BE:#define __MIPSEB 1
 // MIPS64BE:#define __MIPSEB__ 1
-// MIPS64BE:#define __NO_INLINE__ 1
 // MIPS64BE:#define __POINTER_WIDTH__ 64
 // MIPS64BE:#define __PRAGMA_REDEFINE_EXTNAME 1
 // MIPS64BE:#define __PTRDIFF_TYPE__ long int
@@ -753,11 +795,13 @@
 //
 // MIPS64EL:#define MIPSEL 1
 // MIPS64EL:#define _ABI64 3
+// MIPS64EL:#define _LP64 1
 // MIPS64EL:#define _MIPSEL 1
 // MIPS64EL:#define _MIPS_SIM _ABI64
 // MIPS64EL:#define _MIPS_SZINT 32
 // MIPS64EL:#define _MIPS_SZLONG 64
 // MIPS64EL:#define _MIPS_SZPTR 64
+// MIPS64EL:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // MIPS64EL:#define __CHAR16_TYPE__ unsigned short
 // MIPS64EL:#define __CHAR32_TYPE__ unsigned int
 // MIPS64EL:#define __CHAR_BIT__ 8
@@ -817,9 +861,9 @@
 // MIPS64EL:#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
 // MIPS64EL:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MIPS64EL:#define __LONG_MAX__ 9223372036854775807L
+// MIPS64EL:#define __LP64__ 1
 // MIPS64EL:#define __MIPSEL 1
 // MIPS64EL:#define __MIPSEL__ 1
-// MIPS64EL:#define __NO_INLINE__ 1
 // MIPS64EL:#define __POINTER_WIDTH__ 64
 // MIPS64EL:#define __PRAGMA_REDEFINE_EXTNAME 1
 // MIPS64EL:#define __PTRDIFF_TYPE__ long int
@@ -905,6 +949,8 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=msp430-none-none < /dev/null | FileCheck -check-prefix MSP430 %s
 //
 // MSP430:#define MSP430 1
+// MSP430-NOT:#define _LP64
+// MSP430:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // MSP430:#define __CHAR16_TYPE__ unsigned short
 // MSP430:#define __CHAR32_TYPE__ unsigned int
 // MSP430:#define __CHAR_BIT__ 8
@@ -962,8 +1008,8 @@
 // MSP430:#define __LDBL_MIN__ 2.2250738585072014e-308
 // MSP430:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // MSP430:#define __LONG_MAX__ 2147483647L
+// MSP430-NOT:#define __LP64__
 // MSP430:#define __MSP430__ 1
-// MSP430:#define __NO_INLINE__ 1
 // MSP430:#define __POINTER_WIDTH__ 16
 // MSP430:#define __PTRDIFF_TYPE__ int
 // MSP430:#define __PTRDIFF_WIDTH__ 16 
@@ -993,6 +1039,198 @@
 // MSP430:#define __WINT_WIDTH__ 16
 // MSP430:#define __clang__ 1
 //
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=nvptx-none-none < /dev/null | FileCheck -check-prefix NVPTX32 %s
+//
+// NVPTX32-NOT:#define _LP64
+// NVPTX32:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// NVPTX32:#define __CHAR16_TYPE__ unsigned short
+// NVPTX32:#define __CHAR32_TYPE__ unsigned int
+// NVPTX32:#define __CHAR_BIT__ 8
+// NVPTX32:#define __CONSTANT_CFSTRINGS__ 1
+// NVPTX32:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// NVPTX32:#define __DBL_DIG__ 15
+// NVPTX32:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// NVPTX32:#define __DBL_HAS_DENORM__ 1
+// NVPTX32:#define __DBL_HAS_INFINITY__ 1
+// NVPTX32:#define __DBL_HAS_QUIET_NAN__ 1
+// NVPTX32:#define __DBL_MANT_DIG__ 53
+// NVPTX32:#define __DBL_MAX_10_EXP__ 308
+// NVPTX32:#define __DBL_MAX_EXP__ 1024
+// NVPTX32:#define __DBL_MAX__ 1.7976931348623157e+308
+// NVPTX32:#define __DBL_MIN_10_EXP__ (-307)
+// NVPTX32:#define __DBL_MIN_EXP__ (-1021)
+// NVPTX32:#define __DBL_MIN__ 2.2250738585072014e-308
+// NVPTX32:#define __DECIMAL_DIG__ 17
+// NVPTX32:#define __FINITE_MATH_ONLY__ 0
+// NVPTX32:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// NVPTX32:#define __FLT_DIG__ 6
+// NVPTX32:#define __FLT_EPSILON__ 1.19209290e-7F
+// NVPTX32:#define __FLT_EVAL_METHOD__ 0
+// NVPTX32:#define __FLT_HAS_DENORM__ 1
+// NVPTX32:#define __FLT_HAS_INFINITY__ 1
+// NVPTX32:#define __FLT_HAS_QUIET_NAN__ 1
+// NVPTX32:#define __FLT_MANT_DIG__ 24
+// NVPTX32:#define __FLT_MAX_10_EXP__ 38
+// NVPTX32:#define __FLT_MAX_EXP__ 128
+// NVPTX32:#define __FLT_MAX__ 3.40282347e+38F
+// NVPTX32:#define __FLT_MIN_10_EXP__ (-37)
+// NVPTX32:#define __FLT_MIN_EXP__ (-125)
+// NVPTX32:#define __FLT_MIN__ 1.17549435e-38F
+// NVPTX32:#define __FLT_RADIX__ 2
+// NVPTX32:#define __INT16_TYPE__ short
+// NVPTX32:#define __INT32_TYPE__ int
+// NVPTX32:#define __INT64_C_SUFFIX__ LL
+// NVPTX32:#define __INT64_TYPE__ long long int
+// NVPTX32:#define __INT8_TYPE__ char
+// NVPTX32:#define __INTMAX_MAX__ 9223372036854775807LL
+// NVPTX32:#define __INTMAX_TYPE__ long long int
+// NVPTX32:#define __INTMAX_WIDTH__ 64
+// NVPTX32:#define __INTPTR_TYPE__ unsigned int
+// NVPTX32:#define __INTPTR_WIDTH__ 32
+// NVPTX32:#define __INT_MAX__ 2147483647
+// NVPTX32:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// NVPTX32:#define __LDBL_DIG__ 15
+// NVPTX32:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// NVPTX32:#define __LDBL_HAS_DENORM__ 1
+// NVPTX32:#define __LDBL_HAS_INFINITY__ 1
+// NVPTX32:#define __LDBL_HAS_QUIET_NAN__ 1
+// NVPTX32:#define __LDBL_MANT_DIG__ 53
+// NVPTX32:#define __LDBL_MAX_10_EXP__ 308
+// NVPTX32:#define __LDBL_MAX_EXP__ 1024
+// NVPTX32:#define __LDBL_MAX__ 1.7976931348623157e+308
+// NVPTX32:#define __LDBL_MIN_10_EXP__ (-307)
+// NVPTX32:#define __LDBL_MIN_EXP__ (-1021)
+// NVPTX32:#define __LDBL_MIN__ 2.2250738585072014e-308
+// NVPTX32:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// NVPTX32:#define __LONG_MAX__ 9223372036854775807L
+// NVPTX32-NOT:#define __LP64__
+// NVPTX32:#define __NVPTX__ 1
+// NVPTX32:#define __POINTER_WIDTH__ 32
+// NVPTX32:#define __PRAGMA_REDEFINE_EXTNAME 1
+// NVPTX32:#define __PTRDIFF_TYPE__ unsigned int
+// NVPTX32:#define __PTRDIFF_WIDTH__ 32
+// NVPTX32:#define __PTX__ 1
+// NVPTX32:#define __SCHAR_MAX__ 127
+// NVPTX32:#define __SHRT_MAX__ 32767
+// NVPTX32:#define __SIG_ATOMIC_WIDTH__ 32
+// NVPTX32:#define __SIZEOF_DOUBLE__ 8
+// NVPTX32:#define __SIZEOF_FLOAT__ 4
+// NVPTX32:#define __SIZEOF_INT__ 4
+// NVPTX32:#define __SIZEOF_LONG_DOUBLE__ 8
+// NVPTX32:#define __SIZEOF_LONG_LONG__ 8
+// NVPTX32:#define __SIZEOF_LONG__ 8
+// NVPTX32:#define __SIZEOF_POINTER__ 4
+// NVPTX32:#define __SIZEOF_PTRDIFF_T__ 4
+// NVPTX32:#define __SIZEOF_SHORT__ 2
+// NVPTX32:#define __SIZEOF_SIZE_T__ 4
+// NVPTX32:#define __SIZEOF_WCHAR_T__ 4
+// NVPTX32:#define __SIZEOF_WINT_T__ 4
+// NVPTX32:#define __SIZE_TYPE__ unsigned int
+// NVPTX32:#define __SIZE_WIDTH__ 32
+// NVPTX32:#define __UINTMAX_TYPE__ long long unsigned int
+// NVPTX32:#define __USER_LABEL_PREFIX__ _
+// NVPTX32:#define __WCHAR_MAX__ 2147483647
+// NVPTX32:#define __WCHAR_TYPE__ int
+// NVPTX32:#define __WCHAR_WIDTH__ 32
+// NVPTX32:#define __WINT_TYPE__ int
+// NVPTX32:#define __WINT_WIDTH__ 32
+//
+// RUN: %clang_cc1 -E -dM -ffreestanding -triple=nvptx64-none-none < /dev/null | FileCheck -check-prefix NVPTX64 %s
+//
+// NVPTX64:#define _LP64 1
+// NVPTX64:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+// NVPTX64:#define __CHAR16_TYPE__ unsigned short
+// NVPTX64:#define __CHAR32_TYPE__ unsigned int
+// NVPTX64:#define __CHAR_BIT__ 8
+// NVPTX64:#define __CONSTANT_CFSTRINGS__ 1
+// NVPTX64:#define __DBL_DENORM_MIN__ 4.9406564584124654e-324
+// NVPTX64:#define __DBL_DIG__ 15
+// NVPTX64:#define __DBL_EPSILON__ 2.2204460492503131e-16
+// NVPTX64:#define __DBL_HAS_DENORM__ 1
+// NVPTX64:#define __DBL_HAS_INFINITY__ 1
+// NVPTX64:#define __DBL_HAS_QUIET_NAN__ 1
+// NVPTX64:#define __DBL_MANT_DIG__ 53
+// NVPTX64:#define __DBL_MAX_10_EXP__ 308
+// NVPTX64:#define __DBL_MAX_EXP__ 1024
+// NVPTX64:#define __DBL_MAX__ 1.7976931348623157e+308
+// NVPTX64:#define __DBL_MIN_10_EXP__ (-307)
+// NVPTX64:#define __DBL_MIN_EXP__ (-1021)
+// NVPTX64:#define __DBL_MIN__ 2.2250738585072014e-308
+// NVPTX64:#define __DECIMAL_DIG__ 17
+// NVPTX64:#define __FINITE_MATH_ONLY__ 0
+// NVPTX64:#define __FLT_DENORM_MIN__ 1.40129846e-45F
+// NVPTX64:#define __FLT_DIG__ 6
+// NVPTX64:#define __FLT_EPSILON__ 1.19209290e-7F
+// NVPTX64:#define __FLT_EVAL_METHOD__ 0
+// NVPTX64:#define __FLT_HAS_DENORM__ 1
+// NVPTX64:#define __FLT_HAS_INFINITY__ 1
+// NVPTX64:#define __FLT_HAS_QUIET_NAN__ 1
+// NVPTX64:#define __FLT_MANT_DIG__ 24
+// NVPTX64:#define __FLT_MAX_10_EXP__ 38
+// NVPTX64:#define __FLT_MAX_EXP__ 128
+// NVPTX64:#define __FLT_MAX__ 3.40282347e+38F
+// NVPTX64:#define __FLT_MIN_10_EXP__ (-37)
+// NVPTX64:#define __FLT_MIN_EXP__ (-125)
+// NVPTX64:#define __FLT_MIN__ 1.17549435e-38F
+// NVPTX64:#define __FLT_RADIX__ 2
+// NVPTX64:#define __INT16_TYPE__ short
+// NVPTX64:#define __INT32_TYPE__ int
+// NVPTX64:#define __INT64_C_SUFFIX__ LL
+// NVPTX64:#define __INT64_TYPE__ long long int
+// NVPTX64:#define __INT8_TYPE__ char
+// NVPTX64:#define __INTMAX_MAX__ 9223372036854775807LL
+// NVPTX64:#define __INTMAX_TYPE__ long long int
+// NVPTX64:#define __INTMAX_WIDTH__ 64
+// NVPTX64:#define __INTPTR_TYPE__ long long unsigned int
+// NVPTX64:#define __INTPTR_WIDTH__ 64
+// NVPTX64:#define __INT_MAX__ 2147483647
+// NVPTX64:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
+// NVPTX64:#define __LDBL_DIG__ 15
+// NVPTX64:#define __LDBL_EPSILON__ 2.2204460492503131e-16
+// NVPTX64:#define __LDBL_HAS_DENORM__ 1
+// NVPTX64:#define __LDBL_HAS_INFINITY__ 1
+// NVPTX64:#define __LDBL_HAS_QUIET_NAN__ 1
+// NVPTX64:#define __LDBL_MANT_DIG__ 53
+// NVPTX64:#define __LDBL_MAX_10_EXP__ 308
+// NVPTX64:#define __LDBL_MAX_EXP__ 1024
+// NVPTX64:#define __LDBL_MAX__ 1.7976931348623157e+308
+// NVPTX64:#define __LDBL_MIN_10_EXP__ (-307)
+// NVPTX64:#define __LDBL_MIN_EXP__ (-1021)
+// NVPTX64:#define __LDBL_MIN__ 2.2250738585072014e-308
+// NVPTX64:#define __LONG_LONG_MAX__ 9223372036854775807LL
+// NVPTX64:#define __LONG_MAX__ 9223372036854775807L
+// NVPTX64:#define __LP64__ 1
+// NVPTX64:#define __NVPTX__ 1
+// NVPTX64:#define __POINTER_WIDTH__ 64
+// NVPTX64:#define __PRAGMA_REDEFINE_EXTNAME 1
+// NVPTX64:#define __PTRDIFF_TYPE__ long long unsigned int
+// NVPTX64:#define __PTRDIFF_WIDTH__ 64
+// NVPTX64:#define __PTX__ 1
+// NVPTX64:#define __SCHAR_MAX__ 127
+// NVPTX64:#define __SHRT_MAX__ 32767
+// NVPTX64:#define __SIG_ATOMIC_WIDTH__ 32
+// NVPTX64:#define __SIZEOF_DOUBLE__ 8
+// NVPTX64:#define __SIZEOF_FLOAT__ 4
+// NVPTX64:#define __SIZEOF_INT__ 4
+// NVPTX64:#define __SIZEOF_LONG_DOUBLE__ 8
+// NVPTX64:#define __SIZEOF_LONG_LONG__ 8
+// NVPTX64:#define __SIZEOF_LONG__ 8
+// NVPTX64:#define __SIZEOF_POINTER__ 8
+// NVPTX64:#define __SIZEOF_PTRDIFF_T__ 8
+// NVPTX64:#define __SIZEOF_SHORT__ 2
+// NVPTX64:#define __SIZEOF_SIZE_T__ 8
+// NVPTX64:#define __SIZEOF_WCHAR_T__ 4
+// NVPTX64:#define __SIZEOF_WINT_T__ 4
+// NVPTX64:#define __SIZE_TYPE__ long long unsigned int
+// NVPTX64:#define __SIZE_WIDTH__ 64
+// NVPTX64:#define __UINTMAX_TYPE__ long long unsigned int
+// NVPTX64:#define __USER_LABEL_PREFIX__ _
+// NVPTX64:#define __WCHAR_MAX__ 2147483647
+// NVPTX64:#define __WCHAR_TYPE__ int
+// NVPTX64:#define __WCHAR_WIDTH__ 32
+// NVPTX64:#define __WINT_TYPE__ int
+// NVPTX64:#define __WINT_WIDTH__ 32
+//
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc-none-none -target-cpu 603e < /dev/null | FileCheck -check-prefix PPC603E %s
 //
 // PPC603E:#define _ARCH_603 1
@@ -1000,7 +1238,9 @@
 // PPC603E:#define _ARCH_PPC 1
 // PPC603E:#define _ARCH_PPCGR 1
 // PPC603E:#define _BIG_ENDIAN 1
+// PPC603E-NOT:#define _LP64
 // PPC603E:#define __BIG_ENDIAN__ 1
+// PPC603E:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // PPC603E:#define __CHAR16_TYPE__ unsigned short
 // PPC603E:#define __CHAR32_TYPE__ unsigned int
 // PPC603E:#define __CHAR_BIT__ 8
@@ -1060,8 +1300,8 @@
 // PPC603E:#define __LONG_DOUBLE_128__ 1
 // PPC603E:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // PPC603E:#define __LONG_MAX__ 2147483647L
+// PPC603E-NOT:#define __LP64__
 // PPC603E:#define __NATURAL_ALIGNMENT__ 1
-// PPC603E:#define __NO_INLINE__ 1
 // PPC603E:#define __POINTER_WIDTH__ 32
 // PPC603E:#define __POWERPC__ 1
 // PPC603E:#define __PTRDIFF_TYPE__ long int
@@ -1107,6 +1347,7 @@
 // PPC64:#define _BIG_ENDIAN 1
 // PPC64:#define _LP64 1
 // PPC64:#define __BIG_ENDIAN__ 1
+// PPC64:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // PPC64:#define __CHAR16_TYPE__ unsigned short
 // PPC64:#define __CHAR32_TYPE__ unsigned int
 // PPC64:#define __CHAR_BIT__ 8
@@ -1169,7 +1410,6 @@
 // PPC64:#define __LONG_MAX__ 9223372036854775807L
 // PPC64:#define __LP64__ 1
 // PPC64:#define __NATURAL_ALIGNMENT__ 1
-// PPC64:#define __NO_INLINE__ 1
 // PPC64:#define __POINTER_WIDTH__ 64
 // PPC64:#define __POWERPC__ 1
 // PPC64:#define __PTRDIFF_TYPE__ long int
@@ -1209,6 +1449,7 @@
 // PPC64-LINUX:#define _BIG_ENDIAN 1
 // PPC64-LINUX:#define _LP64 1
 // PPC64-LINUX:#define __BIG_ENDIAN__ 1
+// PPC64-LINUX:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // PPC64-LINUX:#define __CHAR16_TYPE__ unsigned short
 // PPC64-LINUX:#define __CHAR32_TYPE__ unsigned int
 // PPC64-LINUX:#define __CHAR_BIT__ 8
@@ -1271,7 +1512,6 @@
 // PPC64-LINUX:#define __LONG_MAX__ 9223372036854775807L
 // PPC64-LINUX:#define __LP64__ 1
 // PPC64-LINUX:#define __NATURAL_ALIGNMENT__ 1
-// PPC64-LINUX:#define __NO_INLINE__ 1
 // PPC64-LINUX:#define __POINTER_WIDTH__ 64
 // PPC64-LINUX:#define __POWERPC__ 1
 // PPC64-LINUX:#define __PTRDIFF_TYPE__ long int
@@ -1311,7 +1551,9 @@
 //
 // PPC:#define _ARCH_PPC 1
 // PPC:#define _BIG_ENDIAN 1
+// PPC-NOT:#define _LP64
 // PPC:#define __BIG_ENDIAN__ 1
+// PPC:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // PPC:#define __CHAR16_TYPE__ unsigned short
 // PPC:#define __CHAR32_TYPE__ unsigned int
 // PPC:#define __CHAR_BIT__ 8
@@ -1372,8 +1614,8 @@
 // PPC:#define __LONG_DOUBLE_128__ 1
 // PPC:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // PPC:#define __LONG_MAX__ 2147483647L
+// PPC-NOT:#define __LP64__
 // PPC:#define __NATURAL_ALIGNMENT__ 1
-// PPC:#define __NO_INLINE__ 1
 // PPC:#define __POINTER_WIDTH__ 32
 // PPC:#define __POWERPC__ 1
 // PPC:#define __PTRDIFF_TYPE__ long int
@@ -1409,7 +1651,9 @@
 //
 // PPC-LINUX:#define _ARCH_PPC 1
 // PPC-LINUX:#define _BIG_ENDIAN 1
+// PPC-LINUX-NOT:#define _LP64
 // PPC-LINUX:#define __BIG_ENDIAN__ 1
+// PPC-LINUX:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // PPC-LINUX:#define __CHAR16_TYPE__ unsigned short
 // PPC-LINUX:#define __CHAR32_TYPE__ unsigned int
 // PPC-LINUX:#define __CHAR_BIT__ 8
@@ -1470,8 +1714,8 @@
 // PPC-LINUX:#define __LONG_DOUBLE_128__ 1
 // PPC-LINUX:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // PPC-LINUX:#define __LONG_MAX__ 2147483647L
+// PPC-LINUX-NOT:#define __LP64__
 // PPC-LINUX:#define __NATURAL_ALIGNMENT__ 1
-// PPC-LINUX:#define __NO_INLINE__ 1
 // PPC-LINUX:#define __POINTER_WIDTH__ 32
 // PPC-LINUX:#define __POWERPC__ 1
 // PPC-LINUX:#define __PTRDIFF_TYPE__ int
@@ -1507,6 +1751,8 @@
 //
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=sparc-none-none < /dev/null | FileCheck -check-prefix SPARC %s
 //
+// SPARC-NOT:#define _LP64
+// SPARC:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // SPARC:#define __CHAR16_TYPE__ unsigned short
 // SPARC:#define __CHAR32_TYPE__ unsigned int
 // SPARC:#define __CHAR_BIT__ 8
@@ -1565,7 +1811,7 @@
 // SPARC:#define __LDBL_MIN__ 2.2250738585072014e-308
 // SPARC:#define __LONG_LONG_MAX__ 9223372036854775807LL
 // SPARC:#define __LONG_MAX__ 2147483647L
-// SPARC:#define __NO_INLINE__ 1
+// SPARC-NOT:#define __LP64__
 // SPARC:#define __POINTER_WIDTH__ 32
 // SPARC:#define __PTRDIFF_TYPE__ long int
 // SPARC:#define __PTRDIFF_WIDTH__ 32
@@ -1602,6 +1848,8 @@
 // 
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=tce-none-none < /dev/null | FileCheck -check-prefix TCE %s
 //
+// TCE-NOT:#define _LP64
+// TCE:#define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // TCE:#define __CHAR16_TYPE__ unsigned short
 // TCE:#define __CHAR32_TYPE__ unsigned int
 // TCE:#define __CHAR_BIT__ 8
@@ -1658,7 +1906,7 @@
 // TCE:#define __LDBL_MIN__ 1.17549435e-38F
 // TCE:#define __LONG_LONG_MAX__ 2147483647LL
 // TCE:#define __LONG_MAX__ 2147483647L
-// TCE:#define __NO_INLINE__ 1
+// TCE-NOT:#define __LP64__
 // TCE:#define __POINTER_WIDTH__ 32
 // TCE:#define __PTRDIFF_TYPE__ int
 // TCE:#define __PTRDIFF_WIDTH__ 32
@@ -1695,6 +1943,7 @@
 // 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 __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // X86_64:#define __CHAR16_TYPE__ unsigned short
 // X86_64:#define __CHAR32_TYPE__ unsigned int
 // X86_64:#define __CHAR_BIT__ 8
@@ -1756,7 +2005,6 @@
 // X86_64:#define __LONG_MAX__ 9223372036854775807L
 // X86_64:#define __LP64__ 1
 // X86_64:#define __MMX__ 1
-// X86_64:#define __NO_INLINE__ 1
 // X86_64:#define __NO_MATH_INLINES 1
 // X86_64:#define __POINTER_WIDTH__ 64
 // X86_64:#define __PTRDIFF_TYPE__ long int
@@ -1798,6 +2046,7 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -triple=x86_64-pc-linux-gnu < /dev/null | FileCheck -check-prefix X86_64-LINUX %s
 //
 // X86_64-LINUX:#define _LP64 1
+// X86_64-LINUX:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // X86_64-LINUX:#define __CHAR16_TYPE__ unsigned short
 // X86_64-LINUX:#define __CHAR32_TYPE__ unsigned int
 // X86_64-LINUX:#define __CHAR_BIT__ 8
@@ -1859,7 +2108,6 @@
 // X86_64-LINUX:#define __LONG_MAX__ 9223372036854775807L
 // X86_64-LINUX:#define __LP64__ 1
 // X86_64-LINUX:#define __MMX__ 1
-// X86_64-LINUX:#define __NO_INLINE__ 1
 // X86_64-LINUX:#define __NO_MATH_INLINES 1
 // X86_64-LINUX:#define __POINTER_WIDTH__ 64
 // X86_64-LINUX:#define __PTRDIFF_TYPE__ long int
diff --git a/test/Rewriter/objc-modern-StretAPI-2.mm b/test/Rewriter/objc-modern-StretAPI-2.mm
new file mode 100644
index 0000000..961fc16
--- /dev/null
+++ b/test/Rewriter/objc-modern-StretAPI-2.mm
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
+// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"Class=void*" -D"id=void*" -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
+// rdar://12142241
+
+extern "C" void *sel_registerName(const char *);
+typedef unsigned long size_t;
+
+typedef unsigned long NSUInteger;
+typedef struct _NSRange {
+    NSUInteger location;
+    NSUInteger length;
+} NSRange;
+
+
+@interface NSIndexSet
+- (NSRange)rangeAtIndex:(NSUInteger)rangeIndex;
+@end
+
+@interface NSArray
+@end
+
+@implementation NSArray
+- (NSArray *)objectsAtIndexes:(NSIndexSet *)iset {
+
+    NSUInteger ridx = 0;
+    NSRange range = [iset rangeAtIndex:ridx];
+    return 0;
+}
+@end
+
diff --git a/test/Sema/128bitint.c b/test/Sema/128bitint.c
index ddad835..600c25a 100644
--- a/test/Sema/128bitint.c
+++ b/test/Sema/128bitint.c
@@ -18,3 +18,22 @@
 unsigned long long UnsignedTooBig = 123456789012345678901234567890; // expected-warning {{integer constant is too large for its type}}
 __uint128_t Unsigned128 = 123456789012345678901234567890Ui128;
 unsigned long long Unsigned64 = 123456789012345678901234567890Ui128; // expected-warning {{implicit conversion from 'unsigned __int128' to 'unsigned long long' changes value from 123456789012345678901234567890 to 14083847773837265618}}
+
+// Ensure we don't crash when user passes 128-bit values to type safety
+// attributes.
+void pointer_with_type_tag_arg_num_1(void *buf, int datatype)
+    __attribute__(( pointer_with_type_tag(mpi,0x10000000000000001i128,1) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+void pointer_with_type_tag_arg_num_2(void *buf, int datatype)
+    __attribute__(( pointer_with_type_tag(mpi,1,0x10000000000000001i128) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+void MPI_Send(void *buf, int datatype) __attribute__(( pointer_with_type_tag(mpi,1,2) ));
+
+static const __uint128_t mpi_int_wrong __attribute__(( type_tag_for_datatype(mpi,int) )) = 0x10000000000000001i128; // expected-error {{'type_tag_for_datatype' attribute requires the initializer to be an integer constant expression that can be represented by a 64 bit integer}}
+static const int mpi_int __attribute__(( type_tag_for_datatype(mpi,int) )) = 10;
+
+void test(int *buf)
+{
+  MPI_Send(buf, 0x10000000000000001i128); // expected-warning {{implicit conversion from '__int128' to 'int' changes value}}
+}
+
diff --git a/test/Sema/MicrosoftExtensions.c b/test/Sema/MicrosoftExtensions.c
index 7c2782f..5d7330e 100644
--- a/test/Sema/MicrosoftExtensions.c
+++ b/test/Sema/MicrosoftExtensions.c
@@ -88,7 +88,7 @@
 } BB;
 
 __declspec(deprecated("This is deprecated")) enum DE1 { one, two } e1; // expected-note {{'e1' declared here}}
-struct __declspec(deprecated) DS1 { int i; float f; };
+struct __declspec(deprecated) DS1 { int i; float f; }; // expected-note {{declared here}}
 
 #define MY_TEXT		"This is also deprecated"
 __declspec(deprecated(MY_TEXT)) void Dfunc1( void ) {} // expected-note {{'Dfunc1' declared here}}
diff --git a/test/Sema/arm-asm.c b/test/Sema/arm-asm.c
new file mode 100644
index 0000000..3fc0eeb
--- /dev/null
+++ b/test/Sema/arm-asm.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 %s -triple armv7-apple-darwin -verify -fsyntax-only
+
+void f (void) {
+  int Val;
+  asm volatile ("lw (r1), %0[val]": "=&b"(Val)); // expected-error {{invalid output constraint '=&b' in asm}}
+  return;
+}
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index 44d83e9..155d736 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple i386-pc-linux-gnu -verify -fsyntax-only
+// RUN: %clang_cc1 %s -Wno-private-extern -triple i386-pc-linux-gnu -verify -fsyntax-only
 
 void f() {
   int i;
diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c
index a13e351..b4a6f96 100644
--- a/test/Sema/attr-availability.c
+++ b/test/Sema/attr-availability.c
@@ -37,3 +37,9 @@
 void f7(int) __attribute__((availability(ios,introduced=2.0)));
 void f7(int) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{previous attribute is here}}
 void f7(int) __attribute__((availability(ios,deprecated=4.0))); // expected-warning {{availability does not match previous declaration}}
+
+
+// <rdar://problem/11886458>
+#if !__has_feature(attribute_availability_with_message)
+# error "Missing __has_feature"
+#endif
diff --git a/test/Sema/attr-deprecated-message.c b/test/Sema/attr-deprecated-message.c
index 08b09f9..f48d13e 100644
--- a/test/Sema/attr-deprecated-message.c
+++ b/test/Sema/attr-deprecated-message.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 // rdar: // 6734520
 
-typedef int INT1 __attribute__((deprecated("Please avoid INT1")));
+typedef int INT1 __attribute__((deprecated("Please avoid INT1"))); // expected-note 3 {{'INT1' declared here}}
 
 typedef INT1 INT2 __attribute__ ((__deprecated__("Please avoid INT2")));
 
@@ -12,10 +12,10 @@
 INT1 should_be_unavailable; // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
 INT1a should_not_be_deprecated;
 
-INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); 
+INT1 f1(void) __attribute__ ((deprecated("Please avoid f1"))); // expected-note {{'f1' declared here}}
 INT1 f2(void); // expected-warning {{'INT1' is deprecated: Please avoid INT1}}
 
-typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color")));
+typedef enum {red, green, blue} Color __attribute__((deprecated("Please avoid Color"))); // expected-note {{'Color' declared here}}
  
 
 Color c1; // expected-warning {{'Color' is deprecated: Please avoid Color}}
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
index 1c487d2..565be7f 100644
--- a/test/Sema/attr-deprecated.c
+++ b/test/Sema/attr-deprecated.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 
-int f() __attribute__((deprecated)); // expected-note {{declared here}}
+int f() __attribute__((deprecated)); // expected-note 2 {{declared here}}
 void g() __attribute__((deprecated));
 void g(); // expected-note {{declared here}}
 
@@ -23,7 +23,7 @@
 }
 
 int old_fn() __attribute__ ((deprecated));
-int old_fn();
+int old_fn(); // expected-note {{declared here}}
 int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}}
 
 int old_fn() {
@@ -32,7 +32,7 @@
 
 
 struct foo {
-  int x __attribute__((deprecated)); // expected-note {{declared here}}
+  int x __attribute__((deprecated)); // expected-note 3 {{declared here}}
 };
 
 void test1(struct foo *F) {
@@ -41,11 +41,11 @@
   struct foo f2 = { 17 }; // expected-warning {{'x' is deprecated}}
 }
 
-typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 3 {{declared here}}
+typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 12 {{declared here}}
 foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
 
 struct __attribute__((deprecated, 
-                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
+                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{declared here}}
 
 struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
 
@@ -102,7 +102,7 @@
         test19;
 
 // rdar://problem/8518751
-enum __attribute__((deprecated)) Test20 {
+enum __attribute__((deprecated)) Test20 { // expected-note {{declared here}}
   test20_a __attribute__((deprecated)), // expected-note {{declared here}}
   test20_b // expected-note {{declared here}}
 };
@@ -113,3 +113,10 @@
 }
 
 char test21[__has_feature(attribute_deprecated_with_message) ? 1 : -1];
+
+struct test22 {
+  foo_dep a __attribute((deprecated));
+  foo_dep b; // expected-warning {{'foo_dep' is deprecated}}
+  foo_dep c, d __attribute((deprecated)); // expected-warning {{'foo_dep' is deprecated}}
+  __attribute((deprecated)) foo_dep e, f;
+};
diff --git a/test/Sema/attr-unavailable-message.c b/test/Sema/attr-unavailable-message.c
index 745ef14..9710496 100644
--- a/test/Sema/attr-unavailable-message.c
+++ b/test/Sema/attr-unavailable-message.c
@@ -29,7 +29,7 @@
 
 // rdar://10201690
 enum foo {
-    a = 1,
+    a = 1, // expected-note {{declared here}}
     b __attribute__((deprecated())) = 2, // expected-note {{declared here}}
     c = 3
 }__attribute__((deprecated()));  
diff --git a/test/Sema/attr-used.c b/test/Sema/attr-used.c
index 0838816..e2dfab1 100644
--- a/test/Sema/attr-used.c
+++ b/test/Sema/attr-used.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only %s
+// RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern %s
 
 extern int l0 __attribute__((used)); // expected-warning {{used attribute ignored}}
 __private_extern__ int l1 __attribute__((used)); // expected-warning {{used attribute ignored}}
diff --git a/test/Sema/builtins-decl.c b/test/Sema/builtins-decl.c
index 19bdb84..d6b004a 100644
--- a/test/Sema/builtins-decl.c
+++ b/test/Sema/builtins-decl.c
@@ -6,3 +6,8 @@
 extern unsigned int __builtin_ia32_crc32qi (unsigned int, unsigned char);
 extern unsigned int __builtin_ia32_crc32hi (unsigned int, unsigned short);
 extern unsigned int __builtin_ia32_crc32si (unsigned int, unsigned int);
+
+// GCC documents these as unsigned, but they are defined with a signed argument.
+extern int __builtin_ffs(int);
+extern int __builtin_ffsl(long);
+extern int __builtin_ffsll(long long);
diff --git a/test/Sema/callingconv.c b/test/Sema/callingconv.c
index 25669f0..6c844a3 100644
--- a/test/Sema/callingconv.c
+++ b/test/Sema/callingconv.c
@@ -36,6 +36,14 @@
 typedef void (__attribute__((fastcall)) *Handler) (float *);
 Handler H = foo;
 
+int __attribute__((pcs("aapcs", "aapcs"))) pcs1(void); // expected-error {{attribute takes one argument}}
+int __attribute__((pcs())) pcs2(void); // expected-error {{attribute takes one argument}}
+int __attribute__((pcs(pcs1))) pcs3(void); // expected-error {{attribute takes one argument}}
+int __attribute__((pcs(0))) pcs4(void); // expected-error {{'pcs' attribute requires parameter 1 to be a string}}
+int __attribute__((pcs("aapcs"))) pcs5(void); // no-error
+int __attribute__((pcs("aapcs-vfp"))) pcs6(void); // no-error
+int __attribute__((pcs("foo"))) pcs7(void); // expected-error {{Invalid PCS type}}
+
 // PR6361
 void ctest3();
 void __attribute__((cdecl)) ctest3() {}
diff --git a/test/Sema/format-strings-fixit.c b/test/Sema/format-strings-fixit.c
index 800691e..15ac713 100644
--- a/test/Sema/format-strings-fixit.c
+++ b/test/Sema/format-strings-fixit.c
@@ -64,6 +64,18 @@
   printf("%f", (uintmax_t) 42);
   printf("%f", (ptrdiff_t) 42);
 
+  // Look beyond the first typedef.
+  typedef size_t my_size_type;
+  typedef intmax_t my_intmax_type;
+  typedef uintmax_t my_uintmax_type;
+  typedef ptrdiff_t my_ptrdiff_type;
+  typedef int my_int_type;
+  printf("%f", (my_size_type) 42);
+  printf("%f", (my_intmax_type) 42);
+  printf("%f", (my_uintmax_type) 42);
+  printf("%f", (my_ptrdiff_type) 42);
+  printf("%f", (my_int_type) 42);
+
   // string
   printf("%ld", "foo");
 
@@ -122,6 +134,18 @@
   scanf("%f", &uIntmaxVar);
   scanf("%f", &ptrdiffVar);
 
+  // Look beyond the first typedef for named integer types.
+  typedef size_t my_size_type;
+  typedef intmax_t my_intmax_type;
+  typedef uintmax_t my_uintmax_type;
+  typedef ptrdiff_t my_ptrdiff_type;
+  typedef int my_int_type;
+  scanf("%f", (my_size_type*)&sizeVar);
+  scanf("%f", (my_intmax_type*)&intmaxVar);
+  scanf("%f", (my_uintmax_type*)&uIntmaxVar);
+  scanf("%f", (my_ptrdiff_type*)&ptrdiffVar);
+  scanf("%f", (my_int_type*)&intVar);
+
   // Preserve the original formatting.
   scanf("%o", &longVar);
   scanf("%u", &longVar);
@@ -162,6 +186,11 @@
 // CHECK: printf("%jd", (intmax_t) 42);
 // CHECK: printf("%ju", (uintmax_t) 42);
 // CHECK: printf("%td", (ptrdiff_t) 42);
+// CHECK: printf("%zu", (my_size_type) 42);
+// CHECK: printf("%jd", (my_intmax_type) 42);
+// CHECK: printf("%ju", (my_uintmax_type) 42);
+// CHECK: printf("%td", (my_ptrdiff_type) 42);
+// CHECK: printf("%d", (my_int_type) 42);
 // CHECK: printf("%s", "foo");
 // CHECK: printf("%lo", (long) 42);
 // CHECK: printf("%lu", (long) 42);
@@ -193,6 +222,11 @@
 // CHECK: scanf("%jd", &intmaxVar);
 // CHECK: scanf("%ju", &uIntmaxVar);
 // CHECK: scanf("%td", &ptrdiffVar);
+// CHECK: scanf("%zu", (my_size_type*)&sizeVar);
+// CHECK: scanf("%jd", (my_intmax_type*)&intmaxVar);
+// CHECK: scanf("%ju", (my_uintmax_type*)&uIntmaxVar);
+// CHECK: scanf("%td", (my_ptrdiff_type*)&ptrdiffVar);
+// CHECK: scanf("%d", (my_int_type*)&intVar);
 // CHECK: scanf("%lo", &longVar);
 // CHECK: scanf("%lu", &longVar);
 // CHECK: scanf("%lx", &longVar);
diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c
index e94af5a..235ac11 100644
--- a/test/Sema/format-strings-scanf.c
+++ b/test/Sema/format-strings-scanf.c
@@ -33,6 +33,12 @@
   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
+
+  scanf("%s", (char*)0); // no-warning
+  scanf("%s", (volatile char*)0); // no-warning
+  scanf("%s", (signed char*)0); // no-warning
+  scanf("%s", (unsigned char*)0); // no-warning
+  scanf("%hhu", (signed char*)0); // no-warning
 }
 
 void bad_length_modifiers(char *s, void *p, wchar_t *ws, long double *ld) {
@@ -121,3 +127,52 @@
   scanf("%qd", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
   scanf("%qd", llx); // no-warning
 }
+
+void test_writeback(int *x) {
+  scanf("%n", (void*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'void *'}}
+  scanf("%n %c", x, x); // expected-warning{{format specifies type 'char *' but the argument has type 'int *'}}
+
+  scanf("%hhn", (signed char*)0); // no-warning
+  scanf("%hhn", (char*)0); // no-warning
+  scanf("%hhn", (unsigned char*)0); // no-warning
+  scanf("%hhn", (int*)0); // expected-warning{{format specifies type 'signed char *' but the argument has type 'int *'}}
+
+  scanf("%hn", (short*)0); // no-warning
+  scanf("%hn", (unsigned short*)0); // no-warning
+  scanf("%hn", (int*)0); // expected-warning{{format specifies type 'short *' but the argument has type 'int *'}}
+
+  scanf("%n", (int*)0); // no-warning
+  scanf("%n", (unsigned int*)0); // no-warning
+  scanf("%n", (char*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}}
+
+  scanf("%ln", (long*)0); // no-warning
+  scanf("%ln", (unsigned long*)0); // no-warning
+  scanf("%ln", (int*)0); // expected-warning{{format specifies type 'long *' but the argument has type 'int *'}}
+
+  scanf("%lln", (long long*)0); // no-warning
+  scanf("%lln", (unsigned long long*)0); // no-warning
+  scanf("%lln", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+  scanf("%qn", (long long*)0); // no-warning
+  scanf("%qn", (unsigned long long*)0); // no-warning
+  scanf("%qn", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+}
+
+void test_qualifiers(const int *cip, volatile int* vip,
+                     const char *ccp, volatile char* vcp,
+                     const volatile int *cvip) {
+  scanf("%d", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}}
+  scanf("%n", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}}
+  scanf("%s", ccp); // expected-warning{{format specifies type 'char *' but the argument has type 'const char *'}}
+  scanf("%d", cvip); // expected-warning{{format specifies type 'int *' but the argument has type 'const volatile int *'}}
+
+  scanf("%d", vip); // No warning.
+  scanf("%n", vip); // No warning.
+  scanf("%c", vcp); // No warning.
+
+  typedef int* ip_t;
+  typedef const int* cip_t;
+  scanf("%d", (ip_t)0); // No warning.
+  scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
+}
diff --git a/test/Sema/format-strings-size_t.c b/test/Sema/format-strings-size_t.c
index 7f88ff3..5058a76 100644
--- a/test/Sema/format-strings-size_t.c
+++ b/test/Sema/format-strings-size_t.c
@@ -13,3 +13,16 @@
   // ptrdiff_t
   printf("%td", (double)42); // expected-warning {{format specifies type 'ptrdiff_t' (aka 'long') but the argument has type 'double'}}
 }
+
+void test_writeback(void) {
+  printf("%jn", (long*)0); // no-warning
+  printf("%jn", (unsigned long*)0); // no-warning
+  printf("%jn", (int*)0); // expected-warning{{format specifies type 'intmax_t *' (aka 'long *') but the argument has type 'int *'}}
+
+  printf("%zn", (long*)0); // no-warning
+  // FIXME: Warn about %zn with non-ssize_t argument.
+
+  printf("%tn", (long*)0); // no-warning
+  printf("%tn", (unsigned long*)0); // no-warning
+  printf("%tn", (int*)0); // expected-warning{{format specifies type 'ptrdiff_t *' (aka 'long *') but the argument has type 'int *'}}
+}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 5c30849..86b9296 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -88,9 +88,35 @@
 {
   int x;
   char *b;
+  printf("%n", b); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}}
+  printf("%n", &x); // no-warning
 
-  printf("%n",&x); // expected-warning {{'%n' in format string discouraged}}
-  sprintf(b,"%d%%%n",1, &x); // expected-warning {{'%n' in format string dis}}
+  printf("%hhn", (signed char*)0); // no-warning
+  printf("%hhn", (char*)0); // no-warning
+  printf("%hhn", (unsigned char*)0); // no-warning
+  printf("%hhn", (int*)0); // expected-warning{{format specifies type 'signed char *' but the argument has type 'int *'}}
+
+  printf("%hn", (short*)0); // no-warning
+  printf("%hn", (unsigned short*)0); // no-warning
+  printf("%hn", (int*)0); // expected-warning{{format specifies type 'short *' but the argument has type 'int *'}}
+
+  printf("%n", (int*)0); // no-warning
+  printf("%n", (unsigned int*)0); // no-warning
+  printf("%n", (char*)0); // expected-warning{{format specifies type 'int *' but the argument has type 'char *'}}
+
+  printf("%ln", (long*)0); // no-warning
+  printf("%ln", (unsigned long*)0); // no-warning
+  printf("%ln", (int*)0); // expected-warning{{format specifies type 'long *' but the argument has type 'int *'}}
+
+  printf("%lln", (long long*)0); // no-warning
+  printf("%lln", (unsigned long long*)0); // no-warning
+  printf("%lln", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+  printf("%qn", (long long*)0); // no-warning
+  printf("%qn", (unsigned long long*)0); // no-warning
+  printf("%qn", (int*)0); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
+
+  printf("%Ln", 0); // expected-warning{{length modifier 'L' results in undefined behavior or no effect with 'n' conversion specifier}}
 }
 
 void check_invalid_specifier(FILE* fp, char *buf)
@@ -167,7 +193,6 @@
   int x;
   printf(P);   // expected-warning {{format string is not a string literal (potentially insecure)}}
   printf(P, 42);
-  printf("%n", &x); // expected-warning {{use of '%n' in format string discouraged }}
 }
 
 void torture(va_list v8) {
@@ -185,7 +210,6 @@
   printf("%*d\n", f, x); // expected-warning{{field width should have type 'int', but argument has type 'double'}}
   printf("%*.*d\n", x, f, x); // expected-warning{{field precision should have type 'int', but argument has type 'double'}}
   printf("%**\n"); // expected-warning{{invalid conversion specifier '*'}}
-  printf("%n", &i); // expected-warning{{use of '%n' in format string discouraged (potentially insecure)}}
   printf("%d%d\n", x); // expected-warning{{more '%' conversions than data arguments}}
   printf("%d\n", x, x); // expected-warning{{data argument not used by format string}}
   printf("%W%d%Z\n", x, x, x); // expected-warning{{invalid conversion specifier 'W'}} expected-warning{{invalid conversion specifier 'Z'}}
@@ -316,14 +340,14 @@
   // 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("%#n", (int *) 0); // expected-warning{{flag '#' results in undefined behavior with 'n' conversion specifier}}
+  printf("%-n", (int *) 0); // expected-warning{{flag '-' results in undefined behavior with 'n' conversion specifier}}
   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)}}
+  printf("%1n", (int *) 0); // expected-warning{{field width used with 'n' conversion specifier, resulting in undefined behavior}}
+  printf("%.9n", (int *) 0); // expected-warning{{precision used with 'n' conversion specifier, resulting in undefined behavior}}
 
   // Ignored flags
   printf("% +f", 1.23); // expected-warning{{flag ' ' is ignored when flag '+' is present}}
@@ -435,10 +459,6 @@
   printf(kFormat2, 1, "foo"); // expected-warning{{data argument position '18' exceeds the number of data arguments (2)}}
   printf("%18$s\n", 1, "foo"); // expected-warning{{data argument position '18' exceeds the number of data arguments (2)}}
 
-  const char kFormat3[] = "%n"; // expected-note{{format string is defined here}}
-  printf(kFormat3, "as"); // expected-warning{{use of '%n' in format string discouraged}}
-  printf("%n", "as"); // expected-warning{{use of '%n' in format string discouraged}}
-
   const char kFormat4[] = "%y"; // expected-note{{format string is defined here}}
   printf(kFormat4, 5); // expected-warning{{invalid conversion specifier 'y'}}
   printf("%y", 5); // expected-warning{{invalid conversion specifier 'y'}}
@@ -562,3 +582,19 @@
   test14_foo("%", "%d", p); // expected-warning{{incomplete format specifier}}
   test14_bar("%", "%d", p); // expected-warning{{incomplete format specifier}}
 }
+
+void test_qualifiers(volatile int *vip, const int *cip,
+                     const volatile int *cvip) {
+  printf("%n", cip); // expected-warning{{format specifies type 'int *' but the argument has type 'const int *'}}
+  printf("%n", cvip); // expected-warning{{format specifies type 'int *' but the argument has type 'const volatile int *'}}
+
+  printf("%n", vip); // No warning.
+  printf("%p", cip); // No warning.
+  printf("%p", cvip); // No warning.
+
+
+  typedef int* ip_t;
+  typedef const int* cip_t;
+  printf("%n", (ip_t)0); // No warning.
+  printf("%n", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
+}
diff --git a/test/Sema/invalid-decl.c b/test/Sema/invalid-decl.c
index a5e7ad3..2699b25 100644
--- a/test/Sema/invalid-decl.c
+++ b/test/Sema/invalid-decl.c
@@ -20,3 +20,12 @@
     sizeof(zend_module_entry)
 };
 
+// <rdar://problem/11067144>
+typedef int (FunctionType)(int *value);
+typedef struct {
+  UndefinedType undef; // expected-error {{unknown type name 'UndefinedType'}}
+  FunctionType fun; // expected-error {{field 'fun' declared as a function}}
+} StructType;
+void f(StructType *buf) {
+  buf->fun = 0;
+}
diff --git a/test/Sema/pragma-pack-6.c b/test/Sema/pragma-pack-6.c
new file mode 100644
index 0000000..40659c2
--- /dev/null
+++ b/test/Sema/pragma-pack-6.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple i686-apple-darwin9 %s -fsyntax-only -verify
+
+// Pragma pack handling with tag declarations
+
+struct X;
+
+#pragma pack(2)
+struct X { int x; };
+struct Y;
+#pragma pack()
+
+struct Y { int y; };
+
+extern int check[__alignof(struct X) == 2 ? 1 : -1];
+extern int check[__alignof(struct Y) == 4 ? 1 : -1];
+
diff --git a/test/Sema/private-extern.c b/test/Sema/private-extern.c
index 25591dc..e480f3f 100644
--- a/test/Sema/private-extern.c
+++ b/test/Sema/private-extern.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only %s
+// RUN: %clang_cc1 -verify -fsyntax-only -Wno-private-extern %s
 
 static int g0; // expected-note{{previous definition}}
 int g0; // expected-error{{non-static declaration of 'g0' follows static declaration}}
diff --git a/test/Sema/static-array.c b/test/Sema/static-array.c
index 2d4b968..5ca693b 100644
--- a/test/Sema/static-array.c
+++ b/test/Sema/static-array.c
@@ -1,12 +1,9 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
 
 void cat0(int a[static 0]) {} // expected-warning {{'static' has no effect on zero-length arrays}}
 
 void cat(int a[static 3]) {} // expected-note 2 {{callee declares array parameter as static here}}
 
-typedef int i3[static 3];
-void tcat(i3 a) {}
-
 void vat(int i, int a[static i]) {} // expected-note {{callee declares array parameter as static here}}
 
 void f(int *p) {
@@ -20,12 +17,41 @@
   cat(c);
   cat(p);
 
-  tcat(0); // expected-warning {{null passed to a callee which requires a non-null argument}}
-  tcat(a); // expected-warning {{array argument is too small; contains 2 elements, callee requires at least 3}}
-  tcat(b);
-  tcat(c);
-  tcat(p);
-
   vat(1, 0); // expected-warning {{null passed to a callee which requires a non-null argument}}
   vat(3, b);
 }
+
+
+typedef int td[static 3]; // expected-error {{'static' used in array declarator outside of function prototype}}
+typedef void(*fp)(int[static 42]); // no-warning
+
+void g(void) {
+  int a[static 42]; // expected-error {{'static' used in array declarator outside of function prototype}}
+
+  int b[const 10]; // expected-error {{type qualifier used in array declarator outside of function prototype}}
+  int c[volatile 10]; // expected-error {{type qualifier used in array declarator outside of function prototype}}
+  int d[restrict 10]; // expected-error {{type qualifier used in array declarator outside of function prototype}}
+
+  int e[static restrict 1]; // expected-error {{'static' used in array declarator outside of function prototype}}
+}
+
+void h(int [static const 10][42]); // no-warning
+
+void i(int [10]
+       [static 42]); // expected-error {{'static' used in non-outermost array type derivation}}
+
+void j(int [10]
+       [const 42]); // expected-error {{type qualifier used in non-outermost array type derivation}}
+
+void k(int (*x)[static 10]); // expected-error {{'static' used in non-outermost array type derivation}}
+void l(int (x)[static 10]); // no-warning
+void m(int *x[static 10]); // no-warning
+void n(int *(x)[static 10]); // no-warning
+
+void o(int (x[static 10])(void)); // expected-error{{'x' declared as array of functions of type 'int (void)'}}
+void p(int (^x)[static 10]); // expected-error{{block pointer to non-function type is invalid}}
+void q(int (^x[static 10])()); // no-warning
+
+void r(x)
+  int x[restrict]; // no-warning
+{}
diff --git a/test/Sema/tentative-decls.c b/test/Sema/tentative-decls.c
index b15537b..bf2b1e4 100644
--- a/test/Sema/tentative-decls.c
+++ b/test/Sema/tentative-decls.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify
+// RUN: %clang_cc1 %s -fsyntax-only -Wprivate-extern -verify
 
 // PR3310
 struct a x1; // expected-note 2{{forward declaration of 'struct a'}}
@@ -32,7 +32,9 @@
 static int i3 = 5;
 extern int i3;
 
-__private_extern__ int pExtern;
+// rdar://7703982
+__private_extern__ int pExtern; // expected-warning {{use of __private_extern__ on a declaration may not produce external symbol private to the linkage unit and is deprecated}} \
+// expected-note {{use __attribute__((visibility("hidden"))) attribute instead}}
 int pExtern = 0;
 
 int i4;
diff --git a/test/Sema/thread-specifier.c b/test/Sema/thread-specifier.c
index 0d439b1..c06aad8 100644
--- a/test/Sema/thread-specifier.c
+++ b/test/Sema/thread-specifier.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -verify -pedantic %s
+// RUN: %clang_cc1 -triple i686-pc-linux-gnu -fsyntax-only -Wno-private-extern -verify -pedantic %s
 
 __thread int t1;
 __thread extern int t2; // expected-warning {{'__thread' before 'extern'}}
diff --git a/test/Sema/tls.c b/test/Sema/tls.c
new file mode 100644
index 0000000..3b2a441
--- /dev/null
+++ b/test/Sema/tls.c
@@ -0,0 +1,20 @@
+// Test that TLS is correctly considered supported or unsupported for the
+// different targets.
+
+// Linux supports TLS.
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fsyntax-only %s
+// RUN: %clang_cc1 -triple i386-pc-linux-gnu -fsyntax-only %s
+
+// Darwin supports TLS since 10.7.
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only %s
+// RUN: %clang_cc1 -triple x86_64-apple-macos10.7.0 -fsyntax-only %s
+
+// FIXME: I thought it was supported actually?
+// RUN: not %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only %s
+// RUN: not %clang_cc1 -triple i386-pc-win32 -fsyntax-only %s
+
+// OpenBSD does not suppport TLS.
+// RUN: not %clang_cc1 -triple x86_64-pc-openbsd -fsyntax-only %s
+// RUN: not %clang_cc1 -triple i386-pc-openbsd -fsyntax-only %s
+
+__thread int x;
diff --git a/test/Sema/typeof-use-deprecated.c b/test/Sema/typeof-use-deprecated.c
index 238e501..1518c83 100644
--- a/test/Sema/typeof-use-deprecated.c
+++ b/test/Sema/typeof-use-deprecated.c
@@ -1,25 +1,25 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
 
-struct s { int a; } __attribute__((deprecated)) x;  // expected-warning {{'s' is deprecated}}
+struct s { int a; } __attribute__((deprecated)) x;  // expected-warning {{'s' is deprecated}} expected-note 2 {{'s' declared here}}
 
 typeof(x) y;  // expected-warning {{'s' is deprecated}}
 
-union un{ int a; } __attribute__((deprecated)) u;  // expected-warning {{'un' is deprecated}}
+union un{ int a; } __attribute__((deprecated)) u;  // expected-warning {{'un' is deprecated}} expected-note 2 {{'un' declared here}}
 
 typeof(     u) z; // expected-warning {{'un' is deprecated}}
 
-enum E{ one} __attribute__((deprecated))  e; // expected-warning {{'E' is deprecated}} 
+enum E{ one} __attribute__((deprecated))  e; // expected-warning {{'E' is deprecated}} expected-note 2 {{'E' declared here}}
 
 typeof( e) w; // expected-warning {{'E' is deprecated}}
 
-struct foo { int x; } __attribute__((deprecated));
-typedef struct foo bar __attribute__((deprecated));
+struct foo { int x; } __attribute__((deprecated)); // expected-note {{'foo' declared here}}
+typedef struct foo bar __attribute__((deprecated)); // expected-note {{'bar' declared here}}
 bar x1;	// expected-warning {{'bar' is deprecated}}
 
 int main() { typeof(x1) y; }	// expected-warning {{'foo' is deprecated}}
 
 struct gorf { int x; };
-typedef struct gorf T __attribute__((deprecated));
+typedef struct gorf T __attribute__((deprecated));  // expected-note {{'T' declared here}}
 T t;	// expected-warning {{'T' is deprecated}}
 void wee() { typeof(t) y; }
 
diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c
index 9257751..634ae0d 100644
--- a/test/Sema/uninit-variables.c
+++ b/test/Sema/uninit-variables.c
@@ -503,3 +503,8 @@
   x *= 0; // expected-warning {{variable 'x' is uninitialized}}
   return x;
 }
+
+int self_init_in_cond(int *p) {
+  int n = ((p && (0 || 1)) && (n = *p)) ? n : -1; // ok
+  return n;
+}
diff --git a/test/Sema/unused-expr.c b/test/Sema/unused-expr.c
index d8d8795..056d09a 100644
--- a/test/Sema/unused-expr.c
+++ b/test/Sema/unused-expr.c
@@ -82,7 +82,7 @@
 
 int fn1() __attribute__ ((warn_unused_result));
 int fn2() __attribute__ ((pure));
-int fn3() __attribute__ ((const));
+int fn3() __attribute__ ((__const));
 // rdar://6587766
 int t6() {
   if (fn1() < 0 || fn2(2,1) < 0 || fn3(2) < 0)  // no warnings
diff --git a/test/Sema/warn-bad-function-cast.c b/test/Sema/warn-bad-function-cast.c
new file mode 100644
index 0000000..41a3f78
--- /dev/null
+++ b/test/Sema/warn-bad-function-cast.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wbad-function-cast -triple x86_64-unknown-unknown -verify
+// rdar://9103192
+
+void vf(void);
+int if1(void);
+char if2(void);
+long if3(void);
+float rf1(void);
+double rf2(void);
+_Complex double cf(void);
+enum e { E1 } ef(void);
+_Bool bf(void);
+char *pf1(void);
+int *pf2(void);
+
+void
+foo(void)
+{
+  /* Casts to void types are always OK.  */
+  (void)vf();
+  (void)if1();
+  (void)cf();
+  (const void)bf();
+  /* Casts to the same type or similar types are OK.  */
+  (int)if1();
+  (long)if2();
+  (char)if3();
+  (float)rf1();
+  (long double)rf2();
+  (_Complex float)cf();
+  (enum f { F1 })ef();
+  (_Bool)bf();
+  (void *)pf1();
+  (char *)pf2();
+  /* All following casts issue warning */
+  (float)if1(); /* expected-warning {{cast from function call of type 'int' to non-matching type 'float'}} */
+  (double)if2(); /* expected-warning {{cast from function call of type 'char' to non-matching type 'double'}} */
+  (_Bool)if3(); /* expected-warning {{cast from function call of type 'long' to non-matching type '_Bool'}} */
+  (int)rf1(); /* expected-warning {{cast from function call of type 'float' to non-matching type 'int'}} */
+  (long)rf2(); /* expected-warning {{cast from function call of type 'double' to non-matching type 'long'}} */
+  (double)cf(); /* expected-warning {{cast from function call of type '_Complex double' to non-matching type 'double'}} */
+  (int)ef(); /* expected-warning {{cast from function call of type 'enum e' to non-matching type 'int'}} */
+  (int)bf(); /* expected-warning {{cast from function call of type '_Bool' to non-matching type 'int'}} */
+  (__SIZE_TYPE__)pf1(); /* expected-warning {{cast from function call of type 'char *' to non-matching type 'unsigned long'}} */
+  (__PTRDIFF_TYPE__)pf2(); /* expected-warning {{cast from function call of type 'int *' to non-matching type 'long'}} */
+}
+
diff --git a/test/Sema/warn-documentation-fixits.c b/test/Sema/warn-documentation-fixits.c
deleted file mode 100644
index 273867d..0000000
--- a/test/Sema/warn-documentation-fixits.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
-
-/// \param ZZZZZZZZZZ Blah blah. expected-warning {{parameter 'ZZZZZZZZZZ' not found in the function declaration}}  expected-note {{did you mean 'a'?}}
-int test1(int a);
-
-/// \param aab Blah blah. expected-warning {{parameter 'aab' not found in the function declaration}}  expected-note {{did you mean 'aaa'?}}
-int test2(int aaa, int bbb);
-
-// CHECK: fix-it:"{{.*}}":{4:12-4:22}:"a"
-// CHECK: fix-it:"{{.*}}":{7:12-7:15}:"aaa"
-
diff --git a/test/Sema/warn-documentation-fixits.cpp b/test/Sema/warn-documentation-fixits.cpp
new file mode 100644
index 0000000..732b44d
--- /dev/null
+++ b/test/Sema/warn-documentation-fixits.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+// expected-warning@+1 {{parameter 'ZZZZZZZZZZ' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}}
+/// \param ZZZZZZZZZZ Blah blah.
+int test1(int a);
+
+// expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}}
+/// \param aab Blah blah.
+int test2(int aaa, int bbb);
+
+// expected-warning@+1 {{template parameter 'ZZZZZZZZZZ' not found in the template declaration}} expected-note@+1 {{did you mean 'T'?}}
+/// \tparam ZZZZZZZZZZ Aaa
+template<typename T>
+void test3(T aaa);
+
+// expected-warning@+1 {{template parameter 'SomTy' not found in the template declaration}} expected-note@+1 {{did you mean 'SomeTy'?}}
+/// \tparam SomTy Aaa
+/// \tparam OtherTy Bbb
+template<typename SomeTy, typename OtherTy>
+void test4(SomeTy aaa, OtherTy bbb);
+
+// CHECK: fix-it:"{{.*}}":{5:12-5:22}:"a"
+// CHECK: fix-it:"{{.*}}":{9:12-9:15}:"aaa"
+// CHECK: fix-it:"{{.*}}":{13:13-13:23}:"T"
+// CHECK: fix-it:"{{.*}}":{18:13-18:18}:"SomeTy"
+
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index 69e12b5..d99520b 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -1,4 +1,8 @@
-// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s
+
+// This file contains lots of corner cases, so ensure that XML we generate is not invalid.
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s | FileCheck %s -check-prefix=WRONG
+// WRONG-NOT: CommentXMLInvalid
 
 // expected-warning@+1 {{expected quoted string after equals sign}}
 /// <a href=>
@@ -79,34 +83,92 @@
 
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\returns Aaa
 int test_block_command1(int);
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief \brief Aaa
+/// \brief \returns Aaa
 int test_block_command2(int);
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
 /// \brief
-/// \brief Aaa
+/// \returns Aaa
 int test_block_command3(int);
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
 /// \brief
 ///
-/// \brief Aaa
+/// \returns Aaa
 int test_block_command4(int);
 
 // There is trailing whitespace on one of the following lines, don't remove it!
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
 /// \brief
 /// 
-/// \brief Aaa
+/// \returns Aaa
 int test_block_command5(int);
 
 /// \brief \c Aaa
 int test_block_command6(int);
 
+// expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\brief' here}}
+/// \brief Aaa
+///
+/// Bbb
+///
+/// \brief Ccc
+int test_duplicate_brief1(int);
+
+// expected-warning@+5 {{duplicated command '\short'}} expected-note@+1 {{previous command '\short' here}}
+/// \short Aaa
+///
+/// Bbb
+///
+/// \short Ccc
+int test_duplicate_brief2(int);
+
+// expected-warning@+5 {{duplicated command '\brief'}} expected-note@+1 {{previous command '\short' (an alias of '\brief') here}}
+/// \short Aaa
+///
+/// Bbb
+///
+/// \brief Ccc
+int test_duplicate_brief3(int);
+
+
+// expected-warning@+5 {{duplicated command '\return'}} expected-note@+1 {{previous command '\return' here}}
+/// \return Aaa
+///
+/// Bbb
+///
+/// \return Ccc
+int test_duplicate_returns1(int);
+
+// expected-warning@+5 {{duplicated command '\returns'}} expected-note@+1 {{previous command '\returns' here}}
+/// \returns Aaa
+///
+/// Bbb
+///
+/// \returns Ccc
+int test_duplicate_returns2(int);
+
+// expected-warning@+5 {{duplicated command '\result'}} expected-note@+1 {{previous command '\result' here}}
+/// \result Aaa
+///
+/// Bbb
+///
+/// \result Ccc
+int test_duplicate_returns3(int);
+
+// expected-warning@+5 {{duplicated command '\return'}} expected-note@+1 {{previous command '\returns' (an alias of '\return') here}}
+/// \returns Aaa
+///
+/// Bbb
+///
+/// \return Ccc
+int test_duplicate_returns4(int);
+
+
 // expected-warning@+1 {{'\param' command used in a comment that is not attached to a function declaration}}
 /// \param a Blah blah.
 int test_param1;
@@ -144,17 +206,21 @@
 /// \param [ junk] a Blah blah.
 int test_param10(int a);
 
+// expected-warning@+1 {{parameter 'a' not found in the function declaration}}
+/// \param a Blah blah.
+int test_param11();
+
 // expected-warning@+1 {{parameter 'A' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}}
 /// \param A Blah blah.
-int test_param11(int a);
+int test_param12(int a);
 
 // expected-warning@+1 {{parameter 'aab' not found in the function declaration}} expected-note@+1 {{did you mean 'aaa'?}}
 /// \param aab Blah blah.
-int test_param12(int aaa, int bbb);
+int test_param13(int aaa, int bbb);
 
 // expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
 /// \param aab Blah blah.
-int test_param13(int bbb, int ccc);
+int test_param14(int bbb, int ccc);
 
 class C {
   // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
@@ -163,21 +229,191 @@
 
   // expected-warning@+1 {{parameter 'aaa' not found in the function declaration}}
   /// \param aaa Blah blah.
- int test_param14(int bbb, int ccc);
+ int test_param15(int bbb, int ccc);
 };
 
+// expected-warning@+1 {{parameter 'aab' not found in the function declaration}}
+/// \param aab Blah blah.
+template<typename T>
+void test_param16(int bbb, int ccc);
+
+// expected-warning@+3 {{parameter 'a' is already documented}}
+// expected-note@+1 {{previous documentation}}
+/// \param a Aaa.
+/// \param a Aaa.
+int test_param17(int a);
+
+// expected-warning@+4 {{parameter 'x2' is already documented}}
+// expected-note@+2 {{previous documentation}}
+/// \param x1 Aaa.
+/// \param x2 Bbb.
+/// \param x2 Ccc.
+int test_param18(int x1, int x2, int x3);
+
+
+// expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
+/// \tparam T Aaa
+int test_tparam1;
+
+// expected-warning@+1 {{'\tparam' command used in a comment that is not attached to a template declaration}}
+/// \tparam T Aaa
+void test_tparam2(int aaa);
+
+// expected-warning@+1 {{empty paragraph passed to '\tparam' command}}
+/// \tparam
+/// \param aaa Blah blah
+template<typename T>
+void test_tparam3(T aaa);
+
+// expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}}
+/// \tparam T Aaa
+template<typename TT>
+void test_tparam4(TT aaa);
+
+// expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TT'?}}
+/// \tparam T Aaa
+template<typename TT>
+class test_tparam5 {
+  // expected-warning@+1 {{template parameter 'T' not found in the template declaration}} expected-note@+1 {{did you mean 'TTT'?}}
+  /// \tparam T Aaa
+  template<typename TTT>
+  void test_tparam6(TTT aaa);
+};
+
+/// \tparam T1 Aaa
+/// \tparam T2 Bbb
+template<typename T1, typename T2>
+void test_tparam7(T1 aaa, T2 bbb);
+
+// expected-warning@+1 {{template parameter 'SomTy' not found in the template declaration}} expected-note@+1 {{did you mean 'SomeTy'?}}
+/// \tparam SomTy Aaa
+/// \tparam OtherTy Bbb
+template<typename SomeTy, typename OtherTy>
+void test_tparam8(SomeTy aaa, OtherTy bbb);
+
+// expected-warning@+2 {{template parameter 'T1' is already documented}} expected-note@+1 {{previous documentation}}
+/// \tparam T1 Aaa
+/// \tparam T1 Bbb
+template<typename T1, typename T2>
+void test_tparam9(T1 aaa, T2 bbb);
+
+/// \tparam T Aaa
+/// \tparam TT Bbb
+template<template<typename T> class TT>
+void test_tparam10(TT<int> aaa);
+
+/// \tparam T Aaa
+/// \tparam TT Bbb
+/// \tparam TTT Ccc
+template<template<template<typename T> class TT, class C> class TTT>
+void test_tparam11();
+
+/// \tparam I Aaa
+template<int I>
+void test_tparam12();
+
+template<typename T, typename U>
+class test_tparam13 { };
+
+/// \tparam T Aaa
+template<typename T>
+using test_tparam14 = test_tparam13<T, int>;
+
+// expected-warning@+1 {{template parameter 'U' not found in the template declaration}} expected-note@+1 {{did you mean 'T'?}}
+/// \tparam U Aaa
+template<typename T>
+using test_tparam15 = test_tparam13<T, int>;
+
+// no-warning
+/// \returns Aaa
+int test_returns_right_decl_1(int);
+
+class test_returns_right_decl_2 {
+  // no-warning
+  /// \returns Aaa
+  int test_returns_right_decl_3(int);
+};
+
+// no-warning
+/// \returns Aaa
+template<typename T>
+int test_returns_right_decl_4(T aaa);
+
+// no-warning
+/// \returns Aaa
+template<>
+int test_returns_right_decl_4(int aaa);
+
+/// \returns Aaa
+template<typename T>
+T test_returns_right_decl_5(T aaa);
+
+// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+/// \returns Aaa
+int test_returns_wrong_decl_1;
+
+// expected-warning@+1 {{'\return' command used in a comment that is not attached to a function or method declaration}}
+/// \return Aaa
+int test_returns_wrong_decl_2;
+
+// expected-warning@+1 {{'\result' command used in a comment that is not attached to a function or method declaration}}
+/// \result Aaa
+int test_returns_wrong_decl_3;
+
+// expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}}
+/// \returns Aaa
+void test_returns_wrong_decl_4(int);
+
+// expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}}
+/// \returns Aaa
+template<typename T>
+void test_returns_wrong_decl_5(T aaa);
+
+// expected-warning@+1 {{'\returns' command used in a comment that is attached to a function returning void}}
+/// \returns Aaa
+template<>
+void test_returns_wrong_decl_5(int aaa);
+
+// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+/// \returns Aaa
+struct test_returns_wrong_decl_6 { };
+
+// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+/// \returns Aaa
+class test_returns_wrong_decl_7 {
+  // expected-warning@+1 {{'\returns' command used in a comment that is attached to a constructor}}
+  /// \returns Aaa
+  test_returns_wrong_decl_7();
+
+  // expected-warning@+1 {{'\returns' command used in a comment that is attached to a destructor}}
+  /// \returns Aaa
+  ~test_returns_wrong_decl_7();
+};
+
+// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+/// \returns Aaa
+enum test_returns_wrong_decl_8 {
+  // expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+  /// \returns Aaa
+  test_returns_wrong_decl_9
+};
+
+// expected-warning@+1 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+/// \returns Aaa
+namespace test_returns_wrong_decl_10 { };
+
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-int test1; ///< \brief\brief Aaa
+int test1; ///< \brief\author Aaa
 
 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
-int test2, ///< \brief\brief Aaa
-    test3; ///< \brief\brief Aaa
+int test2, ///< \brief\author Aaa
+    test3; ///< \brief\author Aaa
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
 int test4; ///< \brief
-           ///< \brief Aaa
+           ///< \author Aaa
 
 
 // Check that we attach the comment to the declaration during parsing in the
@@ -185,100 +421,296 @@
 // documentation comments that are not attached to anything.
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 int test_attach1;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 int test_attach2(int);
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 struct test_attach3 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   int test_attach4;
 
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  int test_attach5; ///< \brief\brief Aaa
+  int test_attach5; ///< \brief\author Aaa
 
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   int test_attach6(int);
 };
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 class test_attach7 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   int test_attach8;
 
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  int test_attach9; ///< \brief\brief Aaa
+  int test_attach9; ///< \brief\author Aaa
 
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   int test_attach10(int);
 };
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 enum test_attach9 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   test_attach10,
 
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  test_attach11 ///< \brief\brief Aaa
+  test_attach11 ///< \brief\author Aaa
 };
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 struct test_noattach12 *test_attach13;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 typedef struct test_noattach14 *test_attach15;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 typedef struct test_attach16 { int a; } test_attach17;
 
 struct S { int a; };
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 struct S *test_attach18;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 typedef struct S *test_attach19;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 struct test_attach20;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 typedef struct test_attach21 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   int test_attach22;
 } test_attach23;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 namespace test_attach24 {
   // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-  /// \brief\brief Aaa
+  /// \brief\author Aaa
   namespace test_attach25 {
   }
 }
 
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T>
+void test_attach26(T aaa);
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T, typename U>
+void test_attach27(T aaa, U bbb);
+
+// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<>
+void test_attach27(int aaa, int bbb);
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T>
+class test_attach28 {
+  T aaa;
+};
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+using test_attach29 = test_attach28<int>;
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T, typename U>
+class test_attach30 { };
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T>
+class test_attach30<T, int> { };
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+template<>
+class test_attach30<int, int> { };
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+template<typename T>
+using test_attach31 = test_attach30<T, int>;
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T, typename U, typename V>
+class test_attach32 { };
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T, typename U>
+class test_attach32<T, U, int> { };
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T>
+class test_attach32<T, int, int> { };
+
+// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<>
+class test_attach32<int, int, int> { };
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+class test_attach33 {
+  // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+  /// \brief\author Aaa
+  /// \tparam T Aaa
+  template<typename T, typename U>
+  void test_attach34(T aaa, U bbb);
+};
+
+template<typename T>
+class test_attach35 {
+  // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
+  // expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
+  /// \brief\author Aaa
+  /// \tparam T Aaa
+  template<typename TT, typename UU>
+  void test_attach36(TT aaa, UU bbb);
+};
+
+// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<> template<>
+void test_attach35<int>::test_attach36(int aaa, int bbb) {}
+
+template<typename T>
+class test_attach37 {
+  // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
+  // expected-warning@+2 {{'\tparam' command used in a comment that is not attached to a template declaration}}
+  /// \brief\author Aaa
+  /// \tparam T Aaa
+  void test_attach38(int aaa, int bbb);
+
+  void test_attach39(int aaa, int bbb);
+};
+
+// expected-warning@+2 {{empty paragraph passed to '\brief' command}}
+// expected-warning@+2 {{template parameter 'T' not found in the template declaration}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<>
+void test_attach37<int>::test_attach38(int aaa, int bbb) {}
+
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \brief\author Aaa
+/// \tparam T Aaa
+template<typename T>
+void test_attach37<T>::test_attach39(int aaa, int bbb) {}
+
+// We used to emit warning that parameter 'a' is not found because we parsed
+// the comment in context of the redeclaration which does not have parameter
+// names.
+template <typename T>
+struct test_attach38 {
+  /*!
+    \param a  First param
+    \param b  Second param
+  */
+  template <typename B>
+  void test_attach39(T a, B b);
+};
+
+template <>
+template <typename B>
+void test_attach38<int>::test_attach39(int, B);
+
+
 // PR13411, reduced.  We used to crash on this.
 /**
  * @code Aaa.
  */
 void test_nocrash1(int);
 
+// We used to crash on this.
+// expected-warning@+2 {{empty paragraph passed to '\param' command}}
+// expected-warning@+1 {{empty paragraph passed to '\brief' command}}
+/// \param\brief
+void test_nocrash2(int);
+
+// PR13593, example 1 and 2
+
+/**
+* Bla.
+*/
+template <typename>
+void test_nocrash3();
+
+/// Foo
+template <typename, typename>
+void test_nocrash4() { }
+
+template <typename>
+void test_nocrash3()
+{
+}
+
+// PR13593, example 3
+
+/**
+ * aaa
+ */
+template <typename T>
+inline T test_nocrash5(T a1)
+{
+    return a1;
+}
+
+///
+//,
+
+inline void test_nocrash6()
+{
+    test_nocrash5(1);
+}
+
+// We used to crash on this.
+
+/*!
+  Blah.
+*/
+typedef const struct test_nocrash7 * test_nocrash8;
+
diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m
index 3a661c5..d6af6ed 100644
--- a/test/Sema/warn-documentation.m
+++ b/test/Sema/warn-documentation.m
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wdocumentation -Wdocumentation-pedantic -verify %s
 
 @class NSString;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @interface Test1
 // expected-warning@+2 {{empty paragraph passed to '\brief' command}}
 /**
- * \brief\brief Aaa
+ * \brief\author Aaa
  * \param aaa Aaa
  * \param bbb Bbb
  */
@@ -20,21 +20,21 @@
 + (NSString *)test2:(NSString *)aaa;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @property int test3; // a property: ObjCPropertyDecl
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @property int test4; // a property: ObjCPropertyDecl
 @end
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @interface Test1()
 @end
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @implementation Test1 // a class implementation : ObjCImplementationDecl
 + (NSString *)test1:(NSString *)aaa suffix:(NSString *)bbb {
   return 0;
@@ -48,20 +48,20 @@
 @dynamic test4; // a property implementation: ObjCPropertyImplDecl
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 NSString *_test5;
 @end
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @interface Test1(Test1Category) // a category: ObjCCategoryDecl
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 + (NSString *)test3:(NSString *)aaa;
 @end
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @implementation Test1(Test1Category) // a category implementation: ObjCCategoryImplDecl
 + (NSString *)test3:(NSString *)aaa {
   return 0;
@@ -69,16 +69,25 @@
 @end
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @protocol TestProto1 // a protocol: ObjCProtocolDecl
 @end
 
 int a;
 
 // expected-warning@+1 {{empty paragraph passed to '\brief' command}}
-/// \brief\brief Aaa
+/// \brief\author Aaa
 @interface Test4
 @end
 
 int b;
 
+@interface TestReturns1
+/// \returns Aaa
+- (int)test1:(NSString *)aaa;
+
+// expected-warning@+1 {{'\returns' command used in a comment that is attached to a method returning void}}
+/// \returns Aaa
+- (void)test2:(NSString *)aaa;
+@end
+
diff --git a/test/Sema/warn-self-assign-field.mm b/test/Sema/warn-self-assign-field.mm
index ad0ff3e..3ba8d62 100644
--- a/test/Sema/warn-self-assign-field.mm
+++ b/test/Sema/warn-self-assign-field.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -verify %s
 
 class S {
  public:
diff --git a/test/Sema/warn-strncat-size.c b/test/Sema/warn-strncat-size.c
index 7157edf..dcc3367 100644
--- a/test/Sema/warn-strncat-size.c
+++ b/test/Sema/warn-strncat-size.c
@@ -59,7 +59,7 @@
   char z[1];
   char str[] = "hi";
 
-  strncat(z, str, sizeof(z)); // expected-warning{{the value of the size argument in 'strncat' is too large, might lead to a buffer overflow}}
+  strncat(z, str, sizeof(z)); // expected-warning{{the value of the size argument to 'strncat' is wrong}}
 }
 
 // Support VLAs.
@@ -69,3 +69,8 @@
 
   strncat(z, str, sizeof(str)); // expected-warning {{size argument in 'strncat' call appears to be size of the source}} expected-note {{change the argument to be the free space in the destination buffer minus the terminating null byte}}
 }
+
+// Non-array type gets a different error message.
+void f(char* s, char* d) {
+  strncat(d, s, sizeof(d)); // expected-warning {{the value of the size argument to 'strncat' is wrong}}
+}
diff --git a/test/Sema/warn-type-safety-mpi-hdf5.c b/test/Sema/warn-type-safety-mpi-hdf5.c
new file mode 100644
index 0000000..9c2ee96
--- /dev/null
+++ b/test/Sema/warn-type-safety-mpi-hdf5.c
@@ -0,0 +1,307 @@
+// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -DMPICH -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -std=c++98 -DOPEN_MPI -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -std=c++98 -DMPICH -fsyntax-only -verify %s
+//
+// RUN: %clang_cc1 -std=c99 -DOPEN_MPI -fno-signed-char -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -DMPICH -fno-signed-char -fsyntax-only -verify %s
+
+//===--- limits.h mock ----------------------------------------------------===//
+
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MIN 0
+#define CHAR_MAX (__SCHAR_MAX__*2  +1)
+#else
+#define CHAR_MIN (-__SCHAR_MAX__-1)
+#define CHAR_MAX __SCHAR_MAX__
+#endif
+
+//===--- mpi.h mock -------------------------------------------------------===//
+
+#define NULL ((void *)0)
+
+#ifdef OPEN_MPI
+typedef struct ompi_datatype_t *MPI_Datatype;
+#endif
+
+#ifdef MPICH
+typedef int MPI_Datatype;
+#endif
+
+int MPI_Send(void *buf, int count, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,1,3) ));
+
+int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+               void *recvbuf, int recvcount, MPI_Datatype recvtype)
+               __attribute__(( pointer_with_type_tag(mpi,1,3), pointer_with_type_tag(mpi,4,6) ));
+
+#ifdef OPEN_MPI
+// OpenMPI and LAM/MPI-style datatype definitions
+
+#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
+
+#define MPI_DATATYPE_NULL OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_datatype_null)
+#define MPI_FLOAT         OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float)
+#define MPI_INT           OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int)
+#define MPI_LONG          OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long)
+#define MPI_LONG_LONG_INT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_long_long_int)
+#define MPI_CHAR          OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_char)
+
+#define MPI_FLOAT_INT     OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float_int)
+#define MPI_2INT          OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_2int)
+
+#define MPI_IN_PLACE ((void *) 1)
+
+extern struct ompi_predefined_datatype_t ompi_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_float         __attribute__(( type_tag_for_datatype(mpi,float) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_int           __attribute__(( type_tag_for_datatype(mpi,int) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_long          __attribute__(( type_tag_for_datatype(mpi,long) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_char          __attribute__(( type_tag_for_datatype(mpi,char) ));
+
+struct ompi_struct_mpi_float_int {float f; int i;};
+extern struct ompi_predefined_datatype_t ompi_mpi_float_int     __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_float_int, layout_compatible) ));
+
+struct ompi_struct_mpi_2int {int i1; int i2;};
+extern struct ompi_predefined_datatype_t ompi_mpi_2int          __attribute__(( type_tag_for_datatype(mpi, struct ompi_struct_mpi_2int, layout_compatible) ));
+#endif
+
+#ifdef MPICH
+// MPICH2 and MVAPICH2-style datatype definitions
+
+#define MPI_COMM_WORLD ((MPI_Comm) 0x44000000)
+
+#define MPI_DATATYPE_NULL ((MPI_Datatype) 0xa0000000)
+#define MPI_FLOAT         ((MPI_Datatype) 0xa0000001)
+#define MPI_INT           ((MPI_Datatype) 0xa0000002)
+#define MPI_LONG          ((MPI_Datatype) 0xa0000003)
+#define MPI_LONG_LONG_INT ((MPI_Datatype) 0xa0000004)
+#define MPI_CHAR          ((MPI_Datatype) 0xa0000005)
+
+#define MPI_FLOAT_INT     ((MPI_Datatype) 0xa0000006)
+#define MPI_2INT          ((MPI_Datatype) 0xa0000007)
+
+#define MPI_IN_PLACE  (void *) -1
+
+static const MPI_Datatype mpich_mpi_datatype_null __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) )) = 0xa0000000;
+static const MPI_Datatype mpich_mpi_float         __attribute__(( type_tag_for_datatype(mpi,float) ))             = 0xa0000001;
+static const MPI_Datatype mpich_mpi_int           __attribute__(( type_tag_for_datatype(mpi,int) ))               = 0xa0000002;
+static const MPI_Datatype mpich_mpi_long          __attribute__(( type_tag_for_datatype(mpi,long) ))              = 0xa0000003;
+static const MPI_Datatype mpich_mpi_long_long_int __attribute__(( type_tag_for_datatype(mpi,long long int) ))     = 0xa0000004;
+static const MPI_Datatype mpich_mpi_char          __attribute__(( type_tag_for_datatype(mpi,char) ))              = 0xa0000005;
+
+struct mpich_struct_mpi_float_int { float f; int i; };
+struct mpich_struct_mpi_2int { int i1; int i2; };
+static const MPI_Datatype mpich_mpi_float_int     __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_float_int, layout_compatible) )) = 0xa0000006;
+static const MPI_Datatype mpich_mpi_2int          __attribute__(( type_tag_for_datatype(mpi, struct mpich_struct_mpi_2int, layout_compatible) )) = 0xa0000007;
+#endif
+
+//===--- HDF5 headers mock ------------------------------------------------===//
+
+typedef int hid_t;
+void H5open(void);
+
+#ifndef HDF_PRIVATE
+#define H5OPEN  H5open(),
+#else
+#define H5OPEN
+#endif
+
+#define H5T_NATIVE_CHAR         (CHAR_MIN?H5T_NATIVE_SCHAR:H5T_NATIVE_UCHAR)
+#define H5T_NATIVE_SCHAR        (H5OPEN H5T_NATIVE_SCHAR_g)
+#define H5T_NATIVE_UCHAR        (H5OPEN H5T_NATIVE_UCHAR_g)
+#define H5T_NATIVE_INT          (H5OPEN H5T_NATIVE_INT_g)
+#define H5T_NATIVE_LONG         (H5OPEN H5T_NATIVE_LONG_g)
+
+hid_t H5T_NATIVE_SCHAR_g __attribute__(( type_tag_for_datatype(hdf5,signed char) ));
+hid_t H5T_NATIVE_UCHAR_g __attribute__(( type_tag_for_datatype(hdf5,unsigned char) ));
+hid_t H5T_NATIVE_INT_g   __attribute__(( type_tag_for_datatype(hdf5,int) ));
+hid_t H5T_NATIVE_LONG_g  __attribute__(( type_tag_for_datatype(hdf5,long) ));
+
+void H5Dwrite(hid_t mem_type_id, const void *buf) __attribute__(( pointer_with_type_tag(hdf5,2,1) ));
+
+//===--- Tests ------------------------------------------------------------===//
+
+//===--- MPI
+
+struct pair_float_int
+{
+  float f; int i;
+};
+
+struct pair_int_int
+{
+  int i1; int i2;
+};
+
+void test_mpi_predefined_types(
+    int *int_buf,
+    long *long_buf1,
+    long *long_buf2,
+    void *void_buf,
+    struct pair_float_int *pfi,
+    struct pair_int_int *pii)
+{
+  char char_buf[255];
+
+  // Layout-compatible scalar types.
+  MPI_Send(int_buf,   1, MPI_INT); // no-warning
+
+  // Layout-compatible class types.
+  MPI_Send(pfi, 1, MPI_FLOAT_INT); // no-warning
+  MPI_Send(pii, 1, MPI_2INT); // no-warning
+
+  // Layout-incompatible scalar types.
+  MPI_Send(long_buf1, 1, MPI_INT); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+
+  // Layout-incompatible class types.
+  MPI_Send(pii, 1, MPI_FLOAT_INT); // expected-warning {{argument type 'struct pair_int_int *' doesn't match specified 'mpi' type tag}}
+  MPI_Send(pfi, 1, MPI_2INT); // expected-warning {{argument type 'struct pair_float_int *' doesn't match specified 'mpi' type tag}}
+
+  // Layout-incompatible class-scalar types.
+  MPI_Send(long_buf1, 1, MPI_2INT); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag}}
+
+  // Function with two buffers.
+  MPI_Gather(long_buf1, 1, MPI_INT,  // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+             long_buf2, 1, MPI_INT); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+
+  // Array buffers should work like pointer buffers.
+  MPI_Send(char_buf,  255, MPI_CHAR); // no-warning
+
+  // Explicit casts should not be dropped.
+  MPI_Send((int *) char_buf,  255, MPI_INT); // no-warning
+  MPI_Send((int *) char_buf,  255, MPI_CHAR); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'char *'}}
+
+  // `void*' buffer should never warn.
+  MPI_Send(void_buf,  255, MPI_CHAR); // no-warning
+
+  // We expect that MPI_IN_PLACE is `void*', shouldn't warn.
+  MPI_Gather(MPI_IN_PLACE, 0, MPI_INT,
+             int_buf,      1, MPI_INT);
+
+  // Special handling for MPI_DATATYPE_NULL: buffer pointer should be either
+  // a `void*' pointer or a null pointer constant.
+  MPI_Gather(NULL,    0, MPI_DATATYPE_NULL, // no-warning
+             int_buf, 1, MPI_INT);
+
+  MPI_Gather(int_buf, 0, MPI_DATATYPE_NULL, // expected-warning {{specified mpi type tag requires a null pointer}}
+             int_buf, 1, MPI_INT);
+}
+
+MPI_Datatype my_int_datatype __attribute__(( type_tag_for_datatype(mpi,int) ));
+
+struct S1 { int a; int b; };
+MPI_Datatype my_s1_datatype __attribute__(( type_tag_for_datatype(mpi,struct S1) ));
+
+// Layout-compatible to S1, but should be treated as a different type.
+struct S2 { int a; int b; };
+MPI_Datatype my_s2_datatype __attribute__(( type_tag_for_datatype(mpi,struct S2) ));
+
+void test_user_types(int *int_buf,
+                     long *long_buf,
+                     struct S1 *s1_buf,
+                     struct S2 *s2_buf)
+{
+  MPI_Send(int_buf,  1, my_int_datatype); // no-warning
+  MPI_Send(long_buf, 1, my_int_datatype); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+
+  MPI_Send(s1_buf, 1, my_s1_datatype); // no-warning
+  MPI_Send(s1_buf, 1, my_s2_datatype); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag that requires 'struct S2 *'}}
+
+  MPI_Send(long_buf, 1, my_s1_datatype); // expected-warning {{argument type 'long *' doesn't match specified 'mpi' type tag that requires 'struct S1 *'}}
+  MPI_Send(s1_buf, 1, MPI_INT); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag that requires 'int *'}}
+}
+
+MPI_Datatype my_unknown_datatype;
+
+void test_not_annotated(int *int_buf,
+                        long *long_buf,
+                        MPI_Datatype type)
+{
+  // Using 'MPI_Datatype's without attributes should not produce warnings.
+  MPI_Send(long_buf, 1, my_unknown_datatype); // no-warning
+  MPI_Send(int_buf, 1, type); // no-warning
+}
+
+struct S1_compat { int a; int b; };
+MPI_Datatype my_s1_compat_datatype
+    __attribute__(( type_tag_for_datatype(mpi, struct S1_compat, layout_compatible) ));
+
+struct S3        { int a; long b; double c; double d; struct S1 s1; };
+struct S3_compat { int a; long b; double c; double d; struct S2 s2; };
+MPI_Datatype my_s3_compat_datatype
+    __attribute__(( type_tag_for_datatype(mpi, struct S3_compat, layout_compatible) ));
+
+struct S4        { char c; };
+struct S4_compat { signed char c; };
+MPI_Datatype my_s4_compat_datatype
+    __attribute__(( type_tag_for_datatype(mpi, struct S4_compat, layout_compatible) ));
+
+union U1        { int a; long b; double c; double d; struct S1 s1; };
+union U1_compat { long b; double c; struct S2 s; int a; double d; };
+MPI_Datatype my_u1_compat_datatype
+    __attribute__(( type_tag_for_datatype(mpi, union U1_compat, layout_compatible) ));
+
+union U2 { int a; long b; double c; struct S1 s1; };
+MPI_Datatype my_u2_datatype
+    __attribute__(( type_tag_for_datatype(mpi, union U2, layout_compatible) ));
+
+void test_layout_compatibility(struct S1 *s1_buf, struct S3 *s3_buf,
+                               struct S4 *s4_buf,
+                               union U1 *u1_buf, union U2 *u2_buf)
+{
+  MPI_Send(s1_buf, 1, my_s1_compat_datatype); // no-warning
+  MPI_Send(s3_buf, 1, my_s3_compat_datatype); // no-warning
+  MPI_Send(s1_buf, 1, my_s3_compat_datatype); // expected-warning {{argument type 'struct S1 *' doesn't match specified 'mpi' type tag}}
+  MPI_Send(s4_buf, 1, my_s4_compat_datatype); // expected-warning {{argument type 'struct S4 *' doesn't match specified 'mpi' type tag}}
+  MPI_Send(u1_buf, 1, my_u1_compat_datatype); // no-warning
+  MPI_Send(u1_buf, 1, my_u2_datatype);        // expected-warning {{argument type 'union U1 *' doesn't match specified 'mpi' type tag}}
+  MPI_Send(u2_buf, 1, my_u1_compat_datatype); // expected-warning {{argument type 'union U2 *' doesn't match specified 'mpi' type tag}}
+}
+
+// There is an MPI_REAL predefined in MPI, but some existing MPI programs do
+// this.
+typedef float real;
+#define MPI_REAL MPI_FLOAT
+
+void test_mpi_real_user_type(real *real_buf, float *float_buf)
+{
+  MPI_Send(real_buf,  1, MPI_REAL);  // no-warning
+  MPI_Send(real_buf,  1, MPI_FLOAT); // no-warning
+  MPI_Send(float_buf, 1, MPI_REAL);  // no-warning
+  MPI_Send(float_buf, 1, MPI_FLOAT); // no-warning
+}
+
+//===--- HDF5
+
+void test_hdf5(char *char_buf,
+               signed char *schar_buf,
+               unsigned char *uchar_buf,
+               int *int_buf,
+               long *long_buf)
+{
+  H5Dwrite(H5T_NATIVE_CHAR,  char_buf);  // no-warning
+#ifdef __CHAR_UNSIGNED__
+  H5Dwrite(H5T_NATIVE_CHAR,  schar_buf); // expected-warning {{argument type 'signed char *' doesn't match specified 'hdf5' type tag that requires 'unsigned char *'}}
+  H5Dwrite(H5T_NATIVE_CHAR,  uchar_buf); // no-warning
+#else
+  H5Dwrite(H5T_NATIVE_CHAR,  schar_buf); // no-warning
+  H5Dwrite(H5T_NATIVE_CHAR,  uchar_buf); // expected-warning {{argument type 'unsigned char *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}
+#endif
+  H5Dwrite(H5T_NATIVE_SCHAR, schar_buf); // no-warning
+  H5Dwrite(H5T_NATIVE_UCHAR, uchar_buf); // no-warning
+  H5Dwrite(H5T_NATIVE_INT,   int_buf);   // no-warning
+  H5Dwrite(H5T_NATIVE_LONG,  long_buf);  // no-warning
+
+#ifdef __CHAR_UNSIGNED__
+  H5Dwrite(H5T_NATIVE_CHAR,  int_buf);  // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'unsigned char *'}}
+#else
+  H5Dwrite(H5T_NATIVE_CHAR,  int_buf);  // expected-warning {{argument type 'int *' doesn't match specified 'hdf5' type tag that requires 'signed char *'}}
+#endif
+  H5Dwrite(H5T_NATIVE_INT,   long_buf); // expected-warning {{argument type 'long *' doesn't match specified 'hdf5' type tag that requires 'int *'}}
+
+  // FIXME: we should warn here, but it will cause false positives because
+  // different kinds may use same magic values.
+  //H5Dwrite(MPI_INT, int_buf);
+}
+
diff --git a/test/Sema/warn-type-safety.c b/test/Sema/warn-type-safety.c
new file mode 100644
index 0000000..6f548aa
--- /dev/null
+++ b/test/Sema/warn-type-safety.c
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -x c++ -std=c++98 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -fno-signed-char -fsyntax-only -verify %s
+
+struct A {};
+
+typedef struct A *MPI_Datatype;
+
+int wrong1(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag )); // expected-error {{attribute requires parameter 1 to be an identifier}}
+
+int wrong2(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,0,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+int wrong3(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,3,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+int wrong4(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,1,0) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+int wrong5(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,1,3) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+int wrong6(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,0x8000000000000001ULL,1) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+extern int x;
+
+int wrong7(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,x,2) )); // expected-error {{attribute requires parameter 2 to be an integer constant}}
+
+int wrong8(void *buf, MPI_Datatype datatype)
+    __attribute__(( pointer_with_type_tag(mpi,1,x) )); // expected-error {{attribute requires parameter 3 to be an integer constant}}
+
+int wrong9 __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{attribute only applies to functions and methods}}
+
+int wrong10(double buf, MPI_Datatype type)
+    __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{'pointer_with_type_tag' attribute only applies to pointer arguments}}
+
+
+extern struct A datatype_wrong1
+    __attribute__(( type_tag_for_datatype )); // expected-error {{attribute requires parameter 1 to be an identifier}}
+
+extern struct A datatype_wrong2
+    __attribute__(( type_tag_for_datatype(mpi,1,2) )); // expected-error {{expected a type}}
+
+extern struct A datatype_wrong3
+    __attribute__(( type_tag_for_datatype(mpi,not_a_type) )); // expected-error {{unknown type name 'not_a_type'}}
+
+extern struct A datatype_wrong4
+    __attribute__(( type_tag_for_datatype(mpi,int,int) )); // expected-error {{expected identifier}}
+
+extern struct A datatype_wrong5
+    __attribute__(( type_tag_for_datatype(mpi,int,not_a_flag) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
+
+extern struct A datatype_wrong6
+    __attribute__(( type_tag_for_datatype(mpi,int,layout_compatible,not_a_flag) )); // expected-error {{invalid comparison flag 'not_a_flag'}}
+
+
+// Using a tag with kind A in a place where the function requires kind B should
+// warn.
+
+void A_func(void *ptr, void *tag) __attribute__(( pointer_with_type_tag(a,1,2) ));
+
+extern struct A A_tag __attribute__(( type_tag_for_datatype(a,int) ));
+extern struct A B_tag __attribute__(( type_tag_for_datatype(b,int) ));
+
+void C_func(void *ptr, int tag) __attribute__(( pointer_with_type_tag(c,1,2) ));
+
+static const int C_tag __attribute__(( type_tag_for_datatype(c,int) )) = 10;
+static const int D_tag __attribute__(( type_tag_for_datatype(d,int) )) = 20;
+
+void test_tag_mismatch(int *ptr)
+{
+  A_func(ptr, &A_tag); // no-warning
+  A_func(ptr, &B_tag); // expected-warning {{this type tag was not designed to be used with this function}}
+  C_func(ptr, C_tag); // no-warning
+  C_func(ptr, D_tag); // expected-warning {{this type tag was not designed to be used with this function}}
+  C_func(ptr, 10); // no-warning
+  C_func(ptr, 20); // should warn, but may cause false positives
+}
+
+// Check that we look through typedefs in the special case of allowing 'char'
+// to be matched with 'signed char' or 'unsigned char'.
+void E_func(void *ptr, int tag) __attribute__(( pointer_with_type_tag(e,1,2) ));
+
+typedef char E_char;
+typedef char E_char_2;
+typedef signed char E_char_signed;
+typedef unsigned char E_char_unsigned;
+
+static const int E_tag __attribute__(( type_tag_for_datatype(e,E_char) )) = 10;
+
+void test_char_typedef(char *char_buf,
+                       E_char_2 *e_char_buf,
+                       E_char_signed *e_char_signed_buf,
+                       E_char_unsigned *e_char_unsigned_buf)
+{
+  E_func(char_buf, E_tag);
+  E_func(e_char_buf, E_tag);
+#ifdef __CHAR_UNSIGNED__
+  E_func(e_char_signed_buf, E_tag); // expected-warning {{argument type 'E_char_signed *' (aka 'signed char *') doesn't match specified 'e' type tag that requires 'E_char *' (aka 'char *')}}
+  E_func(e_char_unsigned_buf, E_tag);
+#else
+  E_func(e_char_signed_buf, E_tag);
+  E_func(e_char_unsigned_buf, E_tag); // expected-warning {{argument type 'E_char_unsigned *' (aka 'unsigned char *') doesn't match specified 'e' type tag that requires 'E_char *' (aka 'char *')}}
+#endif
+}
+
+// Tests for argument_with_type_tag.
+
+#define F_DUPFD 10
+#define F_SETLK 20
+
+struct flock { };
+
+static const int F_DUPFD_tag __attribute__(( type_tag_for_datatype(fcntl,int) )) = F_DUPFD;
+static const int F_SETLK_tag __attribute__(( type_tag_for_datatype(fcntl,struct flock *) )) = F_SETLK;
+
+int fcntl(int fd, int cmd, ...) __attribute__(( argument_with_type_tag(fcntl,3,2) ));
+
+void test_argument_with_type_tag(struct flock *f)
+{
+  fcntl(0, F_DUPFD, 10); // no-warning
+  fcntl(0, F_SETLK, f);  // no-warning
+
+  fcntl(0, F_SETLK, 10); // expected-warning {{argument type 'int' doesn't match specified 'fcntl' type tag that requires 'struct flock *'}}
+  fcntl(0, F_DUPFD, f);  // expected-warning {{argument type 'struct flock *' doesn't match specified 'fcntl' type tag that requires 'int'}}
+}
+
+void test_tag_expresssion(int b) {
+  fcntl(0, b ? F_DUPFD : F_SETLK, 10); // no-warning
+  fcntl(0, b + F_DUPFD, 10); // no-warning
+  fcntl(0, (b, F_DUPFD), 10); // expected-warning {{expression result unused}}
+}
+
+// Check that using 64-bit magic values as tags works and tag values do not
+// overflow internally.
+void F_func(void *ptr, unsigned long long tag) __attribute__((pointer_with_type_tag(f,1,2) ));
+
+static const unsigned long long F_tag1 __attribute__(( type_tag_for_datatype(f,int) )) = 0xFFFFFFFFFFFFFFFFULL;
+static const unsigned long long F_tag2 __attribute__(( type_tag_for_datatype(f,float) )) = 0xFFFFFFFFULL;
+
+void test_64bit_magic(int *int_ptr, float *float_ptr)
+{
+  F_func(int_ptr,   0xFFFFFFFFFFFFFFFFULL);
+  F_func(int_ptr,   0xFFFFFFFFULL);         // expected-warning {{argument type 'int *' doesn't match specified 'f' type tag that requires 'float *'}}
+  F_func(float_ptr, 0xFFFFFFFFFFFFFFFFULL); // expected-warning {{argument type 'float *' doesn't match specified 'f' type tag that requires 'int *'}}
+  F_func(float_ptr, 0xFFFFFFFFULL);
+}
+
+
diff --git a/test/Sema/warn-type-safety.cpp b/test/Sema/warn-type-safety.cpp
new file mode 100644
index 0000000..d053fba
--- /dev/null
+++ b/test/Sema/warn-type-safety.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef struct ompi_datatype_t *MPI_Datatype;
+
+#define OMPI_PREDEFINED_GLOBAL(type, global) ((type) &(global))
+
+#define MPI_FLOAT OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_float)
+#define MPI_INT   OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_int)
+#define MPI_NULL  OMPI_PREDEFINED_GLOBAL(MPI_Datatype, ompi_mpi_null)
+
+extern struct ompi_predefined_datatype_t ompi_mpi_float __attribute__(( type_tag_for_datatype(mpi,float) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_int   __attribute__(( type_tag_for_datatype(mpi,int) ));
+extern struct ompi_predefined_datatype_t ompi_mpi_null  __attribute__(( type_tag_for_datatype(mpi,void,must_be_null) ));
+
+int f(int x) { return x; }
+static const int wrong_init __attribute__(( type_tag_for_datatype(zzz,int) )) = f(100); // expected-error {{'type_tag_for_datatype' attribute requires the initializer to be an integral constant expression}}
+
+//===--- Tests ------------------------------------------------------------===//
+// Check that hidden 'this' is handled correctly.
+
+class C
+{
+public:
+  void f1(void *buf, int count, MPI_Datatype datatype)
+       __attribute__(( pointer_with_type_tag(mpi,5,6) )); // expected-error {{attribute parameter 2 is out of bounds}}
+
+  void f2(void *buf, int count, MPI_Datatype datatype)
+       __attribute__(( pointer_with_type_tag(mpi,2,5) )); // expected-error {{attribute parameter 3 is out of bounds}}
+
+  void f3(void *buf, int count, MPI_Datatype datatype)
+       __attribute__(( pointer_with_type_tag(mpi,1,5) )); // expected-error {{attribute is invalid for the implicit this argument}}
+
+  void f4(void *buf, int count, MPI_Datatype datatype)
+       __attribute__(( pointer_with_type_tag(mpi,2,1) )); // expected-error {{attribute is invalid for the implicit this argument}}
+
+  void MPI_Send(void *buf, int count, MPI_Datatype datatype)
+       __attribute__(( pointer_with_type_tag(mpi,2,4) )); // no-error
+};
+
+// Check that we don't crash on type and value dependent expressions.
+template<int a>
+void value_dep(void *buf, int count, MPI_Datatype datatype)
+     __attribute__(( pointer_with_type_tag(mpi,a,5) )); // expected-error {{attribute requires parameter 2 to be an integer constant}}
+
+class OperatorIntStar
+{
+public:
+  operator int*();
+};
+
+void test1(C *c, int *int_buf)
+{
+  c->MPI_Send(int_buf, 1, MPI_INT); // no-warning
+  c->MPI_Send(int_buf, 1, MPI_FLOAT); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'float *'}}
+
+  OperatorIntStar i;
+  c->MPI_Send(i, 1, MPI_INT); // no-warning
+  c->MPI_Send(i, 1, MPI_FLOAT); // expected-warning {{argument type 'int *' doesn't match specified 'mpi' type tag that requires 'float *'}}
+}
+
+template<typename T>
+void test2(C *c, int *int_buf, T tag)
+{
+  c->MPI_Send(int_buf, 1, tag); // no-warning
+}
+
+void test3(C *c, int *int_buf) {
+  test2(c, int_buf, MPI_INT);
+  test2(c, int_buf, MPI_NULL);
+}
+
diff --git a/test/SemaCXX/PR9460.cpp b/test/SemaCXX/PR9460.cpp
index 5b8b7b2..0dd8446 100644
--- a/test/SemaCXX/PR9460.cpp
+++ b/test/SemaCXX/PR9460.cpp
@@ -8,11 +8,11 @@
   basic_string(aT*);
 };
 
-struct runtime_error{ // expected-note{{candidate constructor}}
-  runtime_error( // expected-note{{candidate constructor}}
+struct runtime_error{
+  runtime_error(
 basic_string<char> struct{ // expected-error {{cannot combine with previous 'type-name' declaration specifier}}
 a(){ // expected-error {{requires a type specifier}}
-  runtime_error(0); // expected-error{{no matching conversion for functional-style cast from 'int' to 'runtime_error'}}
+  runtime_error(0);
 }
 }
 );
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index 2d9624e..f3d818a 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -163,7 +163,7 @@
 
 namespace test5 {
   struct A {
-    operator int() __attribute__((deprecated)); // expected-note 2 {{declared here}}
+    operator int() __attribute__((deprecated)); // expected-note 3 {{declared here}}
     operator long();
   };
   void test1(A a) {
diff --git a/test/SemaCXX/condition.cpp b/test/SemaCXX/condition.cpp
index 993f8e1..ec5eb17 100644
--- a/test/SemaCXX/condition.cpp
+++ b/test/SemaCXX/condition.cpp
@@ -7,7 +7,7 @@
 
   typedef int arr[10];
   while (arr x=0) ; // expected-error {{an array type is not allowed here}} expected-error {{array initializer must be an initializer list}}
-  while (int f()=0) ; // expected-warning {{interpreted as a function declaration}} expected-note {{initializer}} expected-error {{a function type is not allowed here}}
+  while (int f()=0) ; // expected-error {{a function type is not allowed here}}
 
   struct S {} s;
   if (s) ++x; // expected-error {{value of type 'struct S' is not contextually convertible to 'bool'}}
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 4aee913..a80eda4 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -2,7 +2,7 @@
 
 // C++ rules for ?: are a lot stricter than C rules, and have to take into
 // account more conversion options.
-// This test runs in C++0x mode for the contextual conversion of the condition.
+// This test runs in C++11 mode for the contextual conversion of the condition.
 
 struct ToBool { explicit operator bool(); };
 
@@ -328,3 +328,27 @@
     (void)(true ? (void*)0 : A()); // expected-error{{incompatible operand types}}
   }
 }
+
+namespace DR587 {
+  template<typename T>
+  const T *f(bool b) {
+    static T t1 = T();
+    static const T t2 = T();
+    return &(b ? t1 : t2);
+  }
+  struct S {};
+  template const int *f(bool);
+  template const S *f(bool);
+
+  extern bool b;
+  int i = 0;
+  const int ci = 0;
+  volatile int vi = 0;
+  const volatile int cvi = 0;
+
+  const int &cir = b ? i : ci;
+  volatile int &vir = b ? vi : i;
+  const volatile int &cvir1 = b ? ci : cvi;
+  const volatile int &cvir2 = b ? cvi : vi;
+  const volatile int &cvir3 = b ? ci : vi; // expected-error{{volatile lvalue reference to type 'const volatile int' cannot bind to a temporary of type 'int'}}
+}
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 2b9a4adf..a3ead79 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -verify -std=c++11 -pedantic %s -Wno-comment
+// RUN: %clang_cc1 -triple i686-linux -Wno-string-plus-int -fsyntax-only -fcxx-exceptions -verify -std=c++11 -pedantic %s -Wno-comment
 
 namespace StaticAssertFoldTest {
 
@@ -710,10 +710,16 @@
 static_assert((Base2*)(Derived*)(Base*)pb1 == pok2, "");
 static_assert((Derived*)(Base*)pb1 == (Derived*)pok2, "");
 
-constexpr Base *nullB = 42 - 6 * 7;
+constexpr Base *nullB = 42 - 6 * 7; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *const'}}
 static_assert((Bottom*)nullB == 0, "");
 static_assert((Derived*)nullB == 0, "");
 static_assert((void*)(Bottom*)nullB == (void*)(Derived*)nullB, "");
+Base * nullB2 = '\0'; // expected-warning {{expression which evaluates to zero treated as a null pointer constant of type 'Class::Base *'}}
+Base * nullB3 = (0);
+// We suppress the warning in unevaluated contexts to workaround some gtest
+// behavior. Once this becomes an error this isn't a problem anymore.
+static_assert(nullB == (1 - 1), "");
+
 
 namespace ConversionOperators {
 
@@ -1294,9 +1300,9 @@
 // Constructors can be implicitly constexpr, even for a non-literal type.
 namespace ImplicitConstexpr {
   struct Q { Q() = default; Q(const Q&) = default; Q(Q&&) = default; ~Q(); }; // expected-note 3{{here}}
-  struct R { constexpr R(); constexpr R(const R&); constexpr R(R&&); ~R(); };
+  struct R { constexpr R() noexcept; constexpr R(const R&) noexcept; constexpr R(R&&) noexcept; ~R() noexcept; };
   struct S { R r; }; // expected-note 3{{here}}
-  struct T { T(const T&); T(T &&); ~T(); };
+  struct T { T(const T&) noexcept; T(T &&) noexcept; ~T() noexcept; };
   struct U { T t; }; // expected-note 3{{here}}
   static_assert(!__is_literal_type(Q), "");
   static_assert(!__is_literal_type(R), "");
@@ -1351,3 +1357,20 @@
   static_assert(x[1].m == 5, "");
   static_assert(x[2].m == 6, "");
 }
+
+// Indirectly test that an implicit lvalue-to-rvalue conversion is performed
+// when a conditional operator has one argument of type void and where the other
+// is a glvalue of class type.
+namespace ConditionalLValToRVal {
+  struct A {
+    constexpr A(int a) : v(a) {}
+    int v;
+  };
+
+  constexpr A f(const A &a) {
+    return a.v == 0 ? throw a : a;
+  }
+
+  constexpr A a(4);
+  static_assert(f(a).v == 4, "");
+}
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index 1a4e544..f503d01 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -232,13 +232,13 @@
 // <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 A : public std::exception {}; // expected-error {{undeclared identifier}} expected-error {{expected class name}} expected-note 2 {{candidate}}
   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}}
+      : A(e), m_String(e.m_String), m_ErrorStr(__null) { // expected-error {{does not name}} expected-error {{no member named 'm_String' in 'test3::B'}}
     }
   };
 }
diff --git a/test/SemaCXX/convert-to-bool.cpp b/test/SemaCXX/convert-to-bool.cpp
index c9a3555..b52f11c 100644
--- a/test/SemaCXX/convert-to-bool.cpp
+++ b/test/SemaCXX/convert-to-bool.cpp
@@ -62,6 +62,5 @@
 
 void test_copy_init_conversions(C c) {
   A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
-  B &b = b; // okay
+  B &b = c; // okay
 }
-
diff --git a/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
index f002973..641760e 100644
--- a/test/SemaCXX/cxx0x-cursory-default-delete.cpp
+++ b/test/SemaCXX/cxx0x-cursory-default-delete.cpp
@@ -24,7 +24,8 @@
   non_const_copy ncc;
   non_const_copy ncc2 = ncc;
   ncc = ncc2;
-  const non_const_copy cncc;
+  const non_const_copy cncc{};
+  const non_const_copy cncc1; // expected-error {{default initialization of an object of const type 'const non_const_copy' requires a user-provided default constructor}}
   non_const_copy ncc3 = cncc; // expected-error {{no matching}}
   ncc = cncc; // expected-error {{no viable overloaded}}
 };
@@ -69,7 +70,7 @@
 };
 struct except_spec_d_match : except_spec_a, except_spec_b {
   except_spec_d_match() throw(A, B) = default;
-};  
+};
 
 // gcc-compatibility: allow attributes on default definitions
 // (but not normal definitions)
diff --git a/test/SemaCXX/cxx0x-defaulted-functions.cpp b/test/SemaCXX/cxx0x-defaulted-functions.cpp
index 595d428..ce7ee67 100644
--- a/test/SemaCXX/cxx0x-defaulted-functions.cpp
+++ b/test/SemaCXX/cxx0x-defaulted-functions.cpp
@@ -57,3 +57,95 @@
   friend S<bar>::S(const S&);
   friend S<bar>::S(S&&);
 };
+
+namespace DefaultedFnExceptionSpec {
+  // DR1330: The exception-specification of an implicitly-declared special
+  // member function is evaluated as needed.
+  template<typename T> T &&declval();
+  template<typename T> struct pair {
+    pair(const pair&) noexcept(noexcept(T(declval<T>())));
+  };
+
+  struct Y;
+  struct X { X(); X(const Y&); };
+  struct Y { pair<X> p; };
+
+  template<typename T>
+  struct A {
+    pair<T> p;
+  };
+  struct B {
+    B();
+    B(const A<B>&);
+  };
+
+  // Don't crash here.
+  void f() {
+    X x = X();
+    (void)noexcept(B(declval<B>()));
+  }
+
+  template<typename T>
+  struct Error {
+    // FIXME: Type canonicalization causes all the errors to point at the first
+    // declaration which has the type 'void () noexcept (T::error)'. We should
+    // get one error for 'Error<int>::Error()' and one for 'Error<int>::~Error()'.
+    void f() noexcept(T::error); // expected-error 2{{has no members}}
+
+    Error() noexcept(T::error);
+    Error(const Error&) noexcept(T::error);
+    Error(Error&&) noexcept(T::error);
+    Error &operator=(const Error&) noexcept(T::error);
+    Error &operator=(Error&&) noexcept(T::error);
+    ~Error() noexcept(T::error);
+  };
+
+  struct DelayImplicit {
+    Error<int> e;
+  };
+
+  // Don't instantiate the exception specification here.
+  void test1(decltype(declval<DelayImplicit>() = DelayImplicit(DelayImplicit())));
+  void test2(decltype(declval<DelayImplicit>() = declval<const DelayImplicit>()));
+  void test3(decltype(DelayImplicit(declval<const DelayImplicit>())));
+
+  // Any odr-use causes the exception specification to be evaluated.
+  struct OdrUse { // \
+    expected-note {{instantiation of exception specification for 'Error'}} \
+    expected-note {{instantiation of exception specification for '~Error'}}
+    Error<int> e;
+  };
+  OdrUse use; // expected-note {{implicit default constructor for 'DefaultedFnExceptionSpec::OdrUse' first required here}}
+}
+
+namespace PR13527 {
+  struct X {
+    X() = delete; // expected-note {{here}}
+    X(const X&) = delete; // expected-note {{here}}
+    X(X&&) = delete; // expected-note {{here}}
+    X &operator=(const X&) = delete; // expected-note {{here}}
+    X &operator=(X&&) = delete; // expected-note {{here}}
+    ~X() = delete; // expected-note {{here}}
+  };
+  X::X() = default; // expected-error {{redefinition}}
+  X::X(const X&) = default; // expected-error {{redefinition}}
+  X::X(X&&) = default; // expected-error {{redefinition}}
+  X &X::operator=(const X&) = default; // expected-error {{redefinition}}
+  X &X::operator=(X&&) = default; // expected-error {{redefinition}}
+  X::~X() = default; // expected-error {{redefinition}}
+
+  struct Y {
+    Y() = default;
+    Y(const Y&) = default;
+    Y(Y&&) = default;
+    Y &operator=(const Y&) = default;
+    Y &operator=(Y&&) = default;
+    ~Y() = default;
+  };
+  Y::Y() = default; // expected-error {{definition of explicitly defaulted}}
+  Y::Y(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
+  Y::Y(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+  Y &Y::operator=(const Y&) = default; // expected-error {{definition of explicitly defaulted}}
+  Y &Y::operator=(Y&&) = default; // expected-error {{definition of explicitly defaulted}}
+  Y::~Y() = default; // expected-error {{definition of explicitly defaulted}}
+}
diff --git a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 7384309..f11e19a 100644
--- a/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -175,3 +175,15 @@
   
   X x({}, 17);
 }
+
+namespace rdar11948732 {
+  template<typename T> struct X {};
+
+  struct XCtorInit {
+    XCtorInit(std::initializer_list<X<int>>);
+  };
+
+  void f(X<int> &xi) {
+    XCtorInit xc = { xi, xi };
+  }
+}
diff --git a/test/SemaCXX/cxx98-compat.cpp b/test/SemaCXX/cxx98-compat.cpp
index b9a8a1c..37341f8 100644
--- a/test/SemaCXX/cxx98-compat.cpp
+++ b/test/SemaCXX/cxx98-compat.cpp
@@ -335,3 +335,30 @@
   X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
   Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
 }
+
+namespace PR13480 {
+  struct basic_iterator {
+    basic_iterator(const basic_iterator &it) {}
+    basic_iterator(basic_iterator &it) {} // expected-note {{because type 'PR13480::basic_iterator' has a user-declared copy constructor}}
+  };
+
+  union test {
+    basic_iterator it; // expected-warning {{union member 'it' with a non-trivial copy constructor is incompatible with C++98}}
+  };
+}
+
+namespace AssignOpUnion {
+  struct a {
+    void operator=(const a &it) {}
+    void operator=(a &it) {} // expected-note {{because type 'AssignOpUnion::a' has a user-declared copy assignment operator}}
+  };
+
+  struct b {
+    void operator=(const b &it) {} // expected-note {{because type 'AssignOpUnion::b' has a user-declared copy assignment operator}}
+  };
+
+  union test1 {
+    a x; // expected-warning {{union member 'x' with a non-trivial copy assignment operator is incompatible with C++98}}
+    b y; // expected-warning {{union member 'y' with a non-trivial copy assignment operator is incompatible with C++98}}
+  };
+}
diff --git a/test/SemaCXX/dcl_ambig_res.cpp b/test/SemaCXX/dcl_ambig_res.cpp
index fa71b11..08867c0 100644
--- a/test/SemaCXX/dcl_ambig_res.cpp
+++ b/test/SemaCXX/dcl_ambig_res.cpp
@@ -10,9 +10,9 @@
 
 void foo(double a) 
 { 
-  S w(int(a)); // expected-warning{{disambiguated}}
+  S w(int(a)); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}} 
   w(17);
-  S x1(int()); // expected-warning{{disambiguated}}
+  S x1(int()); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}} 
   x1(&returns_an_int);
   S y((int)a); 
   y.bar();
@@ -69,7 +69,7 @@
   static bool const value = false;
 };
 int foo8() {
-  int v(int(S5::value)); // expected-warning{{disambiguated}} expected-error{{parameter declarator cannot be qualified}}
+  int v(int(S5::value)); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}} expected-error{{parameter declarator cannot be qualified}}
 }
 
 template<typename T>
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index ab1a2b5..0980c40 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -22,10 +22,10 @@
   (int())1; // expected-error {{C-style cast from 'int' to 'int ()' is not allowed}}
 
   // Declarations.
-  int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}}
-  T(*d)(int(p)); // expected-warning {{parentheses were disambiguated as a function declarator}} expected-note {{previous definition is here}}
-  typedef T(*td)(int(p));
-  extern T(*tp)(int(p));
+  int fd(T(a)); // expected-warning {{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}}
+  T(*d)(int(p)); // expected-note {{previous}}
+  typedef T td(int(p));
+  extern T tp(int(p));
   T d3(); // expected-warning {{empty parentheses interpreted as a function declaration}} expected-note {{replace parentheses with an initializer}}
   T d3v(void);
   typedef T d3t();
@@ -49,6 +49,7 @@
 };
 
 void func();
+void func2(short);
 namespace N {
   struct S;
 
@@ -59,6 +60,10 @@
 
     S s(); // expected-warning {{function declaration}}
   }
+  void nonEmptyParens() {
+    int f = 0, // g = 0; expected-note {{change this ',' to a ';' to call 'func2'}}
+    func2(short(f)); // expected-warning {{function declaration}} expected-note {{add a pair of parentheses}}
+  }
 }
 
 class C { };
diff --git a/test/SemaCXX/for-range-dereference.cpp b/test/SemaCXX/for-range-dereference.cpp
new file mode 100644
index 0000000..3bf50f3
--- /dev/null
+++ b/test/SemaCXX/for-range-dereference.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+struct Data { };
+struct T {
+  Data *begin();
+  Data *end();
+};
+
+struct NoBegin {
+  Data *end();
+};
+
+struct DeletedEnd : public T {
+  Data *begin();
+  Data *end() = delete; //expected-note {{function has been explicitly marked deleted here}}
+};
+
+struct DeletedADLBegin { };
+
+int* begin(DeletedADLBegin) = delete; //expected-note {{candidate function has been explicitly deleted}} \
+ expected-note 6 {{candidate function not viable: no known conversion}}
+
+struct PrivateEnd {
+  Data *begin();
+
+ private:
+  Data *end(); // expected-note 1 {{declared private here}}
+};
+
+struct ADLNoEnd { };
+Data * begin(ADLNoEnd); // expected-note 7 {{candidate function not viable: no known conversion}}
+
+struct OverloadedStar {
+  T operator*();
+};
+
+void f() {
+  T t;
+  for (auto i : t) { }
+  T *pt;
+  for (auto i : pt) { } // expected-error{{invalid range expression of type 'T *'; did you mean to dereference it with '*'?}}
+
+  int arr[10];
+  for (auto i : arr) { }
+  int (*parr)[10];
+  for (auto i : parr) { }// expected-error{{invalid range expression of type 'int (*)[10]'; did you mean to dereference it with '*'?}}
+
+  NoBegin NB;
+  for (auto i : NB) { }// expected-error{{range type 'NoBegin' has 'end' member but no 'begin' member}}
+  NoBegin *pNB;
+  for (auto i : pNB) { }// expected-error{{invalid range expression of type 'NoBegin *'; no viable 'begin' function available}}
+  NoBegin **ppNB;
+  for (auto i : ppNB) { }// expected-error{{invalid range expression of type 'NoBegin **'; no viable 'begin' function available}}
+  NoBegin *****pppppNB;
+  for (auto i : pppppNB) { }// expected-error{{invalid range expression of type 'NoBegin *****'; no viable 'begin' function available}}
+
+  ADLNoEnd ANE;
+  for (auto i : ANE) { } // expected-error{{invalid range expression of type 'ADLNoEnd'; no viable 'end' function available}}
+  ADLNoEnd *pANE;
+  for (auto i : pANE) { } // expected-error{{invalid range expression of type 'ADLNoEnd *'; no viable 'begin' function available}}
+
+  DeletedEnd DE;
+  for (auto i : DE) { } // expected-error{{attempt to use a deleted function}} \
+expected-note {{when looking up 'end' function for range expression of type 'DeletedEnd'}}
+  DeletedEnd *pDE;
+
+  for (auto i : pDE) { } // expected-error {{invalid range expression of type 'DeletedEnd *'; no viable 'begin' function available}}
+
+  PrivateEnd PE;
+  // FIXME: This diagnostic should be improved, as it does not specify that
+  // the range is invalid.
+  for (auto i : PE) { } // expected-error{{'end' is a private member of 'PrivateEnd'}}
+
+  // FIXME: This diagnostic should be improved as well. It should not mention a
+  // deleted function, and we should not issue a FixIt suggesting a dereference.
+  PrivateEnd *pPE;
+  for (auto i : pPE) { }// expected-error {{invalid range expression of type 'PrivateEnd *'}}
+
+  DeletedADLBegin DAB;
+  for (auto i : DAB) { } // expected-error {{call to deleted function 'begin'}}\
+  expected-note {{when looking up 'begin' function for range expression of type 'DeletedADLBegin'}}
+
+  OverloadedStar OS;
+  for (auto i : *OS) { }
+
+  for (auto i : OS) { } // expected-error {{invalid range expression of type 'OverloadedStar'; did you mean to dereference it with '*'?}}
+}
diff --git a/test/SemaCXX/for-range-no-std.cpp b/test/SemaCXX/for-range-no-std.cpp
index fa42ca4..66b445e 100644
--- a/test/SemaCXX/for-range-no-std.cpp
+++ b/test/SemaCXX/for-range-no-std.cpp
@@ -31,10 +31,10 @@
 void f() {
   int a[] = {1, 2, 3};
   for (auto b : S()) {} // ok
-  for (auto b : T()) {} // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}}
+  for (auto b : T()) {} // expected-error {{invalid range expression of type 'T'}}
   for (auto b : a) {} // ok
   for (int b : NS::ADL()) {} // ok
-  for (int b : NS::NoADL()) {} // expected-error {{no matching function for call to 'begin'}} expected-note {{range has type}}
+  for (int b : NS::NoADL()) {} // expected-error {{invalid range expression of type 'NS::NoADL'}}
 }
 
 void PR11601() {
diff --git a/test/SemaCXX/function-extern-c.cpp b/test/SemaCXX/function-extern-c.cpp
index f20cd38..16dbbb2 100644
--- a/test/SemaCXX/function-extern-c.cpp
+++ b/test/SemaCXX/function-extern-c.cpp
@@ -36,3 +36,5 @@
 extern "C" double f8(void);
 extern "C" long long f11( void );
 extern "C" A *f10( void );
+
+extern "C" struct mypodstruct f12(); // expected-warning {{'f12' has C-linkage specified, but returns incomplete type 'struct mypodstruct' which could be incompatible with C}}
diff --git a/test/SemaCXX/implicit-exception-spec.cpp b/test/SemaCXX/implicit-exception-spec.cpp
index 25316f8..b29cff5 100644
--- a/test/SemaCXX/implicit-exception-spec.cpp
+++ b/test/SemaCXX/implicit-exception-spec.cpp
@@ -17,7 +17,7 @@
   // is false.
   bool ThrowSomething() noexcept(false);
   struct ConstExpr {
-    bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{exception specification is not available until end of class definition}}
+    bool b = noexcept(ConstExpr()) && ThrowSomething(); // expected-error {{cannot be used by non-static data member initializer}}
   };
   // We can use it now.
   bool w = noexcept(ConstExpr());
@@ -25,18 +25,27 @@
   // Much more obviously broken: we can't parse the initializer without already
   // knowing whether it produces a noexcept expression.
   struct TemplateArg {
-    int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{exception specification is not available until end of class definition}}
+    int n = ExceptionIf<noexcept(TemplateArg())>::f(); // expected-error {{cannot be used by non-static data member initializer}}
   };
   bool x = noexcept(TemplateArg());
 
   // And within a nested class.
+  // FIXME: The diagnostic location is terrible here.
   struct Nested {
     struct Inner {
-      int n = ExceptionIf<noexcept(Nested())>::f(); // expected-error {{exception specification is not available until end of class definition}}
-    } inner;
+      int n = ExceptionIf<noexcept(Nested())>::f();
+    } inner; // expected-error {{cannot be used by non-static data member initializer}}
   };
   bool y = noexcept(Nested());
   bool z = noexcept(Nested::Inner());
+
+  struct Nested2 {
+    struct Inner;
+    int n = Inner().n; // expected-error {{cannot be used by non-static data member initializer}}
+    struct Inner {
+      int n = ExceptionIf<noexcept(Nested())>::f();
+    } inner;
+  };
 }
 
 namespace ExceptionSpecification {
diff --git a/test/SemaCXX/lambda-expressions.cpp b/test/SemaCXX/lambda-expressions.cpp
index f5eee6a..0fd6345 100644
--- a/test/SemaCXX/lambda-expressions.cpp
+++ b/test/SemaCXX/lambda-expressions.cpp
@@ -117,16 +117,16 @@
 
     const int m = 0;
     [=] {
-      int &k = f(m); // a null pointer constant
+      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
     } ();
 
     [=] () -> bool {
-      int &k = f(m); // a null pointer constant
+      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
       return &m == 0;
     } ();
 
     [m] {
-      int &k = f(m); // a null pointer constant
+      int &k = f(m); // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
     } ();
   }
 }
@@ -145,3 +145,79 @@
     };
   }
 }
+
+namespace VariadicPackExpansion {
+  template<typename T, typename U> using Fst = T;
+  template<typename...Ts> bool g(Fst<bool, Ts> ...bools);
+  template<typename...Ts> bool f(Ts &&...ts) {
+    return g<Ts...>([&ts] {
+      if (!ts)
+        return false;
+      --ts;
+      return true;
+    } () ...);
+  }
+  void h() {
+    int a = 5, b = 2, c = 3;
+    while (f(a, b, c)) {
+    }
+  }
+
+  struct sink {
+    template<typename...Ts> sink(Ts &&...) {}
+  };
+
+  template<typename...Ts> void local_class() {
+    sink {
+      [] (Ts t) {
+        struct S : Ts {
+          void f(Ts t) {
+            Ts &that = *this;
+            that = t;
+          }
+          Ts g() { return *this; };
+        };
+        S s;
+        s.f(t);
+        return s;
+      } (Ts()).g() ...
+    };
+  };
+  struct X {}; struct Y {};
+  template void local_class<X, Y>();
+
+  template<typename...Ts> void nested(Ts ...ts) {
+    f(
+      // Each expansion of this lambda implicitly captures all of 'ts', because
+      // the inner lambda also expands 'ts'.
+      [&] {
+        return ts + [&] { return f(ts...); } ();
+      } () ...
+    );
+  }
+  template void nested(int, int, int);
+
+  template<typename...Ts> void nested2(Ts ...ts) { // expected-note 2{{here}}
+    // Capture all 'ts', use only one.
+    f([&ts...] { return ts; } ()...);
+    // Capture each 'ts', use it.
+    f([&ts] { return ts; } ()...);
+    // Capture all 'ts', use all of them.
+    f([&ts...] { return (int)f(ts...); } ());
+    // Capture each 'ts', use all of them. Ill-formed. In more detail:
+    //
+    // We instantiate two lambdas here; the first captures ts$0, the second
+    // captures ts$1. Both of them reference both ts parameters, so both are
+    // ill-formed because ts can't be implicitly captured.
+    //
+    // FIXME: This diagnostic does not explain what's happening. We should
+    // specify which 'ts' we're referring to in its diagnostic name. We should
+    // also say which slice of the pack expansion is being performed in the
+    // instantiation backtrace.
+    f([&ts] { return (int)f(ts...); } ()...); // \
+    // expected-error 2{{'ts' cannot be implicitly captured}} \
+    // expected-note 2{{lambda expression begins here}}
+  }
+  template void nested2(int); // ok
+  template void nested2(int, int); // expected-note {{in instantiation of}}
+}
diff --git a/test/SemaCXX/literal-operators.cpp b/test/SemaCXX/literal-operators.cpp
index 7f68cd3..f4c5c35 100644
--- a/test/SemaCXX/literal-operators.cpp
+++ b/test/SemaCXX/literal-operators.cpp
@@ -41,3 +41,4 @@
 template <char...> void operator "" _good ();
 
 // FIXME: Test some invalid decls that might crop up.
+template <typename...> void operator "" _invalid(); // expected-error {{parameter declaration for literal operator 'operator "" _invalid' is not valid}}
diff --git a/test/SemaCXX/member-init.cpp b/test/SemaCXX/member-init.cpp
index 3ca41a0..a13941f 100644
--- a/test/SemaCXX/member-init.cpp
+++ b/test/SemaCXX/member-init.cpp
@@ -14,7 +14,7 @@
 bool b();
 int k;
 struct Recurse {
-  int &n = b() ? Recurse().n : k; // ok
+  int &n = b() ? Recurse().n : k; // expected-error {{defaulted default constructor of 'Recurse' cannot be used by non-static data member initializer which appears before end of class definition}}
 };
 
 struct UnknownBound {
diff --git a/test/SemaCXX/microsoft-cxx0x.cpp b/test/SemaCXX/microsoft-cxx0x.cpp
index 3b9bbef..79bd7c3 100644
--- a/test/SemaCXX/microsoft-cxx0x.cpp
+++ b/test/SemaCXX/microsoft-cxx0x.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wc++11-narrowing -Wmicrosoft -verify -fms-extensions -std=c++11
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wc++11-narrowing -Wmicrosoft -verify -fms-extensions -std=c++11 -fms-compatibility -DMS_COMPAT
 
 
 struct A {
@@ -6,3 +7,16 @@
 };
 int b = 3;
 A var = {  b }; // expected-warning {{ cannot be narrowed }} expected-note {{override}}
+
+
+namespace PR13433 {
+  struct S;
+  S make();
+
+  template<typename F> auto x(F f) -> decltype(f(make()));
+#ifndef MS_COMPAT
+// expected-error@-2{{calling 'make' with incomplete return type 'PR13433::S'}}
+// expected-note@-5{{'make' declared here}}
+// expected-note@-7{{forward declaration of 'PR13433::S'}}
+#endif
+}
diff --git a/test/SemaCXX/nested-name-spec.cpp b/test/SemaCXX/nested-name-spec.cpp
index 4e1abc5..b35e382 100644
--- a/test/SemaCXX/nested-name-spec.cpp
+++ b/test/SemaCXX/nested-name-spec.cpp
@@ -93,8 +93,7 @@
 }
 
 // make sure the following doesn't hit any asserts
-void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}} \
-                      expected-error {{variable has incomplete type 'void'}}
+void f4(undef::C); // expected-error {{use of undeclared identifier 'undef'}}
 
 typedef void C2::f5(int); // expected-error{{typedef declarator cannot be qualified}}
 
diff --git a/test/SemaCXX/nullptr.cpp b/test/SemaCXX/nullptr.cpp
index e313603..d148f76 100644
--- a/test/SemaCXX/nullptr.cpp
+++ b/test/SemaCXX/nullptr.cpp
@@ -33,8 +33,10 @@
   // Operators
   (void)(null == nullptr);
   (void)(null <= nullptr);
+  (void)(null == 0);
   (void)(null == (void*)0);
   (void)((void*)0 == nullptr);
+  (void)(null <= 0);
   (void)(null <= (void*)0);
   (void)((void*)0 <= nullptr);
   (void)(0 == nullptr);
@@ -44,7 +46,7 @@
   (void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
   (void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
   (void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
-  (void)(0 ? nullptr : 0); // expected-error {{non-pointer operand type 'int' incompatible with nullptr}}
+  (void)(0 ? nullptr : 0);
   (void)(0 ? nullptr : (void*)0);
   (void)(0 ? nullptr : A()); // expected-error {{non-pointer operand type 'A' incompatible with nullptr}}
   (void)(0 ? A() : nullptr); // expected-error {{non-pointer operand type 'A' incompatible with nullptr}}
diff --git a/test/SemaCXX/pr13394-crash-on-invalid.cpp b/test/SemaCXX/pr13394-crash-on-invalid.cpp
new file mode 100644
index 0000000..413c52a
--- /dev/null
+++ b/test/SemaCXX/pr13394-crash-on-invalid.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// Don't crash (PR13394).
+
+namespace stretch_v1 {
+  struct closure_t {
+    const stretch_v1::ops_t* d_methods; // expected-error {{no type named 'ops_t' in namespace 'stretch_v1'}}
+  };
+}
+namespace gatekeeper_v1 {
+  namespace gatekeeper_factory_v1 {
+    struct closure_t { // expected-note {{'closure_t' declared here}}
+      gatekeeper_v1::closure_t* create(); // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1'; did you mean 'closure_t'?}}
+    };
+  }
+  gatekeeper_v1::closure_t *x; // expected-error {{no type named 'closure_t' in namespace 'gatekeeper_v1}}
+}
diff --git a/test/SemaCXX/pragma-pack.cpp b/test/SemaCXX/pragma-pack.cpp
index 1bc738b..5c1d5c6 100644
--- a/test/SemaCXX/pragma-pack.cpp
+++ b/test/SemaCXX/pragma-pack.cpp
@@ -32,3 +32,26 @@
 int check[sizeof(Sub) == 13 ? 1 : -1];
 
 }
+
+namespace llvm_support_endian {
+
+template<typename, bool> struct X;
+
+#pragma pack(push)
+#pragma pack(1)
+template<typename T> struct X<T, true> {
+  T t;
+};
+#pragma pack(pop)
+
+#pragma pack(push)
+#pragma pack(2)
+template<> struct X<long double, true> {
+  long double c;
+};
+#pragma pack(pop)
+
+int check1[__alignof(X<int, true>) == 1 ? 1 : -1];
+int check2[__alignof(X<long double, true>) == 2 ? 1 : -1];
+
+}
diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp
index 70d3799..4f3dab0 100644
--- a/test/SemaCXX/references.cpp
+++ b/test/SemaCXX/references.cpp
@@ -136,4 +136,4 @@
 }
 
 // The following crashed trying to recursively evaluate the LValue.
-const int &do_not_crash = do_not_crash;
+const int &do_not_crash = do_not_crash; // expected-warning{{reference 'do_not_crash' is not yet bound to a value when used within its own initialization}}
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 63286e6..54294bc 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -1384,9 +1384,6 @@
   { int arr[F(__has_nothrow_copy(cvoid))]; }
 }
 
-template<bool b> struct assert_expr;
-template<> struct assert_expr<true> {};
-
 void has_nothrow_constructor() {
   { int arr[T(__has_nothrow_constructor(Int))]; }
   { int arr[T(__has_nothrow_constructor(IntAr))]; }
@@ -1415,11 +1412,6 @@
   { int arr[F(__has_nothrow_constructor(void))]; }
   { int arr[F(__has_nothrow_constructor(cvoid))]; }
   { int arr[F(__has_nothrow_constructor(HasTemplateCons))]; }
-
-  // While parsing an in-class initializer, the constructor is not known to be
-  // non-throwing yet.
-  struct HasInClassInit { int n = (assert_expr<!__has_nothrow_constructor(HasInClassInit)>(), 0); };
-  { int arr[T(__has_nothrow_constructor(HasInClassInit))]; }
 }
 
 void has_virtual_destructor() {
@@ -1582,6 +1574,8 @@
   template<typename U> X0(const X0<U>&);
 };
 
+struct Abstract { virtual void f() = 0; };
+
 void is_convertible_to() {
   { int arr[T(__is_convertible_to(Int, Int))]; }
   { int arr[F(__is_convertible_to(Int, IntAr))]; }
@@ -1606,6 +1600,7 @@
   { int arr[F(__is_convertible_to(Function, Function))]; }
   { int arr[F(__is_convertible_to(PrivateCopy, PrivateCopy))]; }
   { int arr[T(__is_convertible_to(X0<int>, X0<float>))]; }
+  { int arr[F(__is_convertible_to(Abstract, Abstract))]; }
 }
 
 namespace is_convertible_to_instantiate {
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 893f08a..c21ef51 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -116,14 +116,14 @@
 
 // Test the improved typo correction for the Parser::ParseCastExpr =>
 // Sema::ActOnIdExpression => Sema::DiagnoseEmptyLookup call path.
-class SomeNetMessage;
+class SomeNetMessage; // expected-note 2{{'SomeNetMessage'}}
 class Message {};
 void foo(Message&);
 void foo(SomeNetMessage&);
 void doit(void *data) {
   Message somenetmsg; // expected-note{{'somenetmsg' declared here}}
   foo(somenetmessage); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'somenetmsg'?}}
-  foo((somenetmessage)data); // expected-error{{use of undeclared identifier 'somenetmessage'; did you mean 'SomeNetMessage'?}}
+  foo((somenetmessage)data); // expected-error{{unknown type name 'somenetmessage'; did you mean 'SomeNetMessage'?}} expected-error{{incomplete type}}
 }
 
 // Test the typo-correction callback in BuildRecoveryCallExpr.
@@ -155,7 +155,7 @@
 struct R {};
 bool begun(R);
 void RangeTest() {
-  for (auto b : R()) {} // expected-error {{use of undeclared identifier 'begin'}} expected-note {{range has type}}
+  for (auto b : R()) {} // expected-error {{invalid range expression of type 'R'}}
 }
 
 // PR 12019 - Avoid infinite mutual recursion in DiagnoseInvalidRedeclaration
@@ -172,7 +172,7 @@
 // Sema::ActOnIdExpression by Parser::ParseCastExpression to allow type names as
 // potential corrections for template arguments.
 namespace clash {
-class ConstructExpr {}; // expected-note{{'clash::ConstructExpr' declared here}}
+class ConstructExpr {}; // expected-note 2{{'clash::ConstructExpr' declared here}}
 }
 class ClashTool {
   bool HaveConstructExpr();
@@ -180,7 +180,7 @@
 
   void test() {
     ConstructExpr *expr = // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
-        getExprAs<ConstructExpr>(); // expected-error{{use of undeclared identifier 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
+        getExprAs<ConstructExpr>(); // expected-error{{unknown type name 'ConstructExpr'; did you mean 'clash::ConstructExpr'?}}
   }
 };
 
@@ -220,6 +220,8 @@
   }
 }
 
+inf f(doulbe); // expected-error{{'int'}} expected-error{{'double'}}
+
 namespace PR6325 {
 class foo { }; // expected-note{{'foo' declared here}}
 // Note that for this example (pulled from the PR), if keywords are not excluded
diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp
index e827236..0633764 100644
--- a/test/SemaCXX/uninitialized.cpp
+++ b/test/SemaCXX/uninitialized.cpp
@@ -116,6 +116,29 @@
   A a19 = getA(x ? a19 : a17);  // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
 }
 
+bool x;
+
+A a1;
+A a2(a1.get());
+A a3(a1);
+A a4(&a4);
+A a5(a5.zero());
+A a6(a6.ONE);
+A a7 = getA();
+A a8 = getA(a8.TWO);
+A a9 = getA(&a9);
+A a10(a10.count);
+
+A a11(a11);  // expected-warning {{variable 'a11' is uninitialized when used within its own initialization}}
+A a12(a12.get());  // expected-warning {{variable 'a12' is uninitialized when used within its own initialization}}
+A a13(a13.num);  // expected-warning {{variable 'a13' is uninitialized when used within its own initialization}}
+A a14 = A(a14);  // expected-warning {{variable 'a14' is uninitialized when used within its own initialization}}
+A a15 = getA(a15.num);  // expected-warning {{variable 'a15' is uninitialized when used within its own initialization}}
+A a16(&a16.num);  // expected-warning {{variable 'a16' is uninitialized when used within its own initialization}}
+A a17(a17.get2());  // expected-warning {{variable 'a17' is uninitialized when used within its own initialization}}
+A a18 = x ? a18 : a17;  // expected-warning {{variable 'a18' is uninitialized when used within its own initialization}}
+A a19 = getA(x ? a19 : a17);  // expected-warning {{variable 'a19' is uninitialized when used within its own initialization}}
+
 struct B {
   // POD struct.
   int x;
@@ -293,3 +316,84 @@
     G(char (*)[8]) : f3(new F(f3->*ptr)) {} // expected-warning {{field is uninitialized when used here}}
   };
 }
+
+namespace statics {
+  static int a = a; // no-warning: used to signal intended lack of initialization.
+  static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+  static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
+  static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+  static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+  // Thes don't warn as they don't require the value.
+  static int g = sizeof(g);
+  int gg = g;  // Silence unneeded warning
+  static void* ptr = &ptr;
+  static int h = bar(&h);
+  static int i = boo(i);
+  static int j = far(j);
+  static int k = __alignof__(k);
+
+  static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+  static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+  static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+
+  void test() {
+    static int a = a; // no-warning: used to signal intended lack of initialization.
+    static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+    static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
+    static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
+    static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+    static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+    // Thes don't warn as they don't require the value.
+    static int g = sizeof(g);
+    static void* ptr = &ptr;
+    static int h = bar(&h);
+    static int i = boo(i);
+    static int j = far(j);
+    static int k = __alignof__(k);
+
+    static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+    static int m = 1 + (k ? m : m);  // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+    static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+   for (;;) {
+      static int a = a; // no-warning: used to signal intended lack of initialization.
+      static int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
+      static int c = (c + c); // expected-warning 2{{variable 'c' is uninitialized when used within its own initialization}}
+      static int d = ({ d + d ;}); // expected-warning 2{{variable 'd' is uninitialized when used within its own initialization}}
+      static int e = static_cast<long>(e) + 1; // expected-warning {{variable 'e' is uninitialized when used within its own initialization}}
+      static int f = foo(f); // expected-warning {{variable 'f' is uninitialized when used within its own initialization}}
+
+      // Thes don't warn as they don't require the value.
+      static int g = sizeof(g);
+      static void* ptr = &ptr;
+      static int h = bar(&h);
+      static int i = boo(i);
+      static int j = far(j);
+      static int k = __alignof__(k);
+
+      static int l = k ? l : l;  // expected-warning 2{{variable 'l' is uninitialized when used within its own initialization}}
+      static int m = 1 + (k ? m : m); // expected-warning 2{{variable 'm' is uninitialized when used within its own initialization}}
+      static int n = -n;  // expected-warning {{variable 'n' is uninitialized when used within its own initialization}}
+    }
+  }
+}
+
+namespace references {
+  int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
+
+  struct S {
+    S() : a(a) {} // expected-warning{{reference is not yet bound to a value when used here}}
+    int &a;
+  };
+
+  void f() {
+    int &a = a; // expected-warning{{reference 'a' is not yet bound to a value when used within its own initialization}}
+  }
+
+  struct T {
+    T() : a(b), b(a) {} // FIXME: Warn here.
+    int &a, &b;
+    int &c = c; // FIXME: Warn here.
+  };
+}
diff --git a/test/SemaCXX/unknown-type-name.cpp b/test/SemaCXX/unknown-type-name.cpp
index 893e0cc..ce5972b 100644
--- a/test/SemaCXX/unknown-type-name.cpp
+++ b/test/SemaCXX/unknown-type-name.cpp
@@ -6,6 +6,8 @@
   };
 
   typedef Wibble foo;
+
+  int zeppelin; // expected-note{{declared here}}
 }
 using namespace N;
 
@@ -15,6 +17,13 @@
   foo::bar  = 4; // expected-error{{no member named 'bar' in 'N::Wibble'}}
 }
 
+int f(foo::bar); // expected-error{{no type named 'bar' in 'N::Wibble'}}
+
+int f(doulbe); // expected-error{{did you mean 'double'?}}
+
+int fun(zapotron); // expected-error{{unknown type name 'zapotron'}}
+int var(zepelin); // expected-error{{did you mean 'zeppelin'?}}
+
 template<typename T>
 struct A {
   typedef T type;
@@ -59,6 +68,20 @@
 template<typename T>
 void f(int, T::type x, char) { } // expected-error{{missing 'typename'}}
 
+int *p;
+
+// FIXME: We should assume that 'undeclared' is a type, not a parameter name
+//        here, and produce an 'unknown type name' diagnostic instead.
+int f1(undeclared, int); // expected-error{{requires a type specifier}}
+
+int f2(undeclared, 0); // expected-error{{undeclared identifier}}
+
+int f3(undeclared *p, int); // expected-error{{unknown type name 'undeclared'}}
+
+int f4(undeclared *p, 0); // expected-error{{undeclared identifier}}
+
+int *test(UnknownType *fool) { return 0; } // expected-error{{unknown type name 'UnknownType'}}
+
 template<typename T> int A<T>::n(T::value); // ok
 template<typename T>
 A<T>::type // expected-error{{missing 'typename'}}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index 9523d43..17a1931 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -529,7 +529,7 @@
   LateFoo fooB;
   fooA.mu.Lock();
   fooB.a = 5; // \
-    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+    // expected-warning{{writing variable 'a' requires locking 'fooB.mu' exclusively}}
   fooA.mu.Unlock();
 }
 
@@ -539,7 +539,7 @@
   b1.mu1_.Lock();
   int res = b1.a_ + b3->b_;
   b3->b_ = *b1.q; // \
-    // expected-warning{{reading the value pointed to by 'q' requires locking 'mu'}}
+    // expected-warning{{reading the value pointed to by 'q' requires locking 'b1.mu'}}
   b1.mu1_.Unlock();
   b1.b_ = res;
   mu.Unlock();
@@ -549,7 +549,7 @@
   LateBar BarA;
   BarA.FooPointer->mu.Lock();
   BarA.Foo.a = 2; // \
-    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo.mu' exclusively}}
   BarA.FooPointer->mu.Unlock();
 }
 
@@ -557,7 +557,7 @@
   LateBar BarA;
   BarA.Foo.mu.Lock();
   BarA.FooPointer->a = 2; // \
-    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+    // expected-warning{{writing variable 'a' requires locking 'BarA.FooPointer->mu' exclusively}}
   BarA.Foo.mu.Unlock();
 }
 
@@ -565,7 +565,7 @@
   LateBar BarA;
   BarA.Foo.mu.Lock();
   BarA.Foo2.a = 2; // \
-    // expected-warning{{writing variable 'a' requires locking 'mu' exclusively}}
+    // expected-warning{{writing variable 'a' requires locking 'BarA.Foo2.mu' exclusively}}
   BarA.Foo.mu.Unlock();
 }
 
@@ -1199,13 +1199,13 @@
 {
   Foo f1, *f2;
   f1.mu_.Lock();
-  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
+  f1.bar(); // expected-warning {{cannot call function 'bar' while mutex 'f1.mu_' is locked}}
   mu2.Lock();
   f1.foo();
   mu2.Unlock();
   f1.mu_.Unlock();
   f2->mu_.Lock();
-  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'mu_' is locked}}
+  f2->bar(); // expected-warning {{cannot call function 'bar' while mutex 'f2->mu_' is locked}}
   f2->mu_.Unlock();
   mu2.Lock();
   w = 2;
@@ -1233,7 +1233,7 @@
 {
   b1->MyLock();
   b1->a_ = 5;
-  b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
+  b2->a_ = 3; // expected-warning {{writing variable 'a_' requires locking 'b2->mu1_' exclusively}}
   b2->MyLock();
   b2->MyUnlock();
   b1->MyUnlock();
@@ -1262,12 +1262,12 @@
 {
   int x;
   b3->mu1_.Lock();
-  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'mu1_'}} \
+  res = b1.a_ + b3->b_; // expected-warning {{reading variable 'a_' requires locking 'b1.mu1_'}} \
     // expected-warning {{writing variable 'res' requires locking 'mu' exclusively}}
   *p = i; // expected-warning {{reading variable 'p' requires locking 'mu'}} \
     // expected-warning {{writing the value pointed to by 'p' requires locking 'mu' exclusively}}
   b1.a_ = res + b3->b_; // expected-warning {{reading variable 'res' requires locking 'mu'}} \
-    // expected-warning {{writing variable 'a_' requires locking 'mu1_' exclusively}}
+    // expected-warning {{writing variable 'a_' requires locking 'b1.mu1_' exclusively}}
   b3->b_ = *b1.q; // expected-warning {{reading the value pointed to by 'q' requires locking 'mu'}}
   b3->mu1_.Unlock();
   b1.b_ = res; // expected-warning {{reading variable 'res' requires locking 'mu'}}
@@ -1292,8 +1292,8 @@
 
      child->Func(new_foo); // There shouldn't be any warning here as the
                            // acquired lock is not in child.
-     child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'lock_'}}
-     child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'lock_' exclusively}}
+     child->bar(7); // expected-warning {{calling function 'bar' requires exclusive lock on 'child->lock_'}}
+     child->a_ = 5; // expected-warning {{writing variable 'a_' requires locking 'child->lock_' exclusively}}
      lock_.Unlock();
   }
 
@@ -1330,7 +1330,7 @@
   lock_.Lock();
 
   child->lock_.Lock();
-  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'lock_' is locked}}
+  child->Func(new_foo); // expected-warning {{cannot call function 'Func' while mutex 'child->lock_' is locked}}
   child->bar(7);
   child->a_ = 5;
   child->lock_.Unlock();
@@ -1378,8 +1378,8 @@
 
 void func()
 {
-  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'mu2'}} \
-    // expected-warning {{calling function 'f1' requires exclusive lock on 'mu1'}}
+  foo->f1(); // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu2'}} \
+             // expected-warning {{calling function 'f1' requires exclusive lock on 'foo->mu1'}}
 }
 } // end namespace thread_annot_lock_42
 
@@ -1402,14 +1402,14 @@
   Child *c;
   Base *b = c;
 
-  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
+  b->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'b->mu_'}}
   b->mu_.Lock();
-  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
+  b->func2(); // expected-warning {{cannot call function 'func2' while mutex 'b->mu_' is locked}}
   b->mu_.Unlock();
 
-  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'mu_'}}
+  c->func1(); // expected-warning {{calling function 'func1' requires exclusive lock on 'c->mu_'}}
   c->mu_.Lock();
-  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'mu_' is locked}}
+  c->func2(); // expected-warning {{cannot call function 'func2' while mutex 'c->mu_' is locked}}
   c->mu_.Unlock();
 }
 } // end namespace thread_annot_lock_46
@@ -1436,9 +1436,9 @@
 void main()
 {
   Foo a;
-  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'mu1'}} \
+  a.method1(1); // expected-warning {{calling function 'method1' requires shared lock on 'a.mu1'}} \
     // expected-warning {{calling function 'method1' requires shared lock on 'mu'}} \
-    // expected-warning {{calling function 'method1' requires shared lock on 'mu2'}} \
+    // expected-warning {{calling function 'method1' requires shared lock on 'a.mu2'}} \
     // expected-warning {{calling function 'method1' requires shared lock on 'mu3'}}
 }
 } // end namespace thread_annot_lock_67_modified
@@ -1484,14 +1484,14 @@
       DataLocker dlr;
       dlr.lockData(d1);   // expected-note {{mutex acquired here}}
       dlr.unlockData(d2); // \
-        // expected-warning {{unlocking 'mu' that was not locked}}
-    } // expected-warning {{mutex 'mu' is still locked at the end of function}}
+        // expected-warning {{unlocking 'd2->mu' that was not locked}}
+    } // expected-warning {{mutex 'd1->mu' is still locked at the end of function}}
 
     void bar4(MyData* d1, MyData* d2) {
       DataLocker dlr;
       dlr.lockData(d1);
       foo(d2); // \
-        // expected-warning {{calling function 'foo' requires exclusive lock on 'mu'}}
+        // expected-warning {{calling function 'foo' requires exclusive lock on 'd2->mu'}}
       dlr.unlockData(d1);
     }
   };
@@ -1550,7 +1550,7 @@
   struct IndirectLock {
     int DoNaughtyThings(T *t) {
       u->n = 0; // expected-warning {{reading variable 'u' requires locking 'm'}}
-      return t->s->n; // expected-warning {{reading variable 's' requires locking 'm'}}
+      return t->s->n; // expected-warning {{reading variable 's' requires locking 't->m'}}
     }
   };
 
@@ -1566,7 +1566,7 @@
   template<typename U> struct W {
     V v;
     void f(U u) {
-      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'm'}}
+      v.p->f(u); // expected-warning {{reading variable 'p' requires locking 'v.m'}}
     }
   };
   template struct W<int>; // expected-note {{here}}
@@ -1629,7 +1629,7 @@
 void foo() EXCLUSIVE_LOCKS_REQUIRED(fooObj.mu_);
 
 void bar() {
-  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
+  foo();  // expected-warning {{calling function 'foo' requires exclusive lock on 'fooObj.mu_'}}
   fooObj.mu_.Lock();
   foo();
   fooObj.mu_.Unlock();
@@ -1702,7 +1702,7 @@
     bool b2 = b;
     if (cond)
       b = true;
-    if (b) {    // b should be unknown at this point, becuase of the join point
+    if (b) {    // b should be unknown at this point, because of the join point
       a = 8;    // expected-warning {{writing variable 'a' requires locking 'mu' exclusively}}
     }
     if (b2) {   // b2 should be known at this point.
@@ -1829,7 +1829,7 @@
 
   f1.mu_.Unlock();
   bt.barTD(&f1);  // \
-    // expected-warning {{calling function 'barTD' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'barTD' requires exclusive lock on 'f1.mu_'}}
 
   bt.fooBase.mu_.Unlock();
   bt.fooBaseT.mu_.Unlock();
@@ -1837,7 +1837,7 @@
 
   Cell<int> cell;
   cell.data = 0; // \
-    // expected-warning {{writing variable 'data' requires locking 'mu_' exclusively}}
+    // expected-warning {{writing variable 'data' requires locking 'cell.mu_' exclusively}}
   cell.foo();
   cell.mu_.Lock();
   cell.fooEx();
@@ -1906,7 +1906,7 @@
 void test() {
   Foo myfoo;
   myfoo.foo1(&myfoo);  // \
-    // expected-warning {{calling function 'foo1' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'foo1' requires exclusive lock on 'myfoo.mu_'}}
   myfoo.mu_.Lock();
   myfoo.foo1(&myfoo);
   myfoo.mu_.Unlock();
@@ -2021,29 +2021,28 @@
   Foo myFoo;
 
   myFoo.foo2();        // \
-    // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'foo2' requires exclusive lock on 'myFoo.mu_'}}
   myFoo.foo3(&myFoo);  // \
-    // expected-warning {{calling function 'foo3' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'foo3' requires exclusive lock on 'myFoo.mu_'}}
   myFoo.fooT1(dummy);  // \
-    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'fooT1' requires exclusive lock on 'myFoo.mu_'}}
 
-  // FIXME: uncomment with template instantiation of attributes patch
-  // myFoo.fooT2(dummy);  // expected warning
+  myFoo.fooT2(dummy);  // \
+    // expected-warning {{calling function 'fooT2' requires exclusive lock on 'myFoo.mu_'}}
 
   fooF1(&myFoo);  // \
-    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'fooF1' requires exclusive lock on 'myFoo.mu_'}}
   fooF2(&myFoo);  // \
-    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'fooF2' requires exclusive lock on 'myFoo.mu_'}}
   fooF3(&myFoo);  // \
-    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'fooF3' requires exclusive lock on 'myFoo.mu_'}}
 
   myFoo.mu_.Lock();
   myFoo.foo2();
   myFoo.foo3(&myFoo);
   myFoo.fooT1(dummy);
 
-  // FIXME: uncomment with template instantiation of attributes patch
-  // myFoo.fooT2(dummy);
+  myFoo.fooT2(dummy);
 
   fooF1(&myFoo);
   fooF2(&myFoo);
@@ -2052,7 +2051,7 @@
 
   FooT<int> myFooT;
   myFooT.foo();  // \
-    // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
+    // expected-warning {{calling function 'foo' requires exclusive lock on 'myFooT.mu_'}}
 }
 
 } // end namespace FunctionDefinitionTest
@@ -2236,27 +2235,27 @@
 
   bar.getFoo().mu_.Lock();
   bar.getFooey().a = 0; // \
-    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    // expected-warning {{writing variable 'a' requires locking 'bar.getFooey().mu_' exclusively}}
   bar.getFoo().mu_.Unlock();
 
   bar.getFoo2(a).mu_.Lock();
   bar.getFoo2(b).a = 0; // \
-    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo2(b).mu_' exclusively}}
   bar.getFoo2(a).mu_.Unlock();
 
   bar.getFoo3(a, b).mu_.Lock();
   bar.getFoo3(a, c).a = 0;  // \
-    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    // expected-warning {{writing variable 'a' requires locking 'bar.getFoo3(a,c).mu_' exclusively}}
   bar.getFoo3(a, b).mu_.Unlock();
 
   getBarFoo(bar, a).mu_.Lock();
   getBarFoo(bar, b).a = 0;  // \
-    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    // expected-warning {{writing variable 'a' requires locking 'getBarFoo(bar,b).mu_' exclusively}}
   getBarFoo(bar, a).mu_.Unlock();
 
   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
   (a > 0 ? fooArray[b] : fooArray[c]).a = 0; // \
-    // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
+    // expected-warning {{writing variable 'a' requires locking '((a#_)#_#fooArray[b]).mu_' exclusively}}
   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
 }
 
@@ -2304,17 +2303,18 @@
 
 // Calls getMu() directly to lock and unlock
 void test1(Foo* f1, Foo* f2) {
-  f1->a = 0;       // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
-  f1->foo();       // expected-warning {{calling function 'foo' requires exclusive lock on 'mu_'}}
+  f1->a = 0;       // expected-warning {{writing variable 'a' requires locking 'f1->mu_' exclusively}}
+  f1->foo();       // expected-warning {{calling function 'foo' requires exclusive lock on 'f1->mu_'}}
 
-  f1->foo2(f2);    // expected-warning 2{{calling function 'foo2' requires exclusive lock on 'mu_'}}
-  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires exclusive lock on 'mu_'}}
+  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f1->mu_'}} \
+                   // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
+  Foo::sfoo(f1);   // expected-warning {{calling function 'sfoo' requires exclusive lock on 'f1->mu_'}}
 
   f1->getMu()->Lock();
 
   f1->a = 0;
   f1->foo();
-  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'mu_'}}
+  f1->foo2(f2);    // expected-warning {{calling function 'foo2' requires exclusive lock on 'f2->mu_'}}
 
   Foo::getMu(f2)->Lock();
   f1->foo2(f2);
@@ -2343,17 +2343,18 @@
 // Use getMu() within other attributes.
 // This requires at lest levels of substitution, more in the case of
 void test2(Bar* b1, Bar* b2) {
-  b1->b = 0;       // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
-  b1->bar();       // expected-warning {{calling function 'bar' requires exclusive lock on 'mu_'}}
-  b1->bar2(b2);    // expected-warning 2{{calling function 'bar2' requires exclusive lock on 'mu_'}}
-  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires exclusive lock on 'mu_'}}
-  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires exclusive lock on 'mu_'}}
+  b1->b = 0;       // expected-warning {{writing variable 'b' requires locking 'b1->mu_' exclusively}}
+  b1->bar();       // expected-warning {{calling function 'bar' requires exclusive lock on 'b1->mu_'}}
+  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b1->mu_'}} \
+                   // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
+  Bar::sbar(b1);   // expected-warning {{calling function 'sbar' requires exclusive lock on 'b1->mu_'}}
+  Bar::sbar2(b1);  // expected-warning {{calling function 'sbar2' requires exclusive lock on 'b1->mu_'}}
 
   b1->getMu()->Lock();
 
   b1->b = 0;
   b1->bar();
-  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'mu_'}}
+  b1->bar2(b2);    // expected-warning {{calling function 'bar2' requires exclusive lock on 'b2->mu_'}}
 
   b2->getMu()->Lock();
   b1->bar2(b2);
@@ -2597,7 +2598,7 @@
     ReaderMutexLock lock(getMutexPtr().get());
     int b = a;
   }
-  int b = a;  // expected-warning {{reading variable 'a' requires locking 'getMutexPtr'}}
+  int b = a;  // expected-warning {{reading variable 'a' requires locking 'getMutexPtr()'}}
 }
 
 } // end namespace TemporaryCleanupExpr
@@ -2732,9 +2733,9 @@
 
 
 void Bar::test0() {
-  foo->a = 0;         // expected-warning {{writing variable 'a' requires locking 'mu_' exclusively}}
-  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires locking 'mu_' exclusively}}
-  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires locking 'mu_' exclusively}}
+  foo->a = 0;         // expected-warning {{writing variable 'a' requires locking 'foo->mu_' exclusively}}
+  (*foo).b = 0;       // expected-warning {{writing variable 'b' requires locking 'foo->mu_' exclusively}}
+  foo.get()->c = 0;   // expected-warning {{writing variable 'c' requires locking 'foo->mu_' exclusively}}
 }
 
 
@@ -2861,10 +2862,10 @@
   foo.unlock1();
 
   foo.lock1();
-  foo.lock1();    // expected-warning {{locking 'mu1_' that is already locked}}
+  foo.lock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
   foo.a = 0;
   foo.unlock1();
-  foo.unlock1();  // expected-warning {{unlocking 'mu1_' that was not locked}}
+  foo.unlock1();  // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
 }
 
 
@@ -2875,10 +2876,10 @@
   foo.unlock1();
 
   foo.slock1();
-  foo.slock1();    // expected-warning {{locking 'mu1_' that is already locked}}
+  foo.slock1();    // expected-warning {{locking 'foo.mu1_' that is already locked}}
   int d2 = foo.a;
   foo.unlock1();
-  foo.unlock1();   // expected-warning {{unlocking 'mu1_' that was not locked}}
+  foo.unlock1();   // expected-warning {{unlocking 'foo.mu1_' that was not locked}}
   return d1 + d2;
 }
 
@@ -2893,17 +2894,17 @@
 
   foo.lock3();
   foo.lock3(); // \
-    // expected-warning {{locking 'mu1_' that is already locked}} \
-    // expected-warning {{locking 'mu2_' that is already locked}} \
-    // expected-warning {{locking 'mu3_' that is already locked}}
+    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
+    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
+    // expected-warning {{locking 'foo.mu3_' that is already locked}}
   foo.a = 0;
   foo.b = 0;
   foo.c = 0;
   foo.unlock3();
   foo.unlock3(); // \
-    // expected-warning {{unlocking 'mu1_' that was not locked}} \
-    // expected-warning {{unlocking 'mu2_' that was not locked}} \
-    // expected-warning {{unlocking 'mu3_' that was not locked}}
+    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
+    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
+    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
 }
 
 
@@ -2917,17 +2918,17 @@
 
   foo.locklots();
   foo.locklots(); // \
-    // expected-warning {{locking 'mu1_' that is already locked}} \
-    // expected-warning {{locking 'mu2_' that is already locked}} \
-    // expected-warning {{locking 'mu3_' that is already locked}}
+    // expected-warning {{locking 'foo.mu1_' that is already locked}} \
+    // expected-warning {{locking 'foo.mu2_' that is already locked}} \
+    // expected-warning {{locking 'foo.mu3_' that is already locked}}
   foo.a = 0;
   foo.b = 0;
   foo.c = 0;
   foo.unlocklots();
   foo.unlocklots(); // \
-    // expected-warning {{unlocking 'mu1_' that was not locked}} \
-    // expected-warning {{unlocking 'mu2_' that was not locked}} \
-    // expected-warning {{unlocking 'mu3_' that was not locked}}
+    // expected-warning {{unlocking 'foo.mu1_' that was not locked}} \
+    // expected-warning {{unlocking 'foo.mu2_' that was not locked}} \
+    // expected-warning {{unlocking 'foo.mu3_' that was not locked}}
 }
 
 }  // end namespace DuplicateAttributeTest
@@ -3055,7 +3056,66 @@
 */
 }
 
-
 } // end namespace TryLockEqTest
 
 
+namespace ExistentialPatternMatching {
+
+class Graph {
+public:
+  Mutex mu_;
+};
+
+void LockAllGraphs()   EXCLUSIVE_LOCK_FUNCTION(&Graph::mu_);
+void UnlockAllGraphs() UNLOCK_FUNCTION(&Graph::mu_);
+
+class Node {
+public:
+  int a GUARDED_BY(&Graph::mu_);
+
+  void foo()  EXCLUSIVE_LOCKS_REQUIRED(&Graph::mu_) {
+    a = 0;
+  }
+  void foo2() LOCKS_EXCLUDED(&Graph::mu_);
+};
+
+void test() {
+  Graph g1;
+  Graph g2;
+  Node n1;
+
+  n1.a = 0;   // expected-warning {{writing variable 'a' requires locking '&ExistentialPatternMatching::Graph::mu_' exclusively}}
+  n1.foo();   // expected-warning {{calling function 'foo' requires exclusive lock on '&ExistentialPatternMatching::Graph::mu_'}}
+  n1.foo2();
+
+  g1.mu_.Lock();
+  n1.a = 0;
+  n1.foo();
+  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+  g1.mu_.Unlock();
+
+  g2.mu_.Lock();
+  n1.a = 0;
+  n1.foo();
+  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+  g2.mu_.Unlock();
+
+  LockAllGraphs();
+  n1.a = 0;
+  n1.foo();
+  n1.foo2();  // expected-warning {{cannot call function 'foo2' while mutex '&ExistentialPatternMatching::Graph::mu_' is locked}}
+  UnlockAllGraphs();
+
+  LockAllGraphs();
+  g1.mu_.Unlock();
+
+  LockAllGraphs();
+  g2.mu_.Unlock();
+
+  LockAllGraphs();
+  g1.mu_.Lock();  // expected-warning {{locking 'g1.mu_' that is already locked}}
+  g1.mu_.Unlock();
+}
+
+} // end namespace ExistentialPatternMatching
+
diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp
index 3f8a735..92c4b10 100644
--- a/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/test/SemaCXX/warn-thread-safety-parsing.cpp
@@ -1255,7 +1255,7 @@
   void foo4(FooLate *f) EXCLUSIVE_LOCKS_REQUIRED(f->mu);
 
   static void foo5()    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
-    // expected-error {{'this' cannot be implicitly used in a static member function declaration}}
+    // expected-error {{invalid use of member 'mu' in static member function}}
 
   template <class T>
   void foo6() EXCLUSIVE_LOCKS_REQUIRED(T::statmu) { }
@@ -1429,4 +1429,39 @@
 }
 
 
+namespace InvalidDeclTest {
+
+class Foo { };
+namespace {
+void Foo::bar(Mutex* mu) LOCKS_EXCLUDED(mu) { } // \
+   // expected-error   {{cannot define or redeclare 'bar' here because namespace '' does not enclose namespace 'Foo'}} \
+   // expected-warning {{attribute locks_excluded ignored, because it is not attached to a declaration}}
+}
+
+} // end namespace InvalidDeclTest
+
+
+namespace StaticScopeTest {
+
+class FooStream;
+
+class Foo {
+  mutable Mutex mu;
+  int a GUARDED_BY(mu);
+
+  static int si GUARDED_BY(mu); // \
+    // expected-error {{invalid use of non-static data member 'mu'}}
+
+  static void foo() EXCLUSIVE_LOCKS_REQUIRED(mu); // \
+    // expected-error {{invalid use of member 'mu' in static member function}}
+
+  friend FooStream& operator<<(FooStream& s, const Foo& f)
+    EXCLUSIVE_LOCKS_REQUIRED(mu); // \
+    // expected-error {{invalid use of non-static data member 'mu'}}
+};
+
+
+} // end namespace StaticScopeTest
+
+
 
diff --git a/test/SemaCXX/warn-unused-private-field.cpp b/test/SemaCXX/warn-unused-private-field.cpp
index 640a9b9..661442d 100644
--- a/test/SemaCXX/warn-unused-private-field.cpp
+++ b/test/SemaCXX/warn-unused-private-field.cpp
@@ -107,7 +107,7 @@
   int used_, unused_; // expected-warning{{private field 'unused_' is not used}}
   int in_class_initializer_ = 42; // expected-warning{{private field 'in_class_initializer_' is not used}}
   int in_class_initializer_with_side_effect_ = side_effect();
-  Trivial trivial_initializer_ = Trivial();
+  Trivial trivial_initializer_ = Trivial(); // expected-warning{{private field 'trivial_initializer_' is not used}}
   Trivial non_trivial_initializer_ = Trivial(42);
   int initialized_with_side_effect_;
   static int static_fields_are_ignored_;
@@ -219,3 +219,28 @@
   void* p2_;  // expected-warning{{private field 'p2_' is not used}}
 };
 }
+
+namespace pr13543 {
+  void f(int);
+  void f(char);
+  struct S {
+    S() : p(&f) {}
+  private:
+    void (*p)(int); // expected-warning{{private field 'p' is not used}}
+  };
+
+  struct A { int n; };
+  struct B {
+    B() : a(A()) {}
+    B(char) {}
+    B(int n) : a{n}, b{(f(n), 0)} {}
+  private:
+    A a = A(); // expected-warning{{private field 'a' is not used}}
+    A b;
+  };
+
+  struct X { ~X(); };
+  class C {
+    X x[4]; // no-warning
+  };
+}
diff --git a/test/SemaObjC/arc-bridged-cast.m b/test/SemaObjC/arc-bridged-cast.m
index c8f4d0d..b5ec36a 100644
--- a/test/SemaObjC/arc-bridged-cast.m
+++ b/test/SemaObjC/arc-bridged-cast.m
@@ -38,30 +38,27 @@
 
 CFTypeRef fixits() {
   id obj1 = (id)CFCreateSomething(); // expected-error{{cast of C pointer type 'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a bridged cast}} \
-  // expected-note{{use __bridge to convert directly (no change in ownership)}} \
-  // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
-  // CHECK: fix-it:"{{.*}}":{40:14-40:14}:"__bridge "
+  // expected-note{{use __bridge to convert directly (no change in ownership)}} expected-note{{use CFBridgingRelease call to transfer ownership of a +1 'CFTypeRef' (aka 'const void *') into ARC}}
   // CHECK: fix-it:"{{.*}}":{40:17-40:17}:"CFBridgingRelease("
   // CHECK: fix-it:"{{.*}}":{40:36-40:36}:")"
 
   CFTypeRef cf1 = (CFTypeRef)CreateSomething(); // expected-error{{cast of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
   // expected-note{{use __bridge to convert directly (no change in ownership)}} \
   // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
-  // CHECK: fix-it:"{{.*}}":{47:20-47:20}:"__bridge "
-  // CHECK: fix-it:"{{.*}}":{47:30-47:30}:"CFBridgingRetain("
-  // CHECK: fix-it:"{{.*}}":{47:47-47:47}:")"
+  // CHECK: fix-it:"{{.*}}":{45:30-45:30}:"CFBridgingRetain("
+  // CHECK: fix-it:"{{.*}}":{45:47-45:47}:")"
 
   return (obj1); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
   // expected-note{{use __bridge to convert directly (no change in ownership)}} \
   // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
-  // CHECK: fix-it:"{{.*}}":{54:10-54:10}:"(__bridge CFTypeRef)"
-  // CHECK: fix-it:"{{.*}}":{54:10-54:10}:"CFBridgingRetain"
+  // CHECK: fix-it:"{{.*}}":{51:10-51:10}:"(__bridge CFTypeRef)"
+  // CHECK: fix-it:"{{.*}}":{51:10-51:10}:"CFBridgingRetain"
 }
 
 CFTypeRef fixitsWithSpace(id obj) {
   return(obj); // expected-error{{implicit conversion of Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged cast}} \
   // expected-note{{use __bridge to convert directly (no change in ownership)}} \
   // expected-note{{use CFBridgingRetain call to make an ARC object available as a +1 'CFTypeRef' (aka 'const void *')}}
-  // CHECK: fix-it:"{{.*}}":{62:9-62:9}:"(__bridge CFTypeRef)"
-  // CHECK: fix-it:"{{.*}}":{62:9-62:9}:" CFBridgingRetain"
+  // CHECK: fix-it:"{{.*}}":{59:9-59:9}:"(__bridge CFTypeRef)"
+  // CHECK: fix-it:"{{.*}}":{59:9-59:9}:" CFBridgingRetain"
 }
diff --git a/test/SemaObjC/arc-cf.m b/test/SemaObjC/arc-cf.m
index 69662ea..5754720 100644
--- a/test/SemaObjC/arc-cf.m
+++ b/test/SemaObjC/arc-cf.m
@@ -10,11 +10,13 @@
 typedef const struct __CFString *CFStringRef;
 
 extern CFStringRef CFMakeString0(void);
+#pragma clang arc_cf_code_audited begin
 extern CFStringRef CFCreateString0(void);
+#pragma clang arc_cf_code_audited end
 void test0() {
   id x;
   x = (id) CFMakeString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
-  x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
+  x = (id) CFCreateString0(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
 }
 
 extern CFStringRef CFMakeString1(void) __attribute__((cf_returns_not_retained));
@@ -22,7 +24,7 @@
 void test1() {
   id x;
   x = (id) CFMakeString1();
-  x = (id) CFCreateString1(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
+  x = (id) CFCreateString1(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
 }
 
 #define CF_AUDIT_BEGIN _Pragma("clang arc_cf_code_audited begin")
@@ -40,6 +42,6 @@
   id x;
   x = (id) CFMakeString2();
   x = (id) CFCreateString2();
-  x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
-  x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{__bridge to convert directly}} expected-note {{CFBridgingRelease call to transfer}}
+  x = (id) CFMakeString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
+  x = (id) CFCreateString3(); // expected-error {{requires a bridged cast}} expected-note {{CFBridgingRelease call to transfer}}
 }
diff --git a/test/SemaObjC/arc-dict-bridged-cast.m b/test/SemaObjC/arc-dict-bridged-cast.m
new file mode 100644
index 0000000..ea64840
--- /dev/null
+++ b/test/SemaObjC/arc-dict-bridged-cast.m
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// rdar://11913153
+
+typedef const struct __CFString * CFStringRef;
+typedef struct __CFString * CFMutableStringRef;
+typedef signed long CFIndex;
+typedef const struct __CFAllocator * CFAllocatorRef;
+
+extern const CFStringRef kCFBundleNameKey;
+
+@protocol NSCopying @end
+
+@interface NSDictionary
+- (id)objectForKeyedSubscript:(id<NSCopying>)key;
+@end
+
+#pragma clang arc_cf_code_audited begin
+extern
+CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength);
+#pragma clang arc_cf_code_audited end
+
+typedef const void * CFTypeRef;
+
+id CFBridgingRelease(CFTypeRef __attribute__((cf_consumed)) X);
+
+@interface NSMutableString @end
+
+NSMutableString *test() {
+  NSDictionary *infoDictionary;
+  infoDictionary[kCFBundleNameKey] = 0; // expected-error {{indexing expression is invalid because subscript type 'CFStringRef' (aka 'const struct __CFString *') is not an integral or Objective-C pointer type}} \
+                                        // expected-error {{implicit conversion of C pointer type 'CFStringRef' (aka 'const struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \
+                                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                                        // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFStringRef' (aka 'const struct __CFString *') into ARC}}
+  return infoDictionary[CFStringCreateMutable(((void*)0), 100)]; // expected-error {{indexing expression is invalid because subscript type 'CFMutableStringRef' (aka 'struct __CFString *') is not an integral or Objective-C pointer type}} \
+                                       // expected-error {{implicit conversion of C pointer type 'CFMutableStringRef' (aka 'struct __CFString *') to Objective-C pointer type '__strong id<NSCopying>' requires a bridged cast}} \
+                                        // expected-note {{use CFBridgingRelease call to transfer ownership of a +1 'CFMutableStringRef' (aka 'struct __CFString *') into ARC}}
+					
+}
+
+// CHECK: fix-it:"{{.*}}":{31:18-31:18}:"(__bridge __strong id<NSCopying>)("
+// CHECK: fix-it:"{{.*}}":{31:34-31:34}:")"
+// CHECK: fix-it:"{{.*}}":{31:18-31:18}:"CFBridgingRelease("
+// CHECK: fix-it:"{{.*}}":{31:34-31:34}:")"
+// CHECK: fix-it:"{{.*}}":{35:25-35:25}:"CFBridgingRelease("
+// CHECK: fix-it:"{{.*}}":{35:63-35:63}:")"
diff --git a/test/SemaObjC/arc-unbridged-cast.m b/test/SemaObjC/arc-unbridged-cast.m
index 7d5a6b0..6a39e70 100644
--- a/test/SemaObjC/arc-unbridged-cast.m
+++ b/test/SemaObjC/arc-unbridged-cast.m
@@ -44,10 +44,10 @@
   x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
   x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
 
-  x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
-  x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
-  x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
-  x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
 
   x = (id) [object property];
   x = (id) (cond ? [object property] : (void*) 0);
diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m
index d6a56e5..260462a 100644
--- a/test/SemaObjC/attr-deprecated.m
+++ b/test/SemaObjC/attr-deprecated.m
@@ -121,3 +121,16 @@
 __attribute__((deprecated))
 @interface A(Blah) // expected-error{{attributes may not be specified on a category}}
 @end
+
+
+typedef struct {
+	int x;
+} footype __attribute((deprecated)); // expected-note 2 {{declared here}}
+
+@interface foo {
+	footype a; // expected-warning {{'footype' is deprecated}}
+	footype b __attribute((deprecated));
+}
+@property footype c; // expected-warning {{'footype' is deprecated}}
+@property footype d __attribute((deprecated));
+@end
diff --git a/test/SemaObjC/continuation-class-err.m b/test/SemaObjC/continuation-class-err.m
index ceb8ee9..8378c3f 100644
--- a/test/SemaObjC/continuation-class-err.m
+++ b/test/SemaObjC/continuation-class-err.m
@@ -5,13 +5,13 @@
   id _object;
   id _object1;
 }
-@property(readonly) id object;	// expected-note {{property declared here}}
+@property(readonly) id object;
 @property(readwrite, assign) id object1; // expected-note {{property declared here}}
 @property (readonly) int indentLevel;
 @end
 
 @interface ReadOnly ()
-@property(readwrite, copy) id object;	// expected-warning {{property attribute in class extension does not match the primary class}}
+@property(readwrite, copy) id object; // Ok. declaring memory model in class extension - primary has none.
 @property(readonly) id object1; // expected-error {{illegal redeclaration of property in class extension 'ReadOnly' (attribute must be 'readwrite', while its primary must be 'readonly')}}
 @property (readwrite, assign) int indentLevel; // OK. assign the default in any case.
 @end
diff --git a/test/SemaObjC/dealloc.m b/test/SemaObjC/dealloc.m
new file mode 100644
index 0000000..feafafd
--- /dev/null
+++ b/test/SemaObjC/dealloc.m
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// rdar://11987838
+
+@protocol NSObject
+- dealloc; // expected-error {{return type must be correctly specified as 'void' under ARC, instead of 'id'}}
+// CHECK: fix-it:"{{.*}}":{6:3-6:3}:"(void)"
+@end
+
+@protocol Foo <NSObject> @end
+
+@interface Root <Foo>
+@end
+
+@interface Baz : Root {
+}
+@end
+
+@implementation Baz
+-  (id) dealloc { // expected-error {{return type must be correctly specified as 'void' under ARC, instead of 'id'}}
+// CHECK: fix-it:"{{.*}}":{20:5-20:7}:"void"
+}
+
+@end
+
diff --git a/test/SemaObjC/delay-parsing-cfunctions.m b/test/SemaObjC/delay-parsing-cfunctions.m
index 81734fd..a6f66fe 100644
--- a/test/SemaObjC/delay-parsing-cfunctions.m
+++ b/test/SemaObjC/delay-parsing-cfunctions.m
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1  -fsyntax-only -Werror -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Werror -verify -Wno-objc-root-class %s
 // rdar://10387088
 
 @interface MyClass
@@ -23,6 +22,14 @@
     return getMe + bar(myObject);
 }
 
+int KR(myObject)
+MyClass * myObject;
+{
+    [myObject privateMethod];
+    [myObject privateMethod1];
+    return getMe + bar(myObject);
+}
+
 - (void)privateMethod1 {
   getMe = getMe+1;
 }
diff --git a/test/SemaObjC/error-implicit-property.m b/test/SemaObjC/error-implicit-property.m
index ea0587a..7e795c7 100644
--- a/test/SemaObjC/error-implicit-property.m
+++ b/test/SemaObjC/error-implicit-property.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -Wno-objc-root-class -verify %s
 // rdar://11273060
 
 @interface I
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 840694a..7faa995 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -34,9 +34,9 @@
 #define CFSTR(cStr)  ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
 
 // This function is used instead of the builtin if -fno-constant-cfstrings.
-// The definition on Mac OS X is NOT annotated with format_arg as of 10.7,
-// but if it were, we want the same checking behavior as with the builtin.
-extern CFStringRef __CFStringMakeConstantString(const char *) __attribute__((format_arg(1)));
+// The definition on Mac OS X is NOT annotated with format_arg as of 10.8,
+// but clang will implicitly add the attribute if it's not written.
+extern CFStringRef __CFStringMakeConstantString(const char *);
 
 int printf(const char * restrict, ...) ;
 
diff --git a/test/SemaObjC/getter-setter-defined-in-category-of-parent.m b/test/SemaObjC/getter-setter-defined-in-category-of-parent.m
new file mode 100644
index 0000000..71c3237
--- /dev/null
+++ b/test/SemaObjC/getter-setter-defined-in-category-of-parent.m
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+
+@interface MyParent {
+  int X;
+}
+@end
+@implementation MyParent
+@end
+
+@interface MyParent(AA) {
+}
+@end
+@implementation MyParent (AA)
+- (void) setX: (int)in {X = in - 2;}
+- (int) X {return X;}
+@end
+
+@interface MyClass : MyParent
+@end
+@implementation MyClass
+@end
+
+int foo(MyClass *o) {
+  o.X = 2;
+  return o.X;
+}
\ No newline at end of file
diff --git a/test/SemaObjC/iboutlet.m b/test/SemaObjC/iboutlet.m
index c9f5d8c..a29915c 100644
--- a/test/SemaObjC/iboutlet.m
+++ b/test/SemaObjC/iboutlet.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties  -verify %s
-// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-default-synthesize-properties  -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-default-synthesize-properties -Wno-objc-root-class -verify %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -fobjc-default-synthesize-properties -Wno-objc-root-class -verify %s
 // rdar://11448209
 
 #define READONLY readonly
diff --git a/test/SemaObjC/no-ivar-in-interface-block.m b/test/SemaObjC/no-ivar-in-interface-block.m
index 1d3b518..215db61 100644
--- a/test/SemaObjC/no-ivar-in-interface-block.m
+++ b/test/SemaObjC/no-ivar-in-interface-block.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -fsyntax-only -verify -Wobjc-interface-ivars %s
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class -Wobjc-interface-ivars %s
 // rdar://10763173
 
 @interface I
diff --git a/test/SemaObjC/property-12.m b/test/SemaObjC/property-12.m
index ee9cb1a..c4a7555 100644
--- a/test/SemaObjC/property-12.m
+++ b/test/SemaObjC/property-12.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wreadonly-setter-attrs -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -Wreadonly-setter-attrs -verify %s
 
 @protocol P0
 @property(readonly,assign) id X; // expected-warning {{property attributes 'readonly' and 'assign' are mutually exclusive}}
diff --git a/test/SemaObjC/property-impl-misuse.m b/test/SemaObjC/property-impl-misuse.m
index a5e1dd6..939909e 100644
--- a/test/SemaObjC/property-impl-misuse.m
+++ b/test/SemaObjC/property-impl-misuse.m
@@ -30,8 +30,8 @@
 @synthesize gradientStyle = _gradientStyle;
 - (void)setGradientStyle:(id)value { }
 
-+ (void)_componentCellWithRepresentedObject {
-    self.gradientStyle; // expected-error {{property 'gradientStyle' not found on object of type 'Class'}}
++ (id)_componentCellWithRepresentedObject {
+    return self.gradientStyle;
 }
 @end
 
diff --git a/test/SemaObjC/property-in-class-extension-1.m b/test/SemaObjC/property-in-class-extension-1.m
new file mode 100644
index 0000000..dfa5e71
--- /dev/null
+++ b/test/SemaObjC/property-in-class-extension-1.m
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1  -fsyntax-only -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -verify -Weverything %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -verify -Weverything %s
+// rdar://12103400
+
+@class NSString;
+
+@interface MyClass
+
+@property (nonatomic, readonly) NSString* addingMemoryModel;
+
+@property (nonatomic, copy, readonly) NSString* matchingMemoryModel;
+
+@property (nonatomic, retain, readonly) NSString* addingNoNewMemoryModel;
+
+@property (readonly) NSString* none;
+@property (readonly) NSString* none1;
+
+@property (assign, readonly) NSString* changeMemoryModel; // expected-note {{property declared here}}
+
+@property (readonly) __weak id weak_prop;
+@property (readonly) __weak id weak_prop1;
+
+@property (assign, readonly) NSString* assignProperty;
+
+@property (readonly) NSString* readonlyProp;
+
+
+
+@end
+
+@interface MyClass ()
+{
+  NSString* _name;
+}
+
+@property (nonatomic, copy) NSString* addingMemoryModel;
+@property (nonatomic, copy) NSString* matchingMemoryModel;
+@property () NSString* addingNoNewMemoryModel;
+@property () NSString* none;
+@property (readwrite) NSString* none1;
+
+@property (retain) NSString* changeMemoryModel; // expected-warning {{property attribute in class extension does not match the primary class}}
+@property () __weak id weak_prop;
+@property (readwrite) __weak id weak_prop1;
+
+@property () NSString* assignProperty;
+@property (assign) NSString* readonlyProp;
+@end
+
diff --git a/test/SemaObjC/protocol-attribute.m b/test/SemaObjC/protocol-attribute.m
index a2414c4..b2aecc2 100644
--- a/test/SemaObjC/protocol-attribute.m
+++ b/test/SemaObjC/protocol-attribute.m
@@ -6,7 +6,7 @@
 Class <FwProto> cFw = 0;  // expected-error {{'FwProto' is unavailable}}
 
 
-__attribute ((deprecated)) @protocol MyProto1 // expected-note 5 {{declared here}}
+__attribute ((deprecated)) @protocol MyProto1 // expected-note 7 {{declared here}}
 @end
 
 @protocol Proto2  <MyProto1>  // expected-warning {{'MyProto1' is deprecated}}
diff --git a/test/SemaObjC/unused.m b/test/SemaObjC/unused.m
index 975b9a9..5c7542b 100644
--- a/test/SemaObjC/unused.m
+++ b/test/SemaObjC/unused.m
@@ -51,3 +51,5 @@
 }
 @end
 
+// rdar://10777111
+static NSString *x = @"hi"; // expected-warning {{unused variable 'x'}}
diff --git a/test/SemaObjC/warn-cast-of-sel-expr.m b/test/SemaObjC/warn-cast-of-sel-expr.m
new file mode 100644
index 0000000..97915a0
--- /dev/null
+++ b/test/SemaObjC/warn-cast-of-sel-expr.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-unused-value %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -verify -Wcast-of-sel-type -Wno-unused-value %s
+// rdar://12107381
+
+SEL s;
+
+SEL sel_registerName(const char *);
+
+int main() {
+(char *)s;  // expected-warning {{cast of type 'SEL' to 'char *' is deprecated; use sel_getName instead}}
+(void *)s;  // ok
+(const char *)sel_registerName("foo");  // expected-warning {{cast of type 'SEL' to 'const char *' is deprecated; use sel_getName instead}}
+
+(const void *)sel_registerName("foo");  // ok
+
+(void) s;   // ok
+
+(void *const)s; // ok
+
+(const void *const)s; // ok
+}
diff --git a/test/SemaObjC/warn-direct-ivar-access.m b/test/SemaObjC/warn-direct-ivar-access.m
new file mode 100644
index 0000000..d2295f4
--- /dev/null
+++ b/test/SemaObjC/warn-direct-ivar-access.m
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1  -fsyntax-only -fobjc-arc -fobjc-runtime-has-weak  -Wdirect-ivar-access -verify -Wno-objc-root-class %s
+// rdar://6505197
+
+__attribute__((objc_root_class)) @interface MyObject {
+@public
+    id _myMaster;
+    id _isTickledPink;
+    int _myIntProp;
+}
+@property(retain) id myMaster;
+@property(assign) id isTickledPink; // expected-note {{property declared here}}
+@property int myIntProp;
+@end
+
+@implementation MyObject
+
+@synthesize myMaster = _myMaster;
+@synthesize isTickledPink = _isTickledPink; // expected-error {{existing ivar '_isTickledPink' for property 'isTickledPink'}}
+@synthesize myIntProp = _myIntProp;
+
+- (void) doSomething {
+    _myMaster = _isTickledPink; // expected-warning {{instance variable '_myMaster' is being directly accessed}} \
+    // expected-warning {{instance variable '_isTickledPink' is being directly accessed}}
+}
+
+- (id) init {
+    _myMaster=0;
+    return _myMaster;
+}
+- (void) dealloc { _myMaster = 0; }
+@end
+
+MyObject * foo ()
+{
+	MyObject* p=0;
+        p.isTickledPink = p.myMaster;	// ok
+	p->_isTickledPink = (*p)._myMaster; // expected-warning {{instance variable '_isTickledPink' is being directly accessed}} \
+        // expected-warning {{instance variable '_myMaster' is being directly accessed}}
+        if (p->_myIntProp) // expected-warning {{instance variable '_myIntProp' is being directly accessed}}
+          p->_myIntProp = 0; // expected-warning {{instance variable '_myIntProp' is being directly accessed}}
+	return p->_isTickledPink; // expected-warning {{instance variable '_isTickledPink' is being directly accessed}}
+}
+
+@interface ITest32 {
+@public
+ id ivar;
+}
+@end
+
+id Test32(__weak ITest32 *x) {
+  __weak ITest32 *y;
+  x->ivar = 0; // expected-error {{dereferencing a __weak pointer is not allowed}}
+  return y ? y->ivar     // expected-error {{dereferencing a __weak pointer is not allowed}}
+           : (*x).ivar;  // expected-error {{dereferencing a __weak pointer is not allowed}}
+}
+
diff --git a/test/SemaObjC/weak-receiver-warn.m b/test/SemaObjC/weak-receiver-warn.m
index e6f8eab..547f008 100644
--- a/test/SemaObjC/weak-receiver-warn.m
+++ b/test/SemaObjC/weak-receiver-warn.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wreceiver-is-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -Wreceiver-is-weak -verify %s
 // rdar://10225276
 
 @interface Test0
diff --git a/test/SemaObjCXX/abstract-class-type-ivar.mm b/test/SemaObjCXX/abstract-class-type-ivar.mm
new file mode 100644
index 0000000..823e9c1
--- /dev/null
+++ b/test/SemaObjCXX/abstract-class-type-ivar.mm
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://12095239
+
+class CppAbstractBase {
+public:
+    virtual void testA() = 0;
+    virtual void testB() = 0; // expected-note {{unimplemented pure virtual method 'testB' in 'CppConcreteSub}}
+    int a;
+};
+
+class CppConcreteSub : public CppAbstractBase {
+    virtual void testA() { }
+};
+
+@interface Objc  {
+    CppConcreteSub _concrete; // expected-error{{ivar type 'CppConcreteSub' is an abstract class}}
+}
+- (CppAbstractBase*)abstract;
+@end
+@implementation Objc
+- (CppAbstractBase*)abstract {
+    return &_concrete;
+}
+@end
+
+class Cpp {
+public:
+    CppConcreteSub sub; // expected-error {{field type 'CppConcreteSub' is an abstract class}}
+};
diff --git a/test/SemaObjCXX/arc-0x.mm b/test/SemaObjCXX/arc-0x.mm
index 49ce145..e24b960 100644
--- a/test/SemaObjCXX/arc-0x.mm
+++ b/test/SemaObjCXX/arc-0x.mm
@@ -11,6 +11,9 @@
 - init;
 @end
 
+// <rdar://problem/12031870>: don't warn about this
+extern "C" A* MakeA();
+
 // Ensure that deduction works with lifetime qualifiers.
 void deduction(id obj) {
   auto a = [[A alloc] init];
diff --git a/test/SemaObjCXX/arc-unbridged-cast.mm b/test/SemaObjCXX/arc-unbridged-cast.mm
index 0b3ba07..f7d2391 100644
--- a/test/SemaObjCXX/arc-unbridged-cast.mm
+++ b/test/SemaObjCXX/arc-unbridged-cast.mm
@@ -44,10 +44,10 @@
   x = (id) (cond ? (void*) 0 : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
   x = (id) (cond ? (CFStringRef) @"help" : unauditedString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
 
-  x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
-  x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
-  x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
-  x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use __bridge to}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) auditedCreateString(); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) (cond ? auditedCreateString() : (void*) 0); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) (cond ? (void*) 0 : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
+  x = (id) (cond ? (CFStringRef) @"help" : auditedCreateString()); // expected-error {{requires a bridged cast}} expected-note {{use CFBridgingRelease call to}}
 
   x = (id) [object property];
   x = (id) (cond ? [object property] : (void*) 0);
diff --git a/test/SemaObjCXX/delay-parsing-cplusfuncs.mm b/test/SemaObjCXX/delay-parsing-cplusfuncs.mm
new file mode 100644
index 0000000..b022709
--- /dev/null
+++ b/test/SemaObjCXX/delay-parsing-cplusfuncs.mm
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Werror -verify -Wno-objc-root-class %s
+// rdar://10387088
+
+@interface MyClass
+- (void)someMethod;
+@end
+
+struct S {
+  int bar(MyClass * myObject);
+
+  int gorfbar(MyClass * myObject);
+
+  S();
+  S(MyClass *O1, MyClass *O2);
+  S(MyClass *O1);
+
+  MyClass * Obj1, *Obj2;
+
+};
+
+@implementation MyClass
+- (void)someMethod {
+    [self privateMethod];  // clang already does not warn here
+}
+
+int S::bar(MyClass * myObject) {
+    [myObject privateMethod]; 
+    return gorfbar(myObject);
+}
+- (void)privateMethod { }
+
+int S::gorfbar(MyClass * myObject) {
+    [myObject privateMethod]; 
+    [myObject privateMethod1]; 
+    return getMe + bar(myObject);
+}
+
+S::S(MyClass *O1, MyClass *O2) : Obj1(O1), Obj2(O2) {
+    [O1 privateMethod]; 
+    [O2 privateMethod1]; 
+}
+S::S(MyClass *O1) : Obj1(O1){ Obj2 = 0; }
+
+S::S() {}
+
+- (void)privateMethod1 {
+  getMe = getMe+1;
+}
+
+static int getMe;
+
+@end
diff --git a/test/SemaObjCXX/delay-parsing-func-tryblock.mm b/test/SemaObjCXX/delay-parsing-func-tryblock.mm
new file mode 100644
index 0000000..8cf615e
--- /dev/null
+++ b/test/SemaObjCXX/delay-parsing-func-tryblock.mm
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -x objective-c++ -fcxx-exceptions -fsyntax-only -Werror -verify -Wno-objc-root-class %s
+// rdar://10387088
+
+@interface MyClass
+- (void)someMethod;
+@end
+
+struct BadReturn {
+  BadReturn(MyClass * myObject);
+  int bar(MyClass * myObject);
+  void MemFunc(MyClass * myObject);
+  int i;
+  MyClass *CObj;
+};
+
+@implementation MyClass
+- (void)someMethod {
+    [self privateMethod];  // clang already does not warn here
+}
+
+int BadReturn::bar(MyClass * myObject) {
+    [myObject privateMethod];
+    return 0;
+}
+
+BadReturn::BadReturn(MyClass * myObject) try : CObj(myObject) {
+} catch(...) {
+  try {
+    [myObject privateMethod];
+    [myObject privateMethod1];
+    getMe = bar(myObject);
+    [CObj privateMethod1];
+  } catch(int ei) {
+    i = ei;
+  } catch(...) {
+    {
+      i = 0;
+    }
+  }
+}
+
+void BadReturn::MemFunc(MyClass * myObject) try {
+} catch(...) {
+  try {
+    [myObject privateMethod];
+    [myObject privateMethod1];
+    getMe = bar(myObject);
+    [CObj privateMethod1];
+  } catch(int ei) {
+    i = ei;
+  } catch(...) {
+    {
+      i = 0;
+    }
+  }
+}
+
+- (void)privateMethod { }
+
+- (void)privateMethod1 {
+  getMe = getMe+1;
+}
+
+static int getMe;
+
+@end
diff --git a/test/SemaObjCXX/protocol-lookup.mm b/test/SemaObjCXX/protocol-lookup.mm
index bd8444c..e8abf6c 100644
--- a/test/SemaObjCXX/protocol-lookup.mm
+++ b/test/SemaObjCXX/protocol-lookup.mm
@@ -52,5 +52,5 @@
 void rdar8575095(id a) {
   [id<NSObject>(a) retain];
   id<NSObject> x(id<NSObject>(0));
-  id<NSObject> x2(id<NSObject>(y)); // expected-warning{{parentheses were disambiguated as a function declarator}}
+  id<NSObject> x2(id<NSObject>(y)); // expected-warning{{disambiguated as a function declaration}} expected-note{{add a pair of parentheses}}
 }
diff --git a/test/SemaObjCXX/warn-missing-super.mm b/test/SemaObjCXX/warn-missing-super.mm
new file mode 100644
index 0000000..cd2a6cc
--- /dev/null
+++ b/test/SemaObjCXX/warn-missing-super.mm
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// PR13401
+
+__attribute((objc_root_class)) @interface NSObject
+@end
+
+@interface Dummy : NSObject
+@end
+
+template<typename T> struct shared_ptr {
+  constexpr shared_ptr() {}
+};
+
+@implementation Dummy
+- (void)dealloc
+{
+	constexpr shared_ptr<int> dummy;
+} // expected-warning {{method possibly missing a [super dealloc] call}}
+@end
diff --git a/test/SemaOpenCL/warn-missing-prototypes.cl b/test/SemaOpenCL/warn-missing-prototypes.cl
new file mode 100644
index 0000000..487cb28
--- /dev/null
+++ b/test/SemaOpenCL/warn-missing-prototypes.cl
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-prototypes %s
+
+void f() { } // expected-warning {{no previous prototype for function 'f'}}
+
+// Don't warn about kernel functions.
+kernel void g() { }
diff --git a/test/SemaTemplate/class-template-id.cpp b/test/SemaTemplate/class-template-id.cpp
index 3b02778..b674537 100644
--- a/test/SemaTemplate/class-template-id.cpp
+++ b/test/SemaTemplate/class-template-id.cpp
@@ -40,7 +40,7 @@
 // PR5655
 template<typename T> struct Foo { }; // expected-note{{template is declared here}}
 
-void f(void) { Foo bar; } // expected-error{{without a template argument list}}
+void f(void) { Foo bar; } // expected-error{{use of class template Foo requires template arguments}}
 
 // rdar://problem/8254267
 template <typename T> class Party;
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index 13d76be..e3e77d0 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -14,7 +14,7 @@
   T f0(T x) {
     return x + 1;  // expected-error{{invalid operands}}
   } 
-  T* f0(T*, T*) { return T(); }
+  T* f0(T*, T*) { return T(); } // expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
   
   template<typename U>
   T f0(T, U) { return T(); }
@@ -32,7 +32,7 @@
 template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}}
 
 template int X0<int>::f0(int);
-template int* X0<int>::f0(int*, int*);
+template int* X0<int>::f0(int*, int*); // expected-note{{in instantiation of member function 'X0<int>::f0' requested here}}
 template int X0<int>::f0(int, float);
 
 template int X0<int>::f0(int) const; // expected-error{{does not refer}}
diff --git a/test/SemaTemplate/instantiate-member-class.cpp b/test/SemaTemplate/instantiate-member-class.cpp
index bb64276..7b42a27 100644
--- a/test/SemaTemplate/instantiate-member-class.cpp
+++ b/test/SemaTemplate/instantiate-member-class.cpp
@@ -124,19 +124,20 @@
   {
     struct B
     {
-      struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+      struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \
+                                             expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
     };
   };
 
   template<int N> void foo()
   {
-    class A<N>::B::C X; // expected-note{{in instantiation of member function}}
+    class A<N>::B::C X; // expected-note 2 {{in instantiation of member function}}
     int A<N+1>::B::C::*member = 0;
   }
 
   void bar()
   {
-    foo<0>();
+    foo<0>(); // expected-note{{in instantiation of function template}}
     foo<1>(); // expected-note{{in instantiation of function template}}
   }
 }
diff --git a/test/SemaTemplate/instantiation-depth.cpp b/test/SemaTemplate/instantiation-depth.cpp
index 8e1b803..c0b8bb2 100644
--- a/test/SemaTemplate/instantiation-depth.cpp
+++ b/test/SemaTemplate/instantiation-depth.cpp
@@ -2,12 +2,30 @@
 // RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth-5 -ftemplate-backtrace-limit=4 %s
 // RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth=5 -ftemplate-backtrace-limit=4 %s
 
+#ifndef NOEXCEPT
+
 template<typename T> struct X : X<T*> { }; \
 // expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
 // expected-note 3 {{instantiation of template class}} \
 // expected-note {{skipping 2 contexts in backtrace}} \
 // expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
 
-void test() { 
+void test() {
   (void)sizeof(X<int>); // expected-note {{instantiation of template class}}
 }
+
+#else
+
+// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 -std=c++11 -DNOEXCEPT %s
+
+template<typename T> struct S {
+  S() noexcept(noexcept(T()));
+};
+struct T : S<T> {}; \
+// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
+// expected-note 4 {{in instantiation of exception spec}} \
+// expected-note {{skipping 2 contexts in backtrace}} \
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
+T t; // expected-note {{implicit default constructor for 'T' first required here}}
+
+#endif
diff --git a/test/SemaTemplate/member-access-ambig.cpp b/test/SemaTemplate/member-access-ambig.cpp
index f8a01d5..5c2d761 100644
--- a/test/SemaTemplate/member-access-ambig.cpp
+++ b/test/SemaTemplate/member-access-ambig.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused-comparison %s
 
 // PR8439
 class A
@@ -43,3 +43,22 @@
   };
 }
 
+namespace AddrOfMember {
+  struct A { int X; };
+  typedef int (A::*P);
+  template<typename T> struct S : T {
+    void f() {
+      P(&T::X) // expected-error {{cannot cast from type 'int *' to member pointer type 'P'}}
+          == &A::X;
+    }
+  };
+
+  void g() {
+    S<A>().f(); // ok, &T::X is 'int (A::*)', not 'int *', even though T is a base class
+  }
+
+  struct B : A { static int X; };
+  void h() {
+    S<B>().f(); // expected-note {{here}}
+  }
+}
diff --git a/test/SemaTemplate/typename-specifier.cpp b/test/SemaTemplate/typename-specifier.cpp
index 15c13e3..733dc7f 100644
--- a/test/SemaTemplate/typename-specifier.cpp
+++ b/test/SemaTemplate/typename-specifier.cpp
@@ -22,8 +22,8 @@
 // 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}} \
-  // expected-warning 2{{'typename' occurs outside of a template}}
+  typename N::A::type f(typename N::A::type(a)); // expected-warning{{disambiguated as a function declaration}} \
+  // expected-note{{add a pair of parentheses}} expected-warning 2{{'typename' occurs outside of a template}}
   int five = f(5);
   
   using namespace N;
diff --git a/test/Tooling/Inputs/lit.local.cfg b/test/Tooling/Inputs/lit.local.cfg
new file mode 100644
index 0000000..e6f55ee
--- /dev/null
+++ b/test/Tooling/Inputs/lit.local.cfg
@@ -0,0 +1 @@
+config.suffixes = []
diff --git a/test/Tooling/Inputs/pch-fail.h b/test/Tooling/Inputs/pch-fail.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Tooling/Inputs/pch-fail.h
diff --git a/test/Tooling/Inputs/pch.cpp b/test/Tooling/Inputs/pch.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Tooling/Inputs/pch.cpp
diff --git a/test/Tooling/Inputs/pch.h b/test/Tooling/Inputs/pch.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Tooling/Inputs/pch.h
diff --git a/test/Tooling/clang-ast-dump.cpp b/test/Tooling/clang-ast-dump.cpp
deleted file mode 100644
index 3847bc6..0000000
--- a/test/Tooling/clang-ast-dump.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: clang-ast-dump "%s" -f test_namespace::TheClass::theMethod -- -c 2>&1 | FileCheck %s
-
-// FIXME: Does this run regardless of +Asserts?
-// REQUIRES: asserts
-
-// CHECK: <CXXMethod ptr="0x{{[0-9a-f]+}}" name="theMethod" prototype="true">
-// CHECK:  <ParmVar ptr="0x{{[0-9a-f]+}}" name="x" initstyle="c">
-// CHECK: (CompoundStmt
-// CHECK-NEXT:   (ReturnStmt
-// CHECK-NEXT:     (BinaryOperator
-
-namespace test_namespace {
-
-class TheClass {
-public:
-  int theMethod(int x) {
-    return x + x;
-  }
-};
-
-}
diff --git a/test/Tooling/clang-check-ast-dump.cpp b/test/Tooling/clang-check-ast-dump.cpp
new file mode 100644
index 0000000..28dcc6e
--- /dev/null
+++ b/test/Tooling/clang-check-ast-dump.cpp
@@ -0,0 +1,43 @@
+// RUN: clang-check -ast-dump "%s" -- 2>&1 | FileCheck %s
+// CHECK: namespace test_namespace
+// CHECK-NEXT: class TheClass
+// CHECK: int theMethod(int x) (CompoundStmt
+// CHECK-NEXT:   (ReturnStmt
+// CHECK-NEXT:     (BinaryOperator
+//
+// RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::theMethod "%s" -- 2>&1 | FileCheck -check-prefix CHECK-FILTER %s
+// CHECK-FILTER-NOT: namespace test_namespace
+// CHECK-FILTER-NOT: class TheClass
+// CHECK-FILTER: int theMethod(int x) (CompoundStmt
+// CHECK-FILTER-NEXT:   (ReturnStmt
+// CHECK-FILTER-NEXT:     (BinaryOperator
+//
+// RUN: clang-check -ast-print "%s" -- 2>&1 | FileCheck -check-prefix CHECK-PRINT %s
+// CHECK-PRINT: namespace test_namespace
+// CHECK-PRINT: class TheClass
+// CHECK-PRINT: int theMethod(int x)
+//
+// RUN: clang-check -ast-list "%s" -- 2>&1 | FileCheck -check-prefix CHECK-LIST %s
+// CHECK-LIST: test_namespace
+// CHECK-LIST-NEXT: test_namespace::TheClass
+// CHECK-LIST-NEXT: test_namespace::TheClass::theMethod
+// CHECK-LIST-NEXT: x
+//
+// RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::n "%s" -- 2>&1 | FileCheck -check-prefix CHECK-ATTR %s
+// CHECK-ATTR: test_namespace
+// CHECK-ATTR-NEXT: int n __attribute__((aligned((BinaryOperator
+
+namespace test_namespace {
+
+class TheClass {
+public:
+  int theMethod(int x) {
+    return x + x;
+  }
+  int n __attribute__((aligned(1+1)));
+};
+
+// Used to fail with -ast-dump-filter X
+template<template<typename T> class C> class Z {};
+
+}
diff --git a/test/Tooling/pch.cpp b/test/Tooling/pch.cpp
new file mode 100644
index 0000000..715c95d
--- /dev/null
+++ b/test/Tooling/pch.cpp
@@ -0,0 +1,17 @@
+// This is a regression test for handling of stat caches within the tooling
+// infrastructure. This test reproduces the problem under valgrind:
+
+// First, create a pch that we can later load. Loading the pch will insert
+// a stat cache into the FileManager:
+// RUN: %clang -x c++-header %S/Inputs/pch.h -o %t1
+
+// Use the generated pch and enforce a subsequent stat miss by using
+// the test file with an unrelated include as second translation unit:
+// Do not directly pipe into FileCheck, as that would hide errors from
+// valgrind due to pipefail not being set in lit.
+// RUN: clang-check "%S/Inputs/pch.cpp" "%s" -- -include-pch %t1 -I "%S" -c >%t2 2>&1
+// RUN: FileCheck %s < %t2
+
+#include "Inputs/pch-fail.h"
+
+// CHECK: Processing
diff --git a/test/lit.cfg b/test/lit.cfg
index 1fc6059..7bc9620 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -259,3 +259,7 @@
 
 if llc_props['enable_assertions']:
     config.available_features.add('asserts')
+
+if lit.util.which('xmllint'):
+    config.available_features.add('xmllint')
+
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 2e3c842..3a6fef5 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -5,4 +5,12 @@
 add_subdirectory(diagtool)
 add_subdirectory(driver)
 add_subdirectory(clang-check)
-add_subdirectory(clang-ast-dump)
+
+# We support checking out the clang-tools-extra repository into the 'extra'
+# subdirectory. It contains tools developed as part of the Clang/LLVM project
+# on top of the Clang tooling platform. We keep them in a separate repository
+# to keep the primary Clang repository small and focused.
+if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/extra AND
+   EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/extra/CMakeLists.txt)
+  add_subdirectory(extra)
+endif()
diff --git a/tools/Makefile b/tools/Makefile
index 95c1e48..e7aa2fa 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -8,9 +8,13 @@
 ##===----------------------------------------------------------------------===##
 
 CLANG_LEVEL := ..
-DIRS := driver libclang c-index-test arcmt-test c-arcmt-test diagtool \
-        clang-check clang-ast-dump
 
 include $(CLANG_LEVEL)/../../Makefile.config
 
+DIRS := driver libclang c-index-test arcmt-test c-arcmt-test diagtool \
+        clang-check
+
+# Recurse into the extra repository of tools if present.
+OPTIONAL_DIRS := extra
+
 include $(CLANG_LEVEL)/Makefile
diff --git a/tools/arcmt-test/CMakeLists.txt b/tools/arcmt-test/CMakeLists.txt
index 3528495..f36b14a 100644
--- a/tools/arcmt-test/CMakeLists.txt
+++ b/tools/arcmt-test/CMakeLists.txt
@@ -1,4 +1,6 @@
-set( LLVM_LINK_COMPONENTS
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
   support
   mc
   )
diff --git a/tools/arcmt-test/Makefile b/tools/arcmt-test/Makefile
index 84c4dc2..719da75 100644
--- a/tools/arcmt-test/Makefile
+++ b/tools/arcmt-test/Makefile
@@ -16,7 +16,8 @@
 # Don't install this. It is used for tests.
 NO_INSTALL = 1
 
-LINK_COMPONENTS := support mc
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangARCMigrate.a clangRewrite.a \
 		 clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
 		 clangSema.a clangEdit.a clangAnalysis.a clangAST.a clangLex.a \
diff --git a/tools/c-arcmt-test/Makefile b/tools/c-arcmt-test/Makefile
index 818f648..b59afda 100644
--- a/tools/c-arcmt-test/Makefile
+++ b/tools/c-arcmt-test/Makefile
@@ -16,7 +16,12 @@
 # Don't install this. It is used for tests.
 NO_INSTALL = 1
 
-LINK_COMPONENTS := support mc
+# 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 $(CLANG_LEVEL)/../../Makefile.config
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clang.a clangARCMigrate.a clangRewrite.a \
 	   clangFrontend.a clangDriver.a \
 	   clangSerialization.a clangParse.a clangSema.a \
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index 743268c..6379194 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -15,4 +15,9 @@
   PROPERTIES
   LINKER_LANGUAGE CXX)
 
-install(TARGETS c-index-test RUNTIME DESTINATION bin)
+# If libxml2 is available, make it available for c-index-test.
+if (LIBXML2_FOUND)
+  add_definitions(${LIBXML2_DEFINITIONS} "-DCLANG_HAVE_LIBXML")
+  include_directories(${LIBXML2_INCLUDE_DIR})
+  target_link_libraries(c-index-test ${LIBXML2_LIBRARIES})
+endif()
diff --git a/tools/c-index-test/Makefile b/tools/c-index-test/Makefile
index 284844f..09eff0f 100644
--- a/tools/c-index-test/Makefile
+++ b/tools/c-index-test/Makefile
@@ -17,7 +17,15 @@
 # No plugins, optimize startup time.
 TOOL_NO_EXPORTS = 1
 
-LINK_COMPONENTS := support mc
+# Don't install this. It is used for tests.
+NO_INSTALL = 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 $(CLANG_LEVEL)/../../Makefile.config
+
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clang.a clangFrontend.a clangDriver.a \
 	   clangTooling.a \
 	   clangSerialization.a clangParse.a clangSema.a \
@@ -25,3 +33,6 @@
 	   clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile
+
+LIBS += $(LIBXML2_LIBS)
+CPPFLAGS += $(LIBXML2_INC)
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index df7c72a..5df21ec 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -2,12 +2,19 @@
 
 #include "clang-c/Index.h"
 #include "clang-c/CXCompilationDatabase.h"
+#include "llvm/Config/config.h"
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
 
+#ifdef CLANG_HAVE_LIBXML
+#include <libxml/parser.h>
+#include <libxml/relaxng.h>
+#include <libxml/xmlerror.h>
+#endif
+
 /******************************************************************************/
 /* Utility functions.                                                         */
 /******************************************************************************/
@@ -179,6 +186,19 @@
   return 0;
 }
 
+static const char *parse_comments_schema(int argc, const char **argv) {
+  const char *CommentsSchemaArg = "-comments-xml-schema=";
+  const char *CommentSchemaFile = NULL;
+
+  if (argc == 0)
+    return CommentSchemaFile;
+
+  if (!strncmp(argv[0], CommentsSchemaArg, strlen(CommentsSchemaArg)))
+    CommentSchemaFile = argv[0] + strlen(CommentsSchemaArg);
+
+  return CommentSchemaFile;
+}
+
 /******************************************************************************/
 /* Pretty-printing.                                                           */
 /******************************************************************************/
@@ -212,6 +232,10 @@
   clang_disposeString(Str);
 }
 
+static void PrintCXStringWithPrefix(const char *Prefix, CXString Str) {
+  PrintCStringWithPrefix(Prefix, clang_getCString(Str));
+}
+
 static void PrintCXStringWithPrefixAndDispose(const char *Prefix,
                                               CXString Str) {
   PrintCStringWithPrefix(Prefix, clang_getCString(Str));
@@ -378,6 +402,23 @@
     else
       printf(" ParamIndex=Invalid");
     break;
+  case CXComment_TParamCommand:
+    printf("CXComment_TParamCommand");
+    PrintCXStringWithPrefixAndDispose(
+        "ParamName",
+        clang_TParamCommandComment_getParamName(Comment));
+    if (clang_TParamCommandComment_isParamPositionValid(Comment)) {
+      printf(" ParamPosition={");
+      for (i = 0, e = clang_TParamCommandComment_getDepth(Comment);
+           i != e; ++i) {
+        printf("%u", clang_TParamCommandComment_getIndex(Comment, i));
+        if (i != e - 1)
+          printf(", ");
+      }
+      printf("}");
+    } else
+      printf(" ParamPosition=Invalid");
+    break;
   case CXComment_VerbatimBlockCommand:
     printf("CXComment_VerbatimBlockCommand");
     PrintCXStringWithPrefixAndDispose(
@@ -420,7 +461,60 @@
   printf("]");
 }
 
-static void PrintCursorComments(CXCursor Cursor) {
+typedef struct {
+  const char *CommentSchemaFile;
+#ifdef CLANG_HAVE_LIBXML
+  xmlRelaxNGParserCtxtPtr RNGParser;
+  xmlRelaxNGPtr Schema;
+#endif
+} CommentXMLValidationData;
+
+static void ValidateCommentXML(const char *Str,
+                               CommentXMLValidationData *ValidationData) {
+#ifdef CLANG_HAVE_LIBXML
+  xmlDocPtr Doc;
+  xmlRelaxNGValidCtxtPtr ValidationCtxt;
+  int status;
+
+  if (!ValidationData || !ValidationData->CommentSchemaFile)
+    return;
+
+  if (!ValidationData->RNGParser) {
+    ValidationData->RNGParser =
+        xmlRelaxNGNewParserCtxt(ValidationData->CommentSchemaFile);
+    ValidationData->Schema = xmlRelaxNGParse(ValidationData->RNGParser);
+  }
+  if (!ValidationData->RNGParser) {
+    printf(" libXMLError");
+    return;
+  }
+
+  Doc = xmlParseDoc((const xmlChar *) Str);
+
+  if (!Doc) {
+    xmlErrorPtr Error = xmlGetLastError();
+    printf(" CommentXMLInvalid [not well-formed XML: %s]", Error->message);
+    return;
+  }
+
+  ValidationCtxt = xmlRelaxNGNewValidCtxt(ValidationData->Schema);
+  status = xmlRelaxNGValidateDoc(ValidationCtxt, Doc);
+  if (!status)
+    printf(" CommentXMLValid");
+  else if (status > 0) {
+    xmlErrorPtr Error = xmlGetLastError();
+    printf(" CommentXMLInvalid [not vaild XML: %s]", Error->message);
+  } else
+    printf(" libXMLError");
+
+  xmlRelaxNGFreeValidCtxt(ValidationCtxt);
+  xmlFreeDoc(Doc);
+#endif
+}
+
+static void PrintCursorComments(CXTranslationUnit TU,
+                                CXCursor Cursor,
+                                CommentXMLValidationData *ValidationData) {
   {
     CXString RawComment;
     const char *RawCommentCString;
@@ -447,12 +541,21 @@
     if (clang_Comment_getKind(Comment) != CXComment_Null) {
       PrintCXStringWithPrefixAndDispose("FullCommentAsHTML",
                                         clang_FullComment_getAsHTML(Comment));
+      {
+        CXString XML;
+        XML = clang_FullComment_getAsXML(TU, Comment);
+        PrintCXStringWithPrefix("FullCommentAsXML", XML);
+        ValidateCommentXML(clang_getCString(XML), ValidationData);
+        clang_disposeString(XML);
+      }
+
       DumpCXComment(Comment);
     }
   }
 }
 
-static void PrintCursor(CXCursor Cursor) {
+static void PrintCursor(CXCursor Cursor,
+                        CommentXMLValidationData *ValidationData) {
   CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);
   if (clang_isInvalid(Cursor.kind)) {
     CXString ks = clang_getCursorKindSpelling(Cursor.kind);
@@ -657,7 +760,7 @@
         PrintRange(RefNameRange, "RefName");
     }
 
-    PrintCursorComments(Cursor);
+    PrintCursorComments(TU, Cursor, ValidationData);
   }
 }
 
@@ -785,10 +888,11 @@
   PrintRange(extent, "Extent");
 }
 
-/* Data used by all of the visitors. */
-typedef struct  {
+/* Data used by the visitors. */
+typedef struct {
   CXTranslationUnit TU;
   enum CXCursorKind *Filter;
+  CommentXMLValidationData ValidationData;
 } VisitorData;
 
 
@@ -802,7 +906,7 @@
     clang_getSpellingLocation(Loc, 0, &line, &column, 0);
     printf("// %s: %s:%d:%d: ", FileCheckPrefix,
            GetCursorSource(Cursor), line, column);
-    PrintCursor(Cursor);
+    PrintCursor(Cursor, &Data->ValidationData);
     PrintCursorExtent(Cursor);
     printf("\n");
     return CXChildVisit_Recurse;
@@ -855,7 +959,7 @@
       } else if (Ref.kind != CXCursor_FunctionDecl) {
         printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
                curLine, curColumn);
-        PrintCursor(Ref);
+        PrintCursor(Ref, &Data->ValidationData);
         printf("\n");
       }
     }
@@ -942,7 +1046,7 @@
   }
 
   if (linkage) {
-    PrintCursor(cursor);
+    PrintCursor(cursor, NULL);
     printf("linkage=%s\n", linkage);
   }
 
@@ -958,7 +1062,7 @@
   if (!clang_isInvalid(clang_getCursorKind(cursor))) {
     CXType T = clang_getCursorType(cursor);
     CXString S = clang_getTypeKindSpelling(T.kind);
-    PrintCursor(cursor);
+    PrintCursor(cursor, NULL);
     printf(" typekind=%s", clang_getCString(S));
     if (clang_isConstQualifiedType(T))
       printf(" const");
@@ -1018,7 +1122,8 @@
 static int perform_test_load(CXIndex Idx, CXTranslationUnit TU,
                              const char *filter, const char *prefix,
                              CXCursorVisitor Visitor,
-                             PostVisitTU PV) {
+                             PostVisitTU PV,
+                             const char *CommentSchemaFile) {
 
   if (prefix)
     FileCheckPrefix = prefix;
@@ -1049,6 +1154,11 @@
 
     Data.TU = TU;
     Data.Filter = ck;
+    Data.ValidationData.CommentSchemaFile = CommentSchemaFile;
+#ifdef CLANG_HAVE_LIBXML
+    Data.ValidationData.RNGParser = NULL;
+    Data.ValidationData.Schema = NULL;
+#endif
     clang_visitChildren(clang_getTranslationUnitCursor(TU), Visitor, &Data);
   }
 
@@ -1080,7 +1190,7 @@
     return 1;
   }
 
-  result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV);
+  result = perform_test_load(Idx, TU, filter, prefix, Visitor, PV, NULL);
   clang_disposeIndex(Idx);
   return result;
 }
@@ -1090,6 +1200,7 @@
                              PostVisitTU PV) {
   CXIndex Idx;
   CXTranslationUnit TU;
+  const char *CommentSchemaFile;
   struct CXUnsavedFile *unsaved_files = 0;
   int num_unsaved_files = 0;
   int result;
@@ -1099,6 +1210,11 @@
                            !strcmp(filter, "local-display"))? 1 : 0,
                           /* displayDiagnosics=*/0);
 
+  if ((CommentSchemaFile = parse_comments_schema(argc, argv))) {
+    argc--;
+    argv++;
+  }
+
   if (parse_remapped_files(argc, argv, 0, &unsaved_files, &num_unsaved_files)) {
     clang_disposeIndex(Idx);
     return -1;
@@ -1116,7 +1232,8 @@
     return 1;
   }
 
-  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
+  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV,
+                             CommentSchemaFile);
   free_remapped_files(unsaved_files, num_unsaved_files);
   clang_disposeIndex(Idx);
   return result;
@@ -1180,7 +1297,7 @@
       return -1;
   }
   
-  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV);
+  result = perform_test_load(Idx, TU, filter, NULL, Visitor, PV, NULL);
 
   free_remapped_files(unsaved_files, num_unsaved_files);
   clang_disposeIndex(Idx);
@@ -1200,7 +1317,7 @@
     printf("-%s", prefix);
   PrintExtent(stdout, start_line, start_col, end_line, end_col);
   printf(" ");
-  PrintCursor(cursor);
+  PrintCursor(cursor, NULL);
   printf("\n");
 }
 
@@ -1797,7 +1914,7 @@
         unsigned line, column;
         clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
         printf("%d:%d ", line, column);
-        PrintCursor(Cursor);
+        PrintCursor(Cursor, NULL);
         PrintCursorExtent(Cursor);
         Spelling = clang_getCursorSpelling(Cursor);
         cspell = clang_getCString(Spelling);
@@ -1842,7 +1959,7 @@
   if (clang_Range_isNull(range))
     return CXVisit_Continue;
 
-  PrintCursor(cursor);
+  PrintCursor(cursor, NULL);
   PrintRange(range, "");
   printf("\n");
   return CXVisit_Continue;
@@ -1926,7 +2043,7 @@
 
       if (I + 1 == Repeats) {
         CXCursorAndRangeVisitor visitor = { 0, findFileRefsVisit };
-        PrintCursor(Cursor);
+        PrintCursor(Cursor, NULL);
         printf("\n");
         clang_findReferencesInFile(Cursor, file, visitor);
         free(Locations[Loc].filename);
@@ -2124,7 +2241,7 @@
   for (i = 0; i != info->numAttributes; ++i) {
     const CXIdxAttrInfo *Attr = info->attributes[i];
     printf("     <attribute>: ");
-    PrintCursor(Attr->cursor);
+    PrintCursor(Attr->cursor, NULL);
   }
 }
 
@@ -2132,7 +2249,7 @@
                                const CXIdxBaseClassInfo *info) {
   printEntityInfo("     <base>", client_data, info->base);
   printf(" | cursor: ");
-  PrintCursor(info->cursor);
+  PrintCursor(info->cursor, NULL);
   printf(" | loc: ");
   printCXIndexLoc(info->loc, client_data);
 }
@@ -2144,7 +2261,7 @@
     printEntityInfo("     <protocol>", client_data,
                     ProtoInfo->protocols[i]->protocol);
     printf(" | cursor: ");
-    PrintCursor(ProtoInfo->protocols[i]->cursor);
+    PrintCursor(ProtoInfo->protocols[i]->cursor, NULL);
     printf(" | loc: ");
     printCXIndexLoc(ProtoInfo->protocols[i]->loc, client_data);
     printf("\n");
@@ -2234,7 +2351,7 @@
 
   printEntityInfo("[indexDeclaration]", client_data, info->entityInfo);
   printf(" | cursor: ");
-  PrintCursor(info->cursor);
+  PrintCursor(info->cursor, NULL);
   printf(" | loc: ");
   printCXIndexLoc(info->loc, client_data);
   printf(" | semantic-container: ");
@@ -2249,7 +2366,7 @@
   for (i = 0; i != info->numAttributes; ++i) {
     const CXIdxAttrInfo *Attr = info->attributes[i];
     printf("     <attribute>: ");
-    PrintCursor(Attr->cursor);
+    PrintCursor(Attr->cursor, NULL);
     printf("\n");
   }
 
@@ -2272,7 +2389,7 @@
     printEntityInfo("     <ObjCCategoryInfo>: class", client_data,
                     CatInfo->objcClass);
     printf(" | cursor: ");
-    PrintCursor(CatInfo->classCursor);
+    PrintCursor(CatInfo->classCursor, NULL);
     printf(" | loc: ");
     printCXIndexLoc(CatInfo->classLoc, client_data);
     printf("\n");
@@ -2316,7 +2433,7 @@
                                        const CXIdxEntityRefInfo *info) {
   printEntityInfo("[indexEntityReference]", client_data, info->referencedEntity);
   printf(" | cursor: ");
-  PrintCursor(info->cursor);
+  PrintCursor(info->cursor, NULL);
   printf(" | loc: ");
   printCXIndexLoc(info->loc, client_data);
   printEntityInfo(" | <parent>:", client_data, info->parentEntity);
@@ -2386,7 +2503,6 @@
     return 1;
   }
   idxAction = 0;
-  result = 1;
 
   index_data.check_prefix = check_prefix;
   index_data.first_check_printed = 0;
@@ -2586,7 +2702,7 @@
     PrintExtent(stdout, start_line, start_column, end_line, end_column);
     if (!clang_isInvalid(cursors[i].kind)) {
       printf(" ");
-      PrintCursor(cursors[i]);
+      PrintCursor(cursors[i], NULL);
     }
     printf("\n");
   }
@@ -3241,6 +3357,10 @@
 int main(int argc, const char **argv) {
   thread_info client_data;
 
+#ifdef CLANG_HAVE_LIBXML
+  LIBXML_TEST_VERSION
+#endif
+
   if (getenv("CINDEXTEST_NOTHREADS"))
     return cindextest_main(argc, argv);
 
diff --git a/tools/clang-ast-dump/CMakeLists.txt b/tools/clang-ast-dump/CMakeLists.txt
deleted file mode 100644
index 7f73341..0000000
--- a/tools/clang-ast-dump/CMakeLists.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-add_clang_executable(clang-ast-dump
-  ClangASTDump.cpp
-  )
-
-target_link_libraries(clang-ast-dump
-  clangTooling
-  clangBasic
-  )
diff --git a/tools/clang-ast-dump/ClangASTDump.cpp b/tools/clang-ast-dump/ClangASTDump.cpp
deleted file mode 100644
index 2b86fd6..0000000
--- a/tools/clang-ast-dump/ClangASTDump.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-//===- tools/clang-ast-dump/ClangASTDump.cpp - Clang AST Dump tool --------===//
-//
-//                     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 clang-ast-dump tool that dumps specified parts
-//  of an AST of a number of translation units.
-//
-//  Run with '-help' for details.
-//
-//  This tool uses the Clang Tooling infrastructure, see
-//    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
-//  for details on setting it up with LLVM source tree.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/CommandLine.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Tooling/CommandLineClangTool.h"
-#include "clang/Tooling/Tooling.h"
-
-using namespace clang::tooling;
-using namespace llvm;
-
-cl::opt<std::string> FilterString(
-  "f",
-  cl::desc("Filter string"),
-  cl::Optional);
-
-cl::opt<bool> ListAll(
-  "l",
-  cl::desc("List all filterable nodes"),
-  cl::init(false),
-  cl::Optional);
-
-static const char *MoreHelpText =
-    "-f <filter-string> can be used to dump only AST declaration nodes having\n"
-    "\ta certain substring in a qualified name.\n"
-    "\n"
-    "-l \tlists qualified names of all filterable declaration nodes.\n"
-    "\n";
-
-namespace {
-
-using namespace clang;
-
-class SelectiveDumpVisitor :
-     public RecursiveASTVisitor<SelectiveDumpVisitor> {
-  typedef RecursiveASTVisitor<SelectiveDumpVisitor> base;
-public:
-  SelectiveDumpVisitor(const std::string &FilterString, bool ListAll)
-      : FilterString(FilterString), ListAll(ListAll) {}
-
-  ASTConsumer* newASTConsumer() {
-    return new DumpConsumer(this);
-  }
-
-  bool shouldWalkTypesOfTypeLocs() const { return false; }
-
-  void Run(TranslationUnitDecl *D) {
-    if (ListAll) {
-      llvm::outs().changeColor(llvm::raw_ostream::BLUE) <<
-          "Listing all filterable nodes:\n";
-      llvm::outs().resetColor();
-      TraverseDecl(D);
-      return;
-    }
-
-    if (FilterString.empty()) {
-      llvm::outs().changeColor(llvm::raw_ostream::BLUE) <<
-          "Dumping translation unit:\n";
-      llvm::outs().resetColor();
-      D->dumpXML(llvm::outs());
-      return;
-    }
-
-    TraverseDecl(D);
-  }
-
-  bool TraverseDecl(Decl *D) {
-    if (ListAll) {
-      std::string Name = getName(D);
-      if (!Name.empty())
-        llvm::outs() << Name << "\n";
-      return base::TraverseDecl(D);
-    }
-
-    if (filterMatches(D)) {
-      llvm::outs().changeColor(llvm::raw_ostream::BLUE) <<
-          "Dumping " << getName(D) << ":\n";
-      llvm::outs().resetColor();
-      D->dumpXML(llvm::outs());
-      return true;
-    }
-    return base::TraverseDecl(D);
-  }
-
-private:
-  std::string getName(Decl *D) {
-    if (isa<NamedDecl>(D))
-      return cast<NamedDecl>(D)->getQualifiedNameAsString();
-    return "";
-  }
-  bool filterMatches(Decl *D) {
-    return getName(D).find(FilterString) != std::string::npos;
-  }
-
-  class DumpConsumer : public ASTConsumer {
-  public:
-    DumpConsumer(SelectiveDumpVisitor *Visitor) : Visitor(Visitor) {}
-
-    virtual void HandleTranslationUnit(ASTContext &Context) {
-      Visitor->Context = &Context;
-      Visitor->Run(Context.getTranslationUnitDecl());
-    }
-
-  private:
-    SelectiveDumpVisitor *Visitor;
-  };
-
-  ASTContext *Context;
-  std::string FilterString;
-  bool ListAll;
-};
-
-} // namespace
-
-int main(int argc, const char **argv) {
-  CommandLineClangTool Tool;
-  cl::extrahelp MoreHelp(MoreHelpText);
-  Tool.initialize(argc, argv);
-  SelectiveDumpVisitor Dumper(FilterString, ListAll);
-  return Tool.run(newFrontendActionFactory(&Dumper));
-}
diff --git a/tools/clang-ast-dump/Makefile b/tools/clang-ast-dump/Makefile
deleted file mode 100644
index 74a0511..0000000
--- a/tools/clang-ast-dump/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- tools/clang-check/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 := ../..
-
-TOOLNAME = clang-ast-dump
-NO_INSTALL = 1
-
-# No plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-LINK_COMPONENTS := support mc
-USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
-           clangTooling.a clangParse.a clangSema.a clangAnalysis.a \
-           clangEdit.a clangAST.a clangLex.a clangBasic.a
-
-include $(CLANG_LEVEL)/Makefile
diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
index 9db8f1a..85e229f 100644
--- a/tools/clang-check/CMakeLists.txt
+++ b/tools/clang-check/CMakeLists.txt
@@ -1,3 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
+  support
+  mc
+  )
+
 add_clang_executable(clang-check
   ClangCheck.cpp
   )
@@ -6,3 +13,6 @@
   clangTooling
   clangBasic
   )
+
+install(TARGETS clang-check
+  RUNTIME DESTINATION bin)
diff --git a/tools/clang-check/ClangCheck.cpp b/tools/clang-check/ClangCheck.cpp
index d93c48a..9e58077 100644
--- a/tools/clang-check/ClangCheck.cpp
+++ b/tools/clang-check/ClangCheck.cpp
@@ -17,10 +17,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/CommandLine.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Driver/OptTable.h"
+#include "clang/Driver/Options.h"
+#include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Tooling/CommandLineClangTool.h"
 #include "clang/Tooling/Tooling.h"
 
+using namespace clang::driver;
 using namespace clang::tooling;
 using namespace llvm;
 
@@ -38,9 +43,46 @@
     "\trules described above.\n"
     "\n";
 
+namespace {
+class ActionFactory {
+public:
+  ActionFactory()
+    : Options(createDriverOptTable()),
+      ASTDump(
+        "ast-dump",
+        cl::desc(Options->getOptionHelpText(options::OPT_ast_dump))),
+      ASTList(
+        "ast-list",
+        cl::desc(Options->getOptionHelpText(options::OPT_ast_list))),
+      ASTPrint(
+        "ast-print",
+        cl::desc(Options->getOptionHelpText(options::OPT_ast_print))),
+      ASTDumpFilter(
+        "ast-dump-filter",
+        cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter))) {}
+
+  clang::ASTConsumer *newASTConsumer() {
+    if (ASTList)
+      return clang::CreateASTDeclNodeLister();
+    if (ASTDump)
+      return clang::CreateASTDumper(ASTDumpFilter);
+    if (ASTPrint)
+      return clang::CreateASTPrinter(&llvm::outs(), ASTDumpFilter);
+    return new clang::ASTConsumer();
+  }
+private:
+  OwningPtr<OptTable> Options;
+  cl::opt<bool> ASTDump;
+  cl::opt<bool> ASTList;
+  cl::opt<bool> ASTPrint;
+  cl::opt<std::string> ASTDumpFilter;
+};
+}
+
 int main(int argc, const char **argv) {
+  ActionFactory Factory;
   CommandLineClangTool Tool;
   cl::extrahelp MoreHelp(MoreHelpText);
   Tool.initialize(argc, argv);
-  return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>());
+  return Tool.run(newFrontendActionFactory(&Factory));
 }
diff --git a/tools/clang-check/Makefile b/tools/clang-check/Makefile
index 49b1ada..6775c65 100644
--- a/tools/clang-check/Makefile
+++ b/tools/clang-check/Makefile
@@ -10,12 +10,12 @@
 CLANG_LEVEL := ../..
 
 TOOLNAME = clang-check
-NO_INSTALL = 1
 
 # No plugins, optimize startup time.
 TOOL_NO_EXPORTS = 1
 
-LINK_COMPONENTS := support mc
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangFrontend.a clangSerialization.a clangDriver.a \
            clangTooling.a clangParse.a clangSema.a clangAnalysis.a \
            clangEdit.a clangAST.a clangLex.a clangBasic.a
diff --git a/tools/diagtool/CMakeLists.txt b/tools/diagtool/CMakeLists.txt
index 77f5f38..a107cbd 100644
--- a/tools/diagtool/CMakeLists.txt
+++ b/tools/diagtool/CMakeLists.txt
@@ -1,5 +1,8 @@
-set( LLVM_LINK_COMPONENTS
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
   support
+  mc
   )
 
 add_clang_executable(diagtool
@@ -27,6 +30,3 @@
 else()
   set(CLANGXX_LINK_OR_COPY copy)
 endif()
-
-install(TARGETS diagtool 
-  RUNTIME DESTINATION bin)
diff --git a/tools/diagtool/Makefile b/tools/diagtool/Makefile
index 8af4cef..b629712 100644
--- a/tools/diagtool/Makefile
+++ b/tools/diagtool/Makefile
@@ -16,8 +16,8 @@
 # Don't install this.
 NO_INSTALL = 1
 
-LINK_COMPONENTS := support mc
-
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
            clangSema.a clangAnalysis.a clangEdit.a clangAST.a clangLex.a \
            clangBasic.a
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index b1e4bad..bd27b4c 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -5689,7 +5689,7 @@
 
   const Decl *D = getCursorDecl(C);
   ASTContext &Context = getCursorContext(C);
-  const RawComment *RC = Context.getRawCommentForDecl(D);
+  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
   if (!RC)
     return clang_getNullRange();
 
@@ -5702,7 +5702,7 @@
 
   const Decl *D = getCursorDecl(C);
   ASTContext &Context = getCursorContext(C);
-  const RawComment *RC = Context.getRawCommentForDecl(D);
+  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
   StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
                            StringRef();
 
@@ -5717,7 +5717,7 @@
 
   const Decl *D = getCursorDecl(C);
   const ASTContext &Context = getCursorContext(C);
-  const RawComment *RC = Context.getRawCommentForDecl(D);
+  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
 
   if (RC) {
     StringRef BriefText = RC->getBriefText(Context);
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 6270038..283276f 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -1,4 +1,6 @@
-set( LLVM_LINK_COMPONENTS
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
   support
   mc
   )
@@ -53,10 +55,22 @@
   clangBasic
   )
 
+set(GENERATED_HEADERS
+  ClangAttrClasses
+  ClangAttrList
+  ClangAttrParsedAttrList
+  ClangCommentNodes
+  ClangDiagnosticCommon
+  ClangDiagnosticFrontend
+  ClangDeclNodes
+  ClangStmtNodes
+  )
+
 if( LLVM_ENABLE_PIC )
   set(SHARED_LIBRARY TRUE)
   add_clang_library(libclang ${SOURCES})
   target_link_libraries(libclang ${LIBRARIES})
+  add_dependencies(libclang ${GENERATED_HEADERS})
 
   if(WIN32)
     set_target_properties(libclang
@@ -90,6 +104,7 @@
 if( NOT BUILD_SHARED_LIBS AND NOT WIN32 )
   add_clang_library(${LIBCLANG_STATIC_TARGET_NAME} STATIC ${SOURCES})
   target_link_libraries(${LIBCLANG_STATIC_TARGET_NAME} ${LIBRARIES})
+  add_dependencies(${LIBCLANG_STATIC_TARGET_NAME} ${GENERATED_HEADERS})
 
   set_target_properties(${LIBCLANG_STATIC_TARGET_NAME}
     PROPERTIES
diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp
index a671c24..c5c9ca8 100644
--- a/tools/libclang/CXComment.cpp
+++ b/tools/libclang/CXComment.cpp
@@ -14,12 +14,20 @@
 #include "clang-c/Index.h"
 #include "CXString.h"
 #include "CXComment.h"
+#include "CXCursor.h"
+#include "CXTranslationUnit.h"
 
 #include "clang/AST/CommentVisitor.h"
+#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/Frontend/ASTUnit.h"
 
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include <climits>
+
 using namespace clang;
 using namespace clang::cxstring;
 using namespace clang::comments;
@@ -57,6 +65,9 @@
   case Comment::ParamCommandCommentKind:
     return CXComment_ParamCommand;
 
+  case Comment::TParamCommandCommentKind:
+    return CXComment_TParamCommand;
+
   case Comment::VerbatimBlockCommentKind:
     return CXComment_VerbatimBlockCommand;
 
@@ -256,7 +267,7 @@
 
 unsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
   const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
-  if (!PCC)
+  if (!PCC || !PCC->isParamIndexValid())
     return ParamCommandComment::InvalidParamIndex;
 
   return PCC->getParamIndex();
@@ -289,6 +300,38 @@
   llvm_unreachable("unknown ParamCommandComment::PassDirection");
 }
 
+CXString clang_TParamCommandComment_getParamName(CXComment CXC) {
+  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
+  if (!TPCC || !TPCC->hasParamName())
+    return createCXString((const char *) 0);
+
+  return createCXString(TPCC->getParamName(), /*DupString=*/ false);
+}
+
+unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
+  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
+  if (!TPCC)
+    return false;
+
+  return TPCC->isPositionValid();
+}
+
+unsigned clang_TParamCommandComment_getDepth(CXComment CXC) {
+  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
+  if (!TPCC || !TPCC->isPositionValid())
+    return 0;
+
+  return TPCC->getDepth();
+}
+
+unsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) {
+  const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
+  if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth())
+    return 0;
+
+  return TPCC->getIndex(Depth);
+}
+
 CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
   const VerbatimBlockLineComment *VBL =
       getASTNodeAs<VerbatimBlockLineComment>(CXC);
@@ -314,16 +357,178 @@
 
 namespace {
 
+/// This comparison will sort parameters with valid index by index and
+/// invalid (unresolved) parameters last.
 class ParamCommandCommentCompareIndex {
 public:
   bool operator()(const ParamCommandComment *LHS,
                   const ParamCommandComment *RHS) const {
-    // To sort invalid (unresolved) parameters last, this comparison relies on
-    // invalid indices to be UINT_MAX.
-    return LHS->getParamIndex() < RHS->getParamIndex();
+    unsigned LHSIndex = UINT_MAX;
+    unsigned RHSIndex = UINT_MAX;
+    if (LHS->isParamIndexValid())
+      LHSIndex = LHS->getParamIndex();
+    if (RHS->isParamIndexValid())
+      RHSIndex = RHS->getParamIndex();
+
+    return LHSIndex < RHSIndex;
   }
 };
 
+/// This comparison will sort template parameters in the following order:
+/// \li real template parameters (depth = 1) in index order;
+/// \li all other names (depth > 1);
+/// \li unresolved names.
+class TParamCommandCommentComparePosition {
+public:
+  bool operator()(const TParamCommandComment *LHS,
+                  const TParamCommandComment *RHS) const {
+    // Sort unresolved names last.
+    if (!LHS->isPositionValid())
+      return false;
+    if (!RHS->isPositionValid())
+      return true;
+
+    if (LHS->getDepth() > 1)
+      return false;
+    if (RHS->getDepth() > 1)
+      return true;
+
+    // Sort template parameters in index order.
+    if (LHS->getDepth() == 1 && RHS->getDepth() == 1)
+      return LHS->getIndex(0) < RHS->getIndex(0);
+
+    // Leave all other names in source order.
+    return true;
+  }
+};
+
+/// Separate parts of a FullComment.
+struct FullCommentParts {
+  /// Take a full comment apart and initialize members accordingly.
+  FullCommentParts(const FullComment *C);
+
+  const BlockContentComment *Brief;
+  const ParagraphComment *FirstParagraph;
+  const BlockCommandComment *Returns;
+  SmallVector<const ParamCommandComment *, 8> Params;
+  SmallVector<const TParamCommandComment *, 4> TParams;
+  SmallVector<const BlockContentComment *, 8> MiscBlocks;
+};
+
+FullCommentParts::FullCommentParts(const FullComment *C) :
+    Brief(NULL), FirstParagraph(NULL), Returns(NULL) {
+  const CommandTraits Traits;
+  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
+       I != E; ++I) {
+    const Comment *Child = *I;
+    if (!Child)
+      continue;
+    switch (Child->getCommentKind()) {
+    case Comment::NoCommentKind:
+      continue;
+
+    case Comment::ParagraphCommentKind: {
+      const ParagraphComment *PC = cast<ParagraphComment>(Child);
+      if (PC->isWhitespace())
+        break;
+      if (!FirstParagraph)
+        FirstParagraph = PC;
+
+      MiscBlocks.push_back(PC);
+      break;
+    }
+
+    case Comment::BlockCommandCommentKind: {
+      const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
+      StringRef CommandName = BCC->getCommandName();
+      if (!Brief && Traits.isBriefCommand(CommandName)) {
+        Brief = BCC;
+        break;
+      }
+      if (!Returns && Traits.isReturnsCommand(CommandName)) {
+        Returns = BCC;
+        break;
+      }
+      MiscBlocks.push_back(BCC);
+      break;
+    }
+
+    case Comment::ParamCommandCommentKind: {
+      const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
+      if (!PCC->hasParamName())
+        break;
+
+      if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
+        break;
+
+      Params.push_back(PCC);
+      break;
+    }
+
+    case Comment::TParamCommandCommentKind: {
+      const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
+      if (!TPCC->hasParamName())
+        break;
+
+      if (!TPCC->hasNonWhitespaceParagraph())
+        break;
+
+      TParams.push_back(TPCC);
+      break;
+    }
+
+    case Comment::VerbatimBlockCommentKind:
+      MiscBlocks.push_back(cast<BlockCommandComment>(Child));
+      break;
+
+    case Comment::VerbatimLineCommentKind: {
+      const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child);
+      if (!Traits.isDeclarationCommand(VLC->getCommandName()))
+        MiscBlocks.push_back(VLC);
+      break;
+    }
+
+    case Comment::TextCommentKind:
+    case Comment::InlineCommandCommentKind:
+    case Comment::HTMLStartTagCommentKind:
+    case Comment::HTMLEndTagCommentKind:
+    case Comment::VerbatimBlockLineCommentKind:
+    case Comment::FullCommentKind:
+      llvm_unreachable("AST node of this kind can't be a child of "
+                       "a FullComment");
+    }
+  }
+
+  // Sort params in order they are declared in the function prototype.
+  // Unresolved parameters are put at the end of the list in the same order
+  // they were seen in the comment.
+  std::stable_sort(Params.begin(), Params.end(),
+                   ParamCommandCommentCompareIndex());
+
+  std::stable_sort(TParams.begin(), TParams.end(),
+                   TParamCommandCommentComparePosition());
+}
+
+void PrintHTMLStartTagComment(const HTMLStartTagComment *C,
+                              llvm::raw_svector_ostream &Result) {
+  Result << "<" << C->getTagName();
+
+  if (C->getNumAttrs() != 0) {
+    for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
+      Result << " ";
+      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
+      Result << Attr.Name;
+      if (!Attr.Value.empty())
+        Result << "=\"" << Attr.Value << "\"";
+    }
+  }
+
+  if (!C->isSelfClosing())
+    Result << ">";
+  else
+    Result << "/>";
+}
+
 class CommentASTToHTMLConverter :
     public ConstCommentVisitor<CommentASTToHTMLConverter> {
 public:
@@ -340,6 +545,7 @@
   void visitParagraphComment(const ParagraphComment *C);
   void visitBlockCommandComment(const BlockCommandComment *C);
   void visitParamCommandComment(const ParamCommandComment *C);
+  void visitTParamCommandComment(const TParamCommandComment *C);
   void visitVerbatimBlockComment(const VerbatimBlockComment *C);
   void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
   void visitVerbatimLineComment(const VerbatimLineComment *C);
@@ -355,6 +561,8 @@
   void appendToResultWithHTMLEscaping(StringRef S);
 
 private:
+  const CommandTraits Traits;
+
   /// Output stream for HTML.
   llvm::raw_svector_ostream Result;
 };
@@ -377,43 +585,36 @@
 
   switch (C->getRenderKind()) {
   case InlineCommandComment::RenderNormal:
-    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
-      Result << C->getArgText(i) << " ";
+    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
+      appendToResultWithHTMLEscaping(C->getArgText(i));
+      Result << " ";
+    }
     return;
 
   case InlineCommandComment::RenderBold:
     assert(C->getNumArgs() == 1);
-    Result << "<b>" << Arg0 << "</b>";
+    Result << "<b>";
+    appendToResultWithHTMLEscaping(Arg0);
+    Result << "</b>";
     return;
   case InlineCommandComment::RenderMonospaced:
     assert(C->getNumArgs() == 1);
-    Result << "<tt>" << Arg0 << "</tt>";
+    Result << "<tt>";
+    appendToResultWithHTMLEscaping(Arg0);
+    Result<< "</tt>";
     return;
   case InlineCommandComment::RenderEmphasized:
     assert(C->getNumArgs() == 1);
-    Result << "<em>" << Arg0 << "</em>";
+    Result << "<em>";
+    appendToResultWithHTMLEscaping(Arg0);
+    Result << "</em>";
     return;
   }
 }
 
 void CommentASTToHTMLConverter::visitHTMLStartTagComment(
                                   const HTMLStartTagComment *C) {
-  Result << "<" << C->getTagName();
-
-  if (C->getNumAttrs() != 0) {
-    for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
-      Result << " ";
-      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
-      Result << Attr.Name;
-      if (!Attr.Value.empty())
-        Result << "=\"" << Attr.Value << "\"";
-    }
-  }
-
-  if (!C->isSelfClosing())
-    Result << ">";
-  else
-    Result << "/>";
+  PrintHTMLStartTagComment(C, Result);
 }
 
 void CommentASTToHTMLConverter::visitHTMLEndTagComment(
@@ -437,13 +638,13 @@
 void CommentASTToHTMLConverter::visitBlockCommandComment(
                                   const BlockCommandComment *C) {
   StringRef CommandName = C->getCommandName();
-  if (CommandName == "brief" || CommandName == "short") {
+  if (Traits.isBriefCommand(CommandName)) {
     Result << "<p class=\"para-brief\">";
     visitNonStandaloneParagraphComment(C->getParagraph());
     Result << "</p>";
     return;
   }
-  if (CommandName == "returns" || CommandName == "return") {
+  if (Traits.isReturnsCommand(CommandName)) {
     Result << "<p class=\"para-returns\">"
               "<span class=\"word-returns\">Returns</span> ";
     visitNonStandaloneParagraphComment(C->getParagraph());
@@ -463,7 +664,8 @@
   } else
     Result << "<dt class=\"param-name-index-invalid\">";
 
-  Result << C->getParamName() << "</dt>";
+  appendToResultWithHTMLEscaping(C->getParamName());
+  Result << "</dt>";
 
   if (C->isParamIndexValid()) {
     Result << "<dd class=\"param-descr-index-"
@@ -476,6 +678,35 @@
   Result << "</dd>";
 }
 
+void CommentASTToHTMLConverter::visitTParamCommandComment(
+                                  const TParamCommandComment *C) {
+  if (C->isPositionValid()) {
+    if (C->getDepth() == 1)
+      Result << "<dt class=\"tparam-name-index-"
+             << C->getIndex(0)
+             << "\">";
+    else
+      Result << "<dt class=\"tparam-name-index-other\">";
+  } else
+    Result << "<dt class=\"tparam-name-index-invalid\">";
+
+  appendToResultWithHTMLEscaping(C->getParamName());
+  Result << "</dt>";
+
+  if (C->isPositionValid()) {
+    if (C->getDepth() == 1)
+      Result << "<dd class=\"tparam-descr-index-"
+             << C->getIndex(0)
+             << "\">";
+    else
+      Result << "<dd class=\"tparam-descr-index-other\">";
+  } else
+    Result << "<dd class=\"tparam-descr-index-invalid\">";
+
+  visitNonStandaloneParagraphComment(C->getParagraph());
+  Result << "</dd>";
+}
+
 void CommentASTToHTMLConverter::visitVerbatimBlockComment(
                                   const VerbatimBlockComment *C) {
   unsigned NumLines = C->getNumLines();
@@ -504,108 +735,41 @@
 }
 
 void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
-  const BlockContentComment *Brief = NULL;
-  const ParagraphComment *FirstParagraph = NULL;
-  const BlockCommandComment *Returns = NULL;
-  SmallVector<const ParamCommandComment *, 8> Params;
-  SmallVector<const BlockContentComment *, 8> MiscBlocks;
-
-  // Extract various blocks into separate variables and vectors above.
-  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
-       I != E; ++I) {
-    const Comment *Child = *I;
-    if (!Child)
-      continue;
-    switch (Child->getCommentKind()) {
-    case Comment::NoCommentKind:
-      continue;
-
-    case Comment::ParagraphCommentKind: {
-      const ParagraphComment *PC = cast<ParagraphComment>(Child);
-      if (PC->isWhitespace())
-        break;
-      if (!FirstParagraph)
-        FirstParagraph = PC;
-
-      MiscBlocks.push_back(PC);
-      break;
-    }
-
-    case Comment::BlockCommandCommentKind: {
-      const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
-      StringRef CommandName = BCC->getCommandName();
-      if (!Brief && (CommandName == "brief" || CommandName == "short")) {
-        Brief = BCC;
-        break;
-      }
-      if (!Returns && (CommandName == "returns" || CommandName == "return")) {
-        Returns = BCC;
-        break;
-      }
-      MiscBlocks.push_back(BCC);
-      break;
-    }
-
-    case Comment::ParamCommandCommentKind: {
-      const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
-      if (!PCC->hasParamName())
-        break;
-
-      if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
-        break;
-
-      Params.push_back(PCC);
-      break;
-    }
-
-    case Comment::VerbatimBlockCommentKind:
-    case Comment::VerbatimLineCommentKind:
-      MiscBlocks.push_back(cast<BlockCommandComment>(Child));
-      break;
-
-    case Comment::TextCommentKind:
-    case Comment::InlineCommandCommentKind:
-    case Comment::HTMLStartTagCommentKind:
-    case Comment::HTMLEndTagCommentKind:
-    case Comment::VerbatimBlockLineCommentKind:
-    case Comment::FullCommentKind:
-      llvm_unreachable("AST node of this kind can't be a child of "
-                       "a FullComment");
-    }
-  }
-
-  // Sort params in order they are declared in the function prototype.
-  // Unresolved parameters are put at the end of the list in the same order
-  // they were seen in the comment.
-  std::stable_sort(Params.begin(), Params.end(),
-                   ParamCommandCommentCompareIndex());
+  FullCommentParts Parts(C);
 
   bool FirstParagraphIsBrief = false;
-  if (Brief)
-    visit(Brief);
-  else if (FirstParagraph) {
+  if (Parts.Brief)
+    visit(Parts.Brief);
+  else if (Parts.FirstParagraph) {
     Result << "<p class=\"para-brief\">";
-    visitNonStandaloneParagraphComment(FirstParagraph);
+    visitNonStandaloneParagraphComment(Parts.FirstParagraph);
     Result << "</p>";
     FirstParagraphIsBrief = true;
   }
 
-  for (unsigned i = 0, e = MiscBlocks.size(); i != e; ++i) {
-    const Comment *C = MiscBlocks[i];
-    if (FirstParagraphIsBrief && C == FirstParagraph)
+  for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
+    const Comment *C = Parts.MiscBlocks[i];
+    if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
       continue;
     visit(C);
   }
 
-  if (Params.size() != 0) {
+  if (Parts.TParams.size() != 0) {
     Result << "<dl>";
-    for (unsigned i = 0, e = Params.size(); i != e; ++i)
-      visit(Params[i]);
+    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
+      visit(Parts.TParams[i]);
     Result << "</dl>";
   }
 
-  if (Returns)
-    visit(Returns);
+  if (Parts.Params.size() != 0) {
+    Result << "<dl>";
+    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
+      visit(Parts.Params[i]);
+    Result << "</dl>";
+  }
+
+  if (Parts.Returns)
+    visit(Parts.Returns);
 
   Result.flush();
 }
@@ -676,3 +840,391 @@
 
 } // end extern "C"
 
+namespace {
+class CommentASTToXMLConverter :
+    public ConstCommentVisitor<CommentASTToXMLConverter> {
+public:
+  /// \param Str accumulator for XML.
+  CommentASTToXMLConverter(const SourceManager &SM,
+                           SmallVectorImpl<char> &Str) :
+    SM(SM), Result(Str) { }
+
+  // Inline content.
+  void visitTextComment(const TextComment *C);
+  void visitInlineCommandComment(const InlineCommandComment *C);
+  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
+  void visitHTMLEndTagComment(const HTMLEndTagComment *C);
+
+  // Block content.
+  void visitParagraphComment(const ParagraphComment *C);
+  void visitBlockCommandComment(const BlockCommandComment *C);
+  void visitParamCommandComment(const ParamCommandComment *C);
+  void visitTParamCommandComment(const TParamCommandComment *C);
+  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
+  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
+  void visitVerbatimLineComment(const VerbatimLineComment *C);
+
+  void visitFullComment(const FullComment *C);
+
+  // Helpers.
+  void appendToResultWithXMLEscaping(StringRef S);
+
+private:
+  const SourceManager &SM;
+
+  /// Output stream for XML.
+  llvm::raw_svector_ostream Result;
+};
+} // end unnamed namespace
+
+void CommentASTToXMLConverter::visitTextComment(const TextComment *C) {
+  appendToResultWithXMLEscaping(C->getText());
+}
+
+void CommentASTToXMLConverter::visitInlineCommandComment(const InlineCommandComment *C) {
+  // Nothing to render if no arguments supplied.
+  if (C->getNumArgs() == 0)
+    return;
+
+  // Nothing to render if argument is empty.
+  StringRef Arg0 = C->getArgText(0);
+  if (Arg0.empty())
+    return;
+
+  switch (C->getRenderKind()) {
+  case InlineCommandComment::RenderNormal:
+    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
+      appendToResultWithXMLEscaping(C->getArgText(i));
+      Result << " ";
+    }
+    return;
+  case InlineCommandComment::RenderBold:
+    assert(C->getNumArgs() == 1);
+    Result << "<bold>";
+    appendToResultWithXMLEscaping(Arg0);
+    Result << "</bold>";
+    return;
+  case InlineCommandComment::RenderMonospaced:
+    assert(C->getNumArgs() == 1);
+    Result << "<monospaced>";
+    appendToResultWithXMLEscaping(Arg0);
+    Result << "</monospaced>";
+    return;
+  case InlineCommandComment::RenderEmphasized:
+    assert(C->getNumArgs() == 1);
+    Result << "<emphasized>";
+    appendToResultWithXMLEscaping(Arg0);
+    Result << "</emphasized>";
+    return;
+  }
+}
+
+void CommentASTToXMLConverter::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
+  Result << "<rawHTML><![CDATA[";
+  PrintHTMLStartTagComment(C, Result);
+  Result << "]]></rawHTML>";
+}
+
+void CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
+  Result << "<rawHTML>&lt;/" << C->getTagName() << "&gt;</rawHTML>";
+}
+
+void CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
+  if (C->isWhitespace())
+    return;
+
+  Result << "<Para>";
+  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
+       I != E; ++I) {
+    visit(*I);
+  }
+  Result << "</Para>";
+}
+
+void CommentASTToXMLConverter::visitBlockCommandComment(const BlockCommandComment *C) {
+  visit(C->getParagraph());
+}
+
+void CommentASTToXMLConverter::visitParamCommandComment(const ParamCommandComment *C) {
+  Result << "<Parameter><Name>";
+  appendToResultWithXMLEscaping(C->getParamName());
+  Result << "</Name>";
+
+  if (C->isParamIndexValid())
+    Result << "<Index>" << C->getParamIndex() << "</Index>";
+
+  Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">";
+  switch (C->getDirection()) {
+  case ParamCommandComment::In:
+    Result << "in";
+    break;
+  case ParamCommandComment::Out:
+    Result << "out";
+    break;
+  case ParamCommandComment::InOut:
+    Result << "in,out";
+    break;
+  }
+  Result << "</Direction><Discussion>";
+  visit(C->getParagraph());
+  Result << "</Discussion></Parameter>";
+}
+
+void CommentASTToXMLConverter::visitTParamCommandComment(
+                                  const TParamCommandComment *C) {
+  Result << "<Parameter><Name>";
+  appendToResultWithXMLEscaping(C->getParamName());
+  Result << "</Name>";
+
+  if (C->isPositionValid() && C->getDepth() == 1) {
+    Result << "<Index>" << C->getIndex(0) << "</Index>";
+  }
+
+  Result << "<Discussion>";
+  visit(C->getParagraph());
+  Result << "</Discussion></Parameter>";
+}
+
+void CommentASTToXMLConverter::visitVerbatimBlockComment(
+                                  const VerbatimBlockComment *C) {
+  unsigned NumLines = C->getNumLines();
+  if (NumLines == 0)
+    return;
+
+  Result << llvm::StringSwitch<const char *>(C->getCommandName())
+      .Case("code", "<Verbatim xml:space=\"preserve\" kind=\"code\">")
+      .Default("<Verbatim xml:space=\"preserve\" kind=\"verbatim\">");
+  for (unsigned i = 0; i != NumLines; ++i) {
+    appendToResultWithXMLEscaping(C->getText(i));
+    if (i + 1 != NumLines)
+      Result << '\n';
+  }
+  Result << "</Verbatim>";
+}
+
+void CommentASTToXMLConverter::visitVerbatimBlockLineComment(
+                                  const VerbatimBlockLineComment *C) {
+  llvm_unreachable("should not see this AST node");
+}
+
+void CommentASTToXMLConverter::visitVerbatimLineComment(
+                                  const VerbatimLineComment *C) {
+  Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
+  appendToResultWithXMLEscaping(C->getText());
+  Result << "</Verbatim>";
+}
+
+void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
+  FullCommentParts Parts(C);
+
+  const DeclInfo *DI = C->getDeclInfo();
+  StringRef RootEndTag;
+  if (DI) {
+    switch (DI->getKind()) {
+    case DeclInfo::OtherKind:
+      RootEndTag = "</Other>";
+      Result << "<Other";
+      break;
+    case DeclInfo::FunctionKind:
+      RootEndTag = "</Function>";
+      Result << "<Function";
+      switch (DI->TemplateKind) {
+      case DeclInfo::NotTemplate:
+        break;
+      case DeclInfo::Template:
+        Result << " templateKind=\"template\"";
+        break;
+      case DeclInfo::TemplateSpecialization:
+        Result << " templateKind=\"specialization\"";
+        break;
+      case DeclInfo::TemplatePartialSpecialization:
+        llvm_unreachable("partial specializations of functions "
+                         "are not allowed in C++");
+      }
+      if (DI->IsInstanceMethod)
+        Result << " isInstanceMethod=\"1\"";
+      if (DI->IsClassMethod)
+        Result << " isClassMethod=\"1\"";
+      break;
+    case DeclInfo::ClassKind:
+      RootEndTag = "</Class>";
+      Result << "<Class";
+      switch (DI->TemplateKind) {
+      case DeclInfo::NotTemplate:
+        break;
+      case DeclInfo::Template:
+        Result << " templateKind=\"template\"";
+        break;
+      case DeclInfo::TemplateSpecialization:
+        Result << " templateKind=\"specialization\"";
+        break;
+      case DeclInfo::TemplatePartialSpecialization:
+        Result << " templateKind=\"partialSpecialization\"";
+        break;
+      }
+      break;
+    case DeclInfo::VariableKind:
+      RootEndTag = "</Variable>";
+      Result << "<Variable";
+      break;
+    case DeclInfo::NamespaceKind:
+      RootEndTag = "</Namespace>";
+      Result << "<Namespace";
+      break;
+    case DeclInfo::TypedefKind:
+      RootEndTag = "</Typedef>";
+      Result << "<Typedef";
+      break;
+    case DeclInfo::EnumKind:
+      RootEndTag = "</Enum>";
+      Result << "<Enum";
+      break;
+    }
+
+    {
+      // Print line and column number.
+      SourceLocation Loc = DI->ThisDecl->getLocation();
+      std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+      FileID FID = LocInfo.first;
+      unsigned FileOffset = LocInfo.second;
+
+      if (!FID.isInvalid()) {
+        if (const FileEntry *FE = SM.getFileEntryForID(FID)) {
+          Result << " file=\"";
+          appendToResultWithXMLEscaping(FE->getName());
+          Result << "\"";
+        }
+        Result << " line=\"" << SM.getLineNumber(FID, FileOffset)
+               << "\" column=\"" << SM.getColumnNumber(FID, FileOffset)
+               << "\"";
+      }
+    }
+
+    // Finish the root tag.
+    Result << ">";
+
+    bool FoundName = false;
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->ThisDecl)) {
+      if (DeclarationName DeclName = ND->getDeclName()) {
+        Result << "<Name>";
+        std::string Name = DeclName.getAsString();
+        appendToResultWithXMLEscaping(Name);
+        FoundName = true;
+        Result << "</Name>";
+      }
+    }
+    if (!FoundName)
+      Result << "<Name>&lt;anonymous&gt;</Name>";
+
+    {
+      // Print USR.
+      SmallString<128> USR;
+      cxcursor::getDeclCursorUSR(DI->ThisDecl, USR);
+      if (!USR.empty()) {
+        Result << "<USR>";
+        appendToResultWithXMLEscaping(USR);
+        Result << "</USR>";
+      }
+    }
+  } else {
+    // No DeclInfo -- just emit some root tag and name tag.
+    RootEndTag = "</Other>";
+    Result << "<Other><Name>unknown</Name>";
+  }
+
+  bool FirstParagraphIsBrief = false;
+  if (Parts.Brief) {
+    Result << "<Abstract>";
+    visit(Parts.Brief);
+    Result << "</Abstract>";
+  } else if (Parts.FirstParagraph) {
+    Result << "<Abstract>";
+    visit(Parts.FirstParagraph);
+    Result << "</Abstract>";
+    FirstParagraphIsBrief = true;
+  }
+
+  if (Parts.TParams.size() != 0) {
+    Result << "<TemplateParameters>";
+    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
+      visit(Parts.TParams[i]);
+    Result << "</TemplateParameters>";
+  }
+
+  if (Parts.Params.size() != 0) {
+    Result << "<Parameters>";
+    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
+      visit(Parts.Params[i]);
+    Result << "</Parameters>";
+  }
+
+  if (Parts.Returns) {
+    Result << "<ResultDiscussion>";
+    visit(Parts.Returns);
+    Result << "</ResultDiscussion>";
+  }
+
+  {
+    bool StartTagEmitted = false;
+    for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
+      const Comment *C = Parts.MiscBlocks[i];
+      if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
+        continue;
+      if (!StartTagEmitted) {
+        Result << "<Discussion>";
+        StartTagEmitted = true;
+      }
+      visit(C);
+    }
+    if (StartTagEmitted)
+      Result << "</Discussion>";
+  }
+
+  Result << RootEndTag;
+
+  Result.flush();
+}
+
+void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) {
+  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
+    const char C = *I;
+    switch (C) {
+      case '&':
+        Result << "&amp;";
+        break;
+      case '<':
+        Result << "&lt;";
+        break;
+      case '>':
+        Result << "&gt;";
+        break;
+      case '"':
+        Result << "&quot;";
+        break;
+      case '\'':
+        Result << "&apos;";
+        break;
+      default:
+        Result << C;
+        break;
+    }
+  }
+}
+
+extern "C" {
+
+CXString clang_FullComment_getAsXML(CXTranslationUnit TU, CXComment CXC) {
+  const FullComment *FC = getASTNodeAs<FullComment>(CXC);
+  if (!FC)
+    return createCXString((const char *) 0);
+
+  SourceManager &SM = static_cast<ASTUnit *>(TU->TUData)->getSourceManager();
+
+  SmallString<1024> XML;
+  CommentASTToXMLConverter Converter(SM, XML);
+  Converter.visit(FC);
+  return createCXString(XML.str(), /* DupString = */ true);
+}
+
+} // end extern "C"
+
diff --git a/tools/libclang/Makefile b/tools/libclang/Makefile
index 3f6774b..975d381 100644
--- a/tools/libclang/Makefile
+++ b/tools/libclang/Makefile
@@ -15,7 +15,8 @@
 LINK_LIBS_IN_SHARED = 1
 SHARED_LIBRARY = 1
 
-LINK_COMPONENTS := support mc
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangARCMigrate.a clangRewrite.a clangFrontend.a clangDriver.a \
      clangSerialization.a \
 		 clangParse.a clangSema.a clangEdit.a clangAnalysis.a \
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index bc8c113..610bd91 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -42,10 +42,15 @@
 clang_ParamCommandComment_getParamIndex
 clang_ParamCommandComment_isDirectionExplicit
 clang_ParamCommandComment_getDirection
+clang_TParamCommandComment_getParamName
+clang_TParamCommandComment_isParamPositionValid
+clang_TParamCommandComment_getDepth
+clang_TParamCommandComment_getIndex
 clang_VerbatimBlockLineComment_getText
 clang_VerbatimLineComment_getText
 clang_HTMLTagComment_getAsString
 clang_FullComment_getAsHTML
+clang_FullComment_getAsXML
 clang_annotateTokens
 clang_codeCompleteAt
 clang_codeCompleteGetContainerKind
diff --git a/tools/scan-build/ccc-analyzer b/tools/scan-build/ccc-analyzer
index b8f7193..c7636f9 100755
--- a/tools/scan-build/ccc-analyzer
+++ b/tools/scan-build/ccc-analyzer
@@ -347,6 +347,8 @@
 my %CompilerLinkerOptionMap = (
   '-fobjc-arc' => 0,
   '-fobjc-abi-version' => 0, # This is really a 1 argument, but always has '='
+  '-fobjc-legacy-dispatch' => 0,
+  '-mios-simulator-version-min' => 0, # This really has 1 argument, but always has '='
   '-isysroot' => 1,
   '-arch' => 1,
   '-m32' => 0,
diff --git a/tools/scan-build/scan-build b/tools/scan-build/scan-build
index 424e15a..65c4893 100755
--- a/tools/scan-build/scan-build
+++ b/tools/scan-build/scan-build
@@ -113,7 +113,9 @@
 else {
   $Clang = $ClangSB;
 }
-my $ClangCXX = $Clang . "++";
+my $ClangCXX = $Clang;
+$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX .= "++";
 my $ClangVersion = HtmlEscape(`$Clang --version`);
 
 ##----------------------------------------------------------------------------##
@@ -866,19 +868,87 @@
   }
 }
 
-sub RunBuildCommand {
+sub SetEnv {
+  my $Options = shift @_;
+  foreach my $opt ('CC', 'CXX', 'CLANG', 'CLANG_CXX',
+                    'CCC_ANALYZER_ANALYSIS', 'CCC_ANALYZER_PLUGINS') {
+    die "$opt is undefined\n" if (!defined $opt);
+    $ENV{$opt} = $Options->{$opt};
+  }
+  foreach my $opt ('CCC_ANALYZER_STORE_MODEL',
+                    'CCC_ANALYZER_PLUGINS',
+                    'CCC_ANALYZER_INTERNAL_STATS',
+                    'CCC_ANALYZER_OUTPUT_FORMAT') {
+    my $x = $Options->{$opt};
+    if (defined $x) { $ENV{$opt} = $x }
+  }
+  my $Verbose = $Options->{'VERBOSE'};
+  if ($Verbose >= 2) {
+    $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
+  }
+  if ($Verbose >= 3) {
+    $ENV{'CCC_ANALYZER_LOG'} = 1;
+  }
+}
+
+sub RunXcodebuild {
+  my $Args = shift;
+  my $IgnoreErrors = shift;
+  my $CCAnalyzer = shift;
+  my $CXXAnalyzer = shift;
+  my $Options = shift;
+
+  if ($IgnoreErrors) {
+    AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
+  }
   
+  # Default to old behavior where we insert a bogus compiler.
+  SetEnv($Options);
+  
+  # Check if using iPhone SDK 3.0 (simulator).  If so the compiler being
+  # used should be gcc-4.2.
+  if (!defined $ENV{"CCC_CC"}) {
+    for (my $i = 0 ; $i < scalar(@$Args); ++$i) {
+      if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
+        if (@$Args[$i+1] =~ /^iphonesimulator3/) {
+          $ENV{"CCC_CC"} = "gcc-4.2";
+          $ENV{"CCC_CXX"} = "g++-4.2";
+        }
+      }
+    }
+  }
+
+  # Disable PCH files until clang supports them.
+  AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
+  
+  # When 'CC' is set, xcodebuild uses it to do all linking, even if we are
+  # linking C++ object files.  Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
+  # (via c++-analyzer) when linking such files.
+  $ENV{"LDPLUSPLUS"} = $CXXAnalyzer;
+ 
+  return (system(@$Args) >> 8); 
+}
+
+sub RunBuildCommand {  
   my $Args = shift;
   my $IgnoreErrors = shift;
   my $Cmd = $Args->[0];
   my $CCAnalyzer = shift;
   my $CXXAnalyzer = shift;
+  my $Options = shift;
   
   # Get only the part of the command after the last '/'.
   if ($Cmd =~ /\/([^\/]+)$/) {
     $Cmd = $1;
   }
   
+  if ($Cmd eq "xcodebuild") {
+    return RunXcodebuild($Args, $IgnoreErrors, $CCAnalyzer, $CXXAnalyzer, $Options);
+  }
+  
+  # Setup the environment.
+  SetEnv($Options);
+  
   if ($Cmd =~ /(.*\/?gcc[^\/]*$)/ or 
       $Cmd =~ /(.*\/?cc[^\/]*$)/ or
       $Cmd =~ /(.*\/?llvm-gcc[^\/]*$)/ or
@@ -910,34 +980,8 @@
       AddIfNotPresent($Args,"-k");
       AddIfNotPresent($Args,"-i");
     }
-    elsif ($Cmd eq "xcodebuild") {
-      AddIfNotPresent($Args,"-PBXBuildsContinueAfterErrors=YES");
-    }
   } 
-  
-  if ($Cmd eq "xcodebuild") {
-    # Check if using iPhone SDK 3.0 (simulator).  If so the compiler being
-    # used should be gcc-4.2.
-    if (!defined $ENV{"CCC_CC"}) {
-      for (my $i = 0 ; $i < scalar(@$Args); ++$i) {
-        if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
-          if (@$Args[$i+1] =~ /^iphonesimulator3/) {
-            $ENV{"CCC_CC"} = "gcc-4.2";
-            $ENV{"CCC_CXX"} = "g++-4.2";            
-          }
-        }
-      }
-    }
 
-    # Disable PCH files until clang supports them.
-    AddIfNotPresent($Args,"GCC_PRECOMPILE_PREFIX_HEADER=NO");
-    
-    # When 'CC' is set, xcodebuild uses it to do all linking, even if we are
-    # linking C++ object files.  Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
-    # (via c++-analyzer) when linking such files.
-    $ENV{"LDPLUSPLUS"} = $CXXAnalyzer;
-  }
-  
   return (system(@$Args) >> 8);
 }
 
@@ -1418,47 +1462,42 @@
   Diag("Using 'clang' from path: $Clang\n");
 }
 
-# Set the appropriate environment variables.
 SetHtmlEnv(\@ARGV, $HtmlDir);
-$ENV{'CC'} = $Cmd;
-$ENV{'CXX'} = $CmdCXX;
-$ENV{'CLANG'} = $Clang;
-$ENV{'CLANG_CXX'} = $ClangCXX;
-if ($Verbose >= 2) {
-  $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
-}
-if ($Verbose >= 3) {
-  $ENV{'CCC_ANALYZER_LOG'} = 1;
-}
-if ($AnalyzeHeaders) {
-  push @AnalysesToRun,"-analyzer-opt-analyze-headers";  
-}
-if ($AnalyzerStats) {
-  push @AnalysesToRun, '-analyzer-checker', 'debug.Stats';
-}
-if ($MaxLoop > 0) {
-  push @AnalysesToRun, '-analyzer-max-loop ' . $MaxLoop;
-}
+if ($AnalyzeHeaders) { push @AnalysesToRun,"-analyzer-opt-analyze-headers"; }
+if ($AnalyzerStats) { push @AnalysesToRun, '-analyzer-checker=debug.Stats'; }
+if ($MaxLoop > 0) { push @AnalysesToRun, '-analyzer-max-loop=$MaxLoop'; }
 
-$ENV{'CCC_ANALYZER_ANALYSIS'} = join ' ',@AnalysesToRun;
-
-$ENV{'CCC_ANALYZER_PLUGINS'} = join ' ',@PluginsToLoad;
+# Delay setting up other environment variables in case we can do true
+# interposition.
+my $CCC_ANALYZER_ANALYSIS = join ' ',@AnalysesToRun;
+my $CCC_ANALYZER_PLUGINS = join ' ',@PluginsToLoad;
+my %Options = (
+  'CC' => $Cmd,
+  'CXX' => $CmdCXX,
+  'CLANG' => $Clang,
+  'CLANG_CXX' => $ClangCXX,
+  'VERBOSE' => $Verbose,
+  'CCC_ANALYZER_ANALYSIS' => $CCC_ANALYZER_ANALYSIS,
+  'CCC_ANALYZER_PLUGINS' => $CCC_ANALYZER_PLUGINS,
+  'OUTPUT_DIR' => $HtmlDir
+);
 
 if (defined $StoreModel) {
-  $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel;
+  $Options{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel;
 }
 if (defined $ConstraintsModel) {
-  $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel;
+  $Options{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel;
 }
 if (defined $InternalStats) {
-  $ENV{'CCC_ANALYZER_INTERNAL_STATS'} = 1;
+  $Options{'CCC_ANALYZER_INTERNAL_STATS'} = 1;
 }
 if (defined $OutputFormat) {
-  $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat;
+  $Options{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat;
 }
 
 # Run the build.
-my $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX);
+my $ExitStatus = RunBuildCommand(\@ARGV, $IgnoreErrors, $Cmd, $CmdCXX,
+                                \%Options);
 
 if (defined $OutputFormat) {
   if ($OutputFormat =~ /plist/) {
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index 63418a2..a4f3401 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -1,8 +1,9 @@
 add_clang_unittest(ASTTests
   CommentLexer.cpp
   CommentParser.cpp
+  DeclPrinterTest.cpp
   )
 
 target_link_libraries(ASTTests
-  clangAST
+  clangAST clangASTMatchers clangTooling
   )
diff --git a/unittests/AST/CommentLexer.cpp b/unittests/AST/CommentLexer.cpp
index dd92df4..cab0fdd 100644
--- a/unittests/AST/CommentLexer.cpp
+++ b/unittests/AST/CommentLexer.cpp
@@ -11,6 +11,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/AST/CommentLexer.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/STLExtras.h"
 #include <vector>
 
@@ -37,6 +38,7 @@
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
   DiagnosticsEngine Diags;
   SourceManager SourceMgr;
+  llvm::BumpPtrAllocator Allocator;
 
   void lexString(const char *Source, std::vector<Token> &Toks);
 };
@@ -47,7 +49,8 @@
   FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
-  comments::Lexer L(Begin, CommentOptions(),
+  comments::CommandTraits Traits;
+  comments::Lexer L(Allocator, Traits, Begin, CommentOptions(),
                     Source, Source + strlen(Source));
 
   while (1) {
@@ -1272,6 +1275,324 @@
   }
 }
 
+TEST_F(CommentLexerTest, HTMLCharacterReferences1) {
+  const char *Source = "// &";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&"),    Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences2) {
+  const char *Source = "// &!";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&"),    Toks[1].getText());
+
+  ASSERT_EQ(tok::text,         Toks[2].getKind());
+  ASSERT_EQ(StringRef("!"),    Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences3) {
+  const char *Source = "// &amp";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&amp"), Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences4) {
+  const char *Source = "// &amp!";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&amp"), Toks[1].getText());
+
+  ASSERT_EQ(tok::text,         Toks[2].getKind());
+  ASSERT_EQ(StringRef("!"),    Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences5) {
+  const char *Source = "// &#";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#"),   Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences6) {
+  const char *Source = "// &#a";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#"),   Toks[1].getText());
+
+  ASSERT_EQ(tok::text,         Toks[2].getKind());
+  ASSERT_EQ(StringRef("a"),    Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences7) {
+  const char *Source = "// &#42";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#42"), Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences8) {
+  const char *Source = "// &#42a";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#42"), Toks[1].getText());
+
+  ASSERT_EQ(tok::text,         Toks[2].getKind());
+  ASSERT_EQ(StringRef("a"),    Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences9) {
+  const char *Source = "// &#x";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#x"),  Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences10) {
+  const char *Source = "// &#xz";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#x"),  Toks[1].getText());
+
+  ASSERT_EQ(tok::text,         Toks[2].getKind());
+  ASSERT_EQ(StringRef("z"),    Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences11) {
+  const char *Source = "// &#xab";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,          Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+  ASSERT_EQ(tok::text,          Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#xab"), Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,       Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences12) {
+  const char *Source = "// &#xaBz";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,          Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+  ASSERT_EQ(tok::text,          Toks[1].getKind());
+  ASSERT_EQ(StringRef("&#xaB"), Toks[1].getText());
+
+  ASSERT_EQ(tok::text,          Toks[2].getKind());
+  ASSERT_EQ(StringRef("z"),     Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,       Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences13) {
+  const char *Source = "// &amp;";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(3U, Toks.size());
+
+  ASSERT_EQ(tok::text,          Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+  ASSERT_EQ(tok::text,          Toks[1].getKind());
+  ASSERT_EQ(StringRef("&"),     Toks[1].getText());
+
+  ASSERT_EQ(tok::newline,       Toks[2].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences14) {
+  const char *Source = "// &amp;&lt;";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,          Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+  ASSERT_EQ(tok::text,          Toks[1].getKind());
+  ASSERT_EQ(StringRef("&"),     Toks[1].getText());
+
+  ASSERT_EQ(tok::text,          Toks[2].getKind());
+  ASSERT_EQ(StringRef("<"),     Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,       Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences15) {
+  const char *Source = "// &amp; meow";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,          Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+  ASSERT_EQ(tok::text,          Toks[1].getKind());
+  ASSERT_EQ(StringRef("&"),     Toks[1].getText());
+
+  ASSERT_EQ(tok::text,          Toks[2].getKind());
+  ASSERT_EQ(StringRef(" meow"), Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,       Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, HTMLCharacterReferences16) {
+  const char *Sources[] = {
+    "// &#61;",
+    "// &#x3d;",
+    "// &#X3d;"
+  };
+
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    std::vector<Token> Toks;
+
+    lexString(Sources[i], Toks);
+
+    ASSERT_EQ(3U, Toks.size());
+
+    ASSERT_EQ(tok::text,          Toks[0].getKind());
+    ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+    ASSERT_EQ(tok::text,          Toks[1].getKind());
+    ASSERT_EQ(StringRef("="),     Toks[1].getText());
+
+    ASSERT_EQ(tok::newline,       Toks[2].getKind());
+  }
+}
+
 TEST_F(CommentLexerTest, MultipleComments) {
   const char *Source =
     "// Aaa\n"
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index 87e10ce..7258a7e 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/CommentLexer.h"
 #include "clang/AST/CommentParser.h"
 #include "clang/AST/CommentSema.h"
+#include "clang/AST/CommentCommandTraits.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Allocator.h"
 #include <vector>
@@ -54,11 +55,12 @@
   FileID File = SourceMgr.createFileIDForMemBuffer(Buf);
   SourceLocation Begin = SourceMgr.getLocForStartOfFile(File);
 
-  comments::Lexer L(Begin, CommentOptions(),
+  comments::CommandTraits Traits;
+  comments::Lexer L(Allocator, Traits, Begin, CommentOptions(),
                     Source, Source + strlen(Source));
 
-  comments::Sema S(Allocator, SourceMgr, Diags);
-  comments::Parser P(L, S, Allocator, SourceMgr, Diags);
+  comments::Sema S(Allocator, SourceMgr, Diags, Traits);
+  comments::Parser P(L, S, Allocator, SourceMgr, Diags, Traits);
   comments::FullComment *FC = P.parseFullComment();
 
   if (DEBUG) {
@@ -205,10 +207,15 @@
         << " direction, "
            "expected " << (IsDirectionExplicit ? "explicit" : "implicit");
 
-  StringRef ActualParamName = PCC->getParamName();
+  if (!ParamName.empty() && !PCC->hasParamName())
+    return ::testing::AssertionFailure()
+        << "ParamCommandComment has no parameter name";
+
+  StringRef ActualParamName = PCC->hasParamName() ? PCC->getParamName() : "";
   if (ActualParamName != ParamName)
     return ::testing::AssertionFailure()
-        << "ParamCommandComment has name \"" << ActualParamName.str() << "\", "
+        << "ParamCommandComment has parameter name \"" << ActualParamName.str()
+        << "\", "
            "expected \"" << ParamName.str() << "\"";
 
   Paragraph = PCC->getParagraph();
@@ -216,6 +223,39 @@
   return ::testing::AssertionSuccess();
 }
 
+::testing::AssertionResult HasTParamCommandAt(
+                              const Comment *C,
+                              size_t Idx,
+                              TParamCommandComment *&TPCC,
+                              StringRef CommandName,
+                              StringRef ParamName,
+                              ParagraphComment *&Paragraph) {
+  ::testing::AssertionResult AR = GetChildAt(C, Idx, TPCC);
+  if (!AR)
+    return AR;
+
+  StringRef ActualCommandName = TPCC->getCommandName();
+  if (ActualCommandName != CommandName)
+    return ::testing::AssertionFailure()
+        << "TParamCommandComment has name \"" << ActualCommandName.str() << "\", "
+           "expected \"" << CommandName.str() << "\"";
+
+  if (!ParamName.empty() && !TPCC->hasParamName())
+    return ::testing::AssertionFailure()
+        << "TParamCommandComment has no parameter name";
+
+  StringRef ActualParamName = TPCC->hasParamName() ? TPCC->getParamName() : "";
+  if (ActualParamName != ParamName)
+    return ::testing::AssertionFailure()
+        << "TParamCommandComment has parameter name \"" << ActualParamName.str()
+        << "\", "
+           "expected \"" << ParamName.str() << "\"";
+
+  Paragraph = TPCC->getParagraph();
+
+  return ::testing::AssertionSuccess();
+}
+
 ::testing::AssertionResult HasInlineCommandAt(const Comment *C,
                                               size_t Idx,
                                               InlineCommandComment *&ICC,
@@ -672,8 +712,7 @@
 }
 
 TEST_F(CommentParserTest, ParamCommand1) {
-  const char *Source =
-    "// \\param aaa Bbb\n";
+  const char *Source = "// \\param aaa";
 
   FullComment *FC = parseString(Source);
   ASSERT_TRUE(HasChildCount(FC, 2));
@@ -687,16 +726,15 @@
                                   /* IsDirectionExplicit = */ false,
                                   "aaa", PC));
     ASSERT_TRUE(HasChildCount(PCC, 1));
-    ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
+    ASSERT_TRUE(HasChildCount(PC, 0));
   }
 }
 
 TEST_F(CommentParserTest, ParamCommand2) {
-  const char *Source =
-    "// \\param [in] aaa Bbb\n";
+  const char *Source = "// \\param\\brief";
 
   FullComment *FC = parseString(Source);
-  ASSERT_TRUE(HasChildCount(FC, 2));
+  ASSERT_TRUE(HasChildCount(FC, 3));
 
   ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
   {
@@ -704,37 +742,119 @@
     ParagraphComment *PC;
     ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
                                   ParamCommandComment::In,
-                                  /* IsDirectionExplicit = */ true,
-                                  "aaa", PC));
+                                  /* IsDirectionExplicit = */ false,
+                                  "", PC));
     ASSERT_TRUE(HasChildCount(PCC, 1));
-    ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
+    ASSERT_TRUE(HasChildCount(PC, 0));
+  }
+  {
+    BlockCommandComment *BCC;
+    ParagraphComment *PC;
+    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "brief", PC));
+    ASSERT_TRUE(HasChildCount(PC, 0));
   }
 }
 
 TEST_F(CommentParserTest, ParamCommand3) {
-  const char *Source =
-    "// \\param [out] aaa Bbb\n";
+  const char *Sources[] = {
+    "// \\param aaa Bbb\n",
+    "// \\param\n"
+    "//     aaa Bbb\n",
+    "// \\param \n"
+    "//     aaa Bbb\n",
+    "// \\param aaa\n"
+    "// Bbb\n"
+  };
 
-  FullComment *FC = parseString(Source);
-  ASSERT_TRUE(HasChildCount(FC, 2));
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    FullComment *FC = parseString(Sources[i]);
+    ASSERT_TRUE(HasChildCount(FC, 2));
 
-  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
-  {
-    ParamCommandComment *PCC;
-    ParagraphComment *PC;
-    ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
-                                  ParamCommandComment::Out,
-                                  /* IsDirectionExplicit = */ true,
-                                  "aaa", PC));
-    ASSERT_TRUE(HasChildCount(PCC, 1));
-    ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
+    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+    {
+      ParamCommandComment *PCC;
+      ParagraphComment *PC;
+      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+                                    ParamCommandComment::In,
+                                    /* IsDirectionExplicit = */ false,
+                                    "aaa", PC));
+      ASSERT_TRUE(HasChildCount(PCC, 1));
+      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
+    }
   }
 }
 
 TEST_F(CommentParserTest, ParamCommand4) {
   const char *Sources[] = {
+    "// \\param [in] aaa Bbb\n",
+    "// \\param[in] aaa Bbb\n",
+    "// \\param\n"
+    "//     [in] aaa Bbb\n",
+    "// \\param [in]\n"
+    "//     aaa Bbb\n",
+    "// \\param [in] aaa\n"
+    "// Bbb\n",
+  };
+
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    FullComment *FC = parseString(Sources[i]);
+    ASSERT_TRUE(HasChildCount(FC, 2));
+
+    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+    {
+      ParamCommandComment *PCC;
+      ParagraphComment *PC;
+      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+                                    ParamCommandComment::In,
+                                    /* IsDirectionExplicit = */ true,
+                                    "aaa", PC));
+      ASSERT_TRUE(HasChildCount(PCC, 1));
+      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
+    }
+  }
+}
+
+TEST_F(CommentParserTest, ParamCommand5) {
+  const char *Sources[] = {
+    "// \\param [out] aaa Bbb\n",
+    "// \\param[out] aaa Bbb\n",
+    "// \\param\n"
+    "//     [out] aaa Bbb\n",
+    "// \\param [out]\n"
+    "//     aaa Bbb\n",
+    "// \\param [out] aaa\n"
+    "// Bbb\n",
+  };
+
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    FullComment *FC = parseString(Sources[i]);
+    ASSERT_TRUE(HasChildCount(FC, 2));
+
+    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+    {
+      ParamCommandComment *PCC;
+      ParagraphComment *PC;
+      ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+                                    ParamCommandComment::Out,
+                                    /* IsDirectionExplicit = */ true,
+                                    "aaa", PC));
+      ASSERT_TRUE(HasChildCount(PCC, 1));
+      ASSERT_TRUE(HasParagraphCommentAt(PCC, 0, " Bbb"));
+    }
+  }
+}
+
+TEST_F(CommentParserTest, ParamCommand6) {
+  const char *Sources[] = {
     "// \\param [in,out] aaa Bbb\n",
-    "// \\param [in, out] aaa Bbb\n"
+    "// \\param[in,out] aaa Bbb\n",
+    "// \\param [in, out] aaa Bbb\n",
+    "// \\param [in,\n"
+    "//     out] aaa Bbb\n",
+    "// \\param [in,out]\n"
+    "//     aaa Bbb\n",
+    "// \\param [in,out] aaa\n"
+    "// Bbb\n"
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -755,6 +875,81 @@
   }
 }
 
+TEST_F(CommentParserTest, ParamCommand7) {
+  const char *Source =
+    "// \\param aaa \\% Bbb \\$ ccc\n";
+
+  FullComment *FC = parseString(Source);
+  ASSERT_TRUE(HasChildCount(FC, 2));
+
+  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+  {
+    ParamCommandComment *PCC;
+    ParagraphComment *PC;
+    ASSERT_TRUE(HasParamCommandAt(FC, 1, PCC, "param",
+                                  ParamCommandComment::In,
+                                  /* IsDirectionExplicit = */ false,
+                                  "aaa", PC));
+    ASSERT_TRUE(HasChildCount(PCC, 1));
+
+    ASSERT_TRUE(HasChildCount(PC, 5));
+      ASSERT_TRUE(HasTextAt(PC, 0, " "));
+      ASSERT_TRUE(HasTextAt(PC, 1, "%"));
+      ASSERT_TRUE(HasTextAt(PC, 2, " Bbb "));
+      ASSERT_TRUE(HasTextAt(PC, 3, "$"));
+      ASSERT_TRUE(HasTextAt(PC, 4, " ccc"));
+  }
+}
+
+TEST_F(CommentParserTest, TParamCommand1) {
+  const char *Sources[] = {
+    "// \\tparam aaa Bbb\n",
+    "// \\tparam\n"
+    "//     aaa Bbb\n",
+    "// \\tparam \n"
+    "//     aaa Bbb\n",
+    "// \\tparam aaa\n"
+    "// Bbb\n"
+  };
+
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    FullComment *FC = parseString(Sources[i]);
+    ASSERT_TRUE(HasChildCount(FC, 2));
+
+    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+    {
+      TParamCommandComment *TPCC;
+      ParagraphComment *PC;
+      ASSERT_TRUE(HasTParamCommandAt(FC, 1, TPCC, "tparam",
+                                     "aaa", PC));
+      ASSERT_TRUE(HasChildCount(TPCC, 1));
+      ASSERT_TRUE(HasParagraphCommentAt(TPCC, 0, " Bbb"));
+    }
+  }
+}
+
+TEST_F(CommentParserTest, TParamCommand2) {
+  const char *Source = "// \\tparam\\brief";
+
+  FullComment *FC = parseString(Source);
+  ASSERT_TRUE(HasChildCount(FC, 3));
+
+  ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+  {
+    TParamCommandComment *TPCC;
+    ParagraphComment *PC;
+    ASSERT_TRUE(HasTParamCommandAt(FC, 1, TPCC, "tparam", "", PC));
+    ASSERT_TRUE(HasChildCount(TPCC, 1));
+    ASSERT_TRUE(HasChildCount(PC, 0));
+  }
+  {
+    BlockCommandComment *BCC;
+    ParagraphComment *PC;
+    ASSERT_TRUE(HasBlockCommandAt(FC, 2, BCC, "brief", PC));
+    ASSERT_TRUE(HasChildCount(PC, 0));
+  }
+}
+
 
 TEST_F(CommentParserTest, InlineCommand1) {
   const char *Source = "// \\c";
diff --git a/unittests/AST/DeclPrinterTest.cpp b/unittests/AST/DeclPrinterTest.cpp
new file mode 100644
index 0000000..268d48e
--- /dev/null
+++ b/unittests/AST/DeclPrinterTest.cpp
@@ -0,0 +1,1217 @@
+//===- unittests/AST/DeclPrinterTest.cpp --- Declaration printer tests ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains tests for Decl::print() and related methods.
+//
+// Search this file for WRONG to see test cases that are producing something
+// completely wrong, invalid C++ or just misleading.
+//
+// These tests have a coding convention:
+// * declaration to be printed is named 'A' unless it should have some special
+// name (e.g., 'operator+');
+// * additional helper declarations are 'Z', 'Y', 'X' and so on.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ast_matchers;
+using namespace tooling;
+
+namespace {
+
+void PrintDecl(raw_ostream &Out, const ASTContext *Context, const Decl *D) {
+  PrintingPolicy Policy = Context->getPrintingPolicy();
+  Policy.TerseOutput = true;
+  D->print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ false);
+}
+
+class PrintMatch : public MatchFinder::MatchCallback {
+  SmallString<1024> Printed;
+  unsigned NumFoundDecls;
+
+public:
+  PrintMatch() : NumFoundDecls(0) {}
+
+  virtual void run(const MatchFinder::MatchResult &Result) {
+    const Decl *D = Result.Nodes.getDeclAs<Decl>("id");
+    if (!D || D->isImplicit())
+      return;
+    NumFoundDecls++;
+    if (NumFoundDecls > 1)
+      return;
+
+    llvm::raw_svector_ostream Out(Printed);
+    PrintDecl(Out, Result.Context, D);
+  }
+
+  StringRef getPrinted() const {
+    return Printed;
+  }
+
+  unsigned getNumFoundDecls() const {
+    return NumFoundDecls;
+  }
+};
+
+bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
+                   ArrayRef<const char *> ClangArgs) {
+  SmallString<16> FileNameStorage;
+  StringRef FileNameRef = "input.cc";
+
+  std::vector<std::string> ArgVector;
+  ArgVector.push_back("clang-tool");
+  ArgVector.push_back("-fsyntax-only");
+  ArgVector.push_back(FileNameRef.data());
+  for (unsigned i = 0, e = ClangArgs.size(); i != e; ++i)
+    ArgVector.push_back(ClangArgs[i]);
+
+  FileManager Files((FileSystemOptions()));
+  ToolInvocation Invocation(ArgVector, ToolAction, &Files);
+
+  SmallString<1024> CodeStorage;
+  Invocation.mapVirtualFile(FileNameRef,
+                            Code.toNullTerminatedStringRef(CodeStorage));
+  return Invocation.run();
+}
+
+::testing::AssertionResult PrintedDeclMatches(
+                                  StringRef Code,
+                                  ArrayRef<const char *> ClangArgs,
+                                  const DeclarationMatcher &NodeMatch,
+                                  StringRef ExpectedPrinted) {
+  PrintMatch Printer;
+  MatchFinder Finder;
+  Finder.addMatcher(NodeMatch, &Printer);
+  OwningPtr<FrontendActionFactory> Factory(newFrontendActionFactory(&Finder));
+
+  if (!runToolOnCode(Factory->create(), Code, ClangArgs))
+    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
+
+  if (Printer.getNumFoundDecls() == 0)
+    return testing::AssertionFailure()
+        << "Matcher didn't find any declarations";
+
+  if (Printer.getNumFoundDecls() > 1)
+    return testing::AssertionFailure()
+        << "Matcher should match only one declaration "
+           "(found " << Printer.getNumFoundDecls() << ")";
+
+  if (Printer.getPrinted() != ExpectedPrinted)
+    return ::testing::AssertionFailure()
+      << "Expected \"" << ExpectedPrinted << "\", "
+         "got \"" << Printer.getPrinted() << "\"";
+
+  return ::testing::AssertionSuccess();
+}
+
+::testing::AssertionResult PrintedDeclMatches(StringRef Code,
+                                              StringRef DeclName,
+                                              StringRef ExpectedPrinted) {
+  return PrintedDeclMatches(Code,
+                            ArrayRef<const char *>(),
+                            nameableDeclaration(hasName(DeclName)).bind("id"),
+                            ExpectedPrinted);
+}
+
+::testing::AssertionResult PrintedDeclMatches(
+                                  StringRef Code,
+                                  const DeclarationMatcher &NodeMatch,
+                                  StringRef ExpectedPrinted) {
+  return PrintedDeclMatches(Code,
+                            ArrayRef<const char *>(),
+                            NodeMatch,
+                            ExpectedPrinted);
+}
+
+::testing::AssertionResult PrintedDeclCXX11Matches(StringRef Code,
+                                                   StringRef DeclName,
+                                                   StringRef ExpectedPrinted) {
+  return PrintedDeclMatches(Code,
+                            ArrayRef<const char *>("-std=c++11"),
+                            nameableDeclaration(hasName(DeclName)).bind("id"),
+                            ExpectedPrinted);
+}
+
+::testing::AssertionResult PrintedDeclCXX11Matches(
+                                  StringRef Code,
+                                  const DeclarationMatcher &NodeMatch,
+                                  StringRef ExpectedPrinted) {
+  return PrintedDeclMatches(Code,
+                            ArrayRef<const char *>("-std=c++11"),
+                            NodeMatch,
+                            ExpectedPrinted);
+}
+
+} // unnamed namespace
+
+TEST(DeclPrinter, TestNamespace1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "namespace A { int B; }",
+    "A",
+    "namespace A {\n}"));
+    // Should be: with { ... }
+}
+
+TEST(DeclPrinter, TestNamespace2) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "inline namespace A { int B; }",
+    "A",
+    "inline namespace A {\n}"));
+    // Should be: with { ... }
+}
+
+TEST(DeclPrinter, TestNamespaceAlias1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "namespace Z { }"
+    "namespace A = Z;",
+    "A",
+    "namespace A = Z"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestNamespaceAlias2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "namespace X { namespace Y {} }"
+    "namespace A = X::Y;",
+    "A",
+    "namespace A = X::Y"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class A { int a; };",
+    "A",
+    "class A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A { int a; };",
+    "A",
+    "struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "union A { int a; };",
+    "A",
+    "union A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class A : Z { int b; };",
+    "A",
+    "class A :  Z {\n}"));
+    // Should be: with semicolon, with { ... }, without two spaces
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl5) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z { int a; };"
+    "struct A : Z { int b; };",
+    "A",
+    "struct A :  Z {\n}"));
+    // Should be: with semicolon, with { ... }, without two spaces
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl6) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class A : public Z { int b; };",
+    "A",
+    "class A : public Z {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl7) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class A : protected Z { int b; };",
+    "A",
+    "class A : protected Z {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl8) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class A : private Z { int b; };",
+    "A",
+    "class A : private Z {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl9) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class A : virtual Z { int b; };",
+    "A",
+    "class A : virtual  Z {\n}"));
+    // Should be: with semicolon, with { ... }, without two spaces
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl10) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class A : virtual public Z { int b; };",
+    "A",
+    "class A : virtual public Z {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestCXXRecordDecl11) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class Z { int a; };"
+    "class Y : virtual public Z { int b; };"
+    "class A : virtual public Z, private Y { int c; };",
+    "A",
+    "class A : virtual public Z, private Y {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestFunctionDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void A();",
+    "A",
+    "void A()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void A() {}",
+    "A",
+    "void A()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void Z();"
+    "void A() { Z(); }",
+    "A",
+    "void A()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "extern void A();",
+    "A",
+    "extern void A()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl5) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "static void A();",
+    "A",
+    "static void A()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl6) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "inline void A();",
+    "A",
+    "inline void A()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl7) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "constexpr int A(int a);",
+    "A",
+    "int A(int a)"));
+    // WRONG; Should be: "constexpr int A(int a);"
+}
+
+TEST(DeclPrinter, TestFunctionDecl8) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void A(int a);",
+    "A",
+    "void A(int a)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl9) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void A(...);",
+    "A",
+    "void A(...)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl10) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void A(int a, ...);",
+    "A",
+    "void A(int a, ...)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl11) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "typedef long size_t;"
+    "typedef int *pInt;"
+    "void A(int a, pInt b, size_t c);",
+    "A",
+    "void A(int a, pInt b, size_t c)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl12) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void A(int a, int b = 0);",
+    "A",
+    "void A(int a, int b = 0)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl13) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void (*A(int a))(int b);",
+    "A",
+    "void (*A(int a))(int)"));
+    // Should be: with semicolon, with parameter name (?)
+}
+
+TEST(DeclPrinter, TestFunctionDecl14) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "void A(T t) { }"
+    "template<>"
+    "void A(int N) { }",
+    function(hasName("A"), isExplicitTemplateSpecialization()).bind("id"),
+    "void A(int N)"));
+    // WRONG; Should be: "template <> void A(int N);"));
+}
+
+
+TEST(DeclPrinter, TestCXXConstructorDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  A();"
+    "};",
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "A();"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  A(int a);"
+    "};",
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "A(int a);"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  A(const A &a);"
+    "};",
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "A(const A &a);"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  A(const A &a, int = 0);"
+    "};",
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "A(const A &a, int = 0);"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl5) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "struct A {"
+    "  A(const A &&a);"
+    "};",
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "A(const A &&a);"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl6) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  explicit A(int a);"
+    "};",
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "explicit A(int a);"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl7) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  constexpr A();"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "constexpr A();"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl8) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  A() = default;"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    constructor(ofClass(hasName("A"))).bind("id"),
+    ""));
+    // WRONG; Should be: "A() = default;"
+}
+
+TEST(DeclPrinter, TestCXXConstructorDecl9) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  A() = delete;"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    constructor(ofClass(hasName("A"))).bind("id"),
+    " = delete"));
+    // WRONG; Should be: "A() = delete;"
+}
+
+TEST(DeclPrinter, TestCXXDestructorDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  ~A();"
+    "};",
+    destructor(ofClass(hasName("A"))).bind("id"),
+    "void ~A()"));
+    // WRONG; Should be: "~A();"
+}
+
+TEST(DeclPrinter, TestCXXDestructorDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  virtual ~A();"
+    "};",
+    destructor(ofClass(hasName("A"))).bind("id"),
+    "virtual void ~A()"));
+    // WRONG; Should be: "virtual ~A();"
+}
+
+TEST(DeclPrinter, TestCXXConversionDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  operator int();"
+    "};",
+    method(ofClass(hasName("A"))).bind("id"),
+    "int operator int()"));
+    // WRONG; Should be: "operator int();"
+}
+
+TEST(DeclPrinter, TestCXXConversionDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct A {"
+    "  operator bool();"
+    "};",
+    method(ofClass(hasName("A"))).bind("id"),
+    "bool operator _Bool()"));
+    // WRONG; Should be: "operator bool();"
+}
+
+TEST(DeclPrinter, TestCXXConversionDecl3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {};"
+    "struct A {"
+    "  operator Z();"
+    "};",
+    method(ofClass(hasName("A"))).bind("id"),
+    "Z operator struct Z()"));
+    // WRONG; Should be: "operator Z();"
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "namespace std { typedef decltype(sizeof(int)) size_t; }"
+    "struct Z {"
+    "  void *operator new(std::size_t);"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    method(ofClass(hasName("Z"))).bind("id"),
+    "void *operator new(std::size_t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "namespace std { typedef decltype(sizeof(int)) size_t; }"
+    "struct Z {"
+    "  void *operator new[](std::size_t);"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    method(ofClass(hasName("Z"))).bind("id"),
+    "void *operator new[](std::size_t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void operator delete(void *);"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    method(ofClass(hasName("Z"))).bind("id"),
+    "void operator delete(void *) noexcept"));
+    // Should be: with semicolon, without noexcept?
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void operator delete(void *);"
+    "};",
+    method(ofClass(hasName("Z"))).bind("id"),
+    "void operator delete(void *)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_AllocationFunction5) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void operator delete[](void *);"
+    "};",
+    ArrayRef<const char *>("-std=c++11"),
+    method(ofClass(hasName("Z"))).bind("id"),
+    "void operator delete[](void *) noexcept"));
+    // Should be: with semicolon, without noexcept?
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_Operator1) {
+  const char *OperatorNames[] = {
+    "+",  "-",  "*",  "/",  "%",  "^",   "&",   "|",
+    "=",  "<",  ">",  "+=", "-=", "*=",  "/=",  "%=",
+    "^=", "&=", "|=", "<<", ">>", ">>=", "<<=", "==",  "!=",
+    "<=", ">=", "&&", "||",  ",", "->*",
+    "()", "[]"
+  };
+
+  for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
+    SmallString<128> Code;
+    Code.append("struct Z { void operator");
+    Code.append(OperatorNames[i]);
+    Code.append("(Z z); };");
+
+    SmallString<128> Expected;
+    Expected.append("void operator");
+    Expected.append(OperatorNames[i]);
+    Expected.append("(Z z)");
+    // Should be: with semicolon
+
+    ASSERT_TRUE(PrintedDeclMatches(
+      Code,
+      method(ofClass(hasName("Z"))).bind("id"),
+      Expected));
+  }
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_Operator2) {
+  const char *OperatorNames[] = {
+    "~", "!", "++", "--", "->"
+  };
+
+  for (unsigned i = 0, e = llvm::array_lengthof(OperatorNames); i != e; ++i) {
+    SmallString<128> Code;
+    Code.append("struct Z { void operator");
+    Code.append(OperatorNames[i]);
+    Code.append("(); };");
+
+    SmallString<128> Expected;
+    Expected.append("void operator");
+    Expected.append(OperatorNames[i]);
+    Expected.append("()");
+    // Should be: with semicolon
+
+    ASSERT_TRUE(PrintedDeclMatches(
+      Code,
+      method(ofClass(hasName("Z"))).bind("id"),
+      Expected));
+  }
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void A(int a);"
+    "};",
+    "A",
+    "void A(int a)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  virtual void A(int a);"
+    "};",
+    "A",
+    "virtual void A(int a)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  virtual void A(int a);"
+    "};"
+    "struct ZZ : Z {"
+    "  void A(int a);"
+    "};",
+    "ZZ::A",
+    "void A(int a)"));
+    // Should be: with semicolon
+    // TODO: should we print "virtual"?
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  inline void A(int a);"
+    "};",
+    "A",
+    "inline void A(int a)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl5) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  virtual void A(int a) = 0;"
+    "};",
+    "A",
+    "virtual void A(int a) = 0"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void A(int a) const;"
+    "};",
+    "A",
+    "void A(int a) const"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void A(int a) volatile;"
+    "};",
+    "A",
+    "void A(int a) volatile"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_CVQualifier3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void A(int a) const volatile;"
+    "};",
+    "A",
+    "void A(int a) const volatile"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier1) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "struct Z {"
+    "  void A(int a) &;"
+    "};",
+    "A",
+    "void A(int a)"));
+    // WRONG; Should be: "void A(int a) &;"
+}
+
+TEST(DeclPrinter, TestCXXMethodDecl_RefQualifier2) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "struct Z {"
+    "  void A(int a) &&;"
+    "};",
+    "A",
+    "void A(int a)"));
+    // WRONG; Should be: "void A(int a) &&;"
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void A(int a) throw();"
+    "};",
+    "A",
+    "void A(int a) throw()"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z {"
+    "  void A(int a) throw(int);"
+    "};",
+    "A",
+    "void A(int a) throw(int)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "class ZZ {};"
+    "struct Z {"
+    "  void A(int a) throw(ZZ, int);"
+    "};",
+    "A",
+    "void A(int a) throw(ZZ, int)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification4) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "struct Z {"
+    "  void A(int a) noexcept;"
+    "};",
+    "A",
+    "void A(int a) noexcept"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification5) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "struct Z {"
+    "  void A(int a) noexcept(true);"
+    "};",
+    "A",
+    "void A(int a) noexcept(trueA(int a) noexcept(true)"));
+    // WRONG; Should be: "void A(int a) noexcept(true);"
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification6) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "struct Z {"
+    "  void A(int a) noexcept(1 < 2);"
+    "};",
+    "A",
+    "void A(int a) noexcept(1 < 2A(int a) noexcept(1 < 2)"));
+    // WRONG; Should be: "void A(int a) noexcept(1 < 2);"
+}
+
+TEST(DeclPrinter, TestFunctionDecl_ExceptionSpecification7) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<int N>"
+    "struct Z {"
+    "  void A(int a) noexcept(N < 2);"
+    "};",
+    "A",
+    "void A(int a) noexcept(N < 2A(int a) noexcept(N < 2)"));
+    // WRONG; Should be: "void A(int a) noexcept(N < 2);"
+}
+
+TEST(DeclPrinter, TestVarDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "char *const (*(*A)[5])(int);",
+    "A",
+    "char *const (*(*A)[5])(int)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestVarDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "void (*A)() throw(int);",
+    "A",
+    "void (*A)() throw(int)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestVarDecl3) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "void (*A)() noexcept;",
+    "A",
+    "void (*A)() noexcept"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFieldDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "struct Z { T A; };",
+    "A",
+    "T A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFieldDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<int N>"
+    "struct Z { int A[N]; };",
+    "A",
+    "int A[N]"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "struct A { T a; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <typename T> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T = int>"
+    "struct A { T a; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <typename T = int> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<class T>"
+    "struct A { T a; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <class T> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T, typename U>"
+    "struct A { T a; U b; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <typename T, typename U> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl5) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<int N>"
+    "struct A { int a[N]; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <int N> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl6) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<int N = 42>"
+    "struct A { int a[N]; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <int N = 42> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl7) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "typedef int MyInt;"
+    "template<MyInt N>"
+    "struct A { int a[N]; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <MyInt N> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl8) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<template<typename U> class T> struct A { };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <template <typename U> class T> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl9) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T> struct Z { };"
+    "template<template<typename U> class T = Z> struct A { };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <template <typename U> class T> struct A {\n}"));
+    // Should be: with semicolon, with { ... }
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl10) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename... T>"
+    "struct A { int a; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <typename ... T> struct A {\n}"));
+    // Should be: with semicolon, with { ... }, without spaces before '...'
+}
+
+TEST(DeclPrinter, TestClassTemplateDecl11) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename... T>"
+    "struct A : public T... { int a; };",
+    classTemplate(hasName("A")).bind("id"),
+    "template <typename ... T> struct A : public T... {\n}"));
+    // Should be: with semicolon, with { ... }, without spaces before '...'
+}
+
+TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T, typename U>"
+    "struct A { T a; U b; };"
+    "template<typename T>"
+    "struct A<T, int> { T a; };",
+    classTemplateSpecialization().bind("id"),
+    "struct A {\n}"));
+    // WRONG; Should be: "template<typename T> struct A<T, int> { ... }"
+}
+
+TEST(DeclPrinter, TestClassTemplatePartialSpecializationDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "struct A { T a; };"
+    "template<typename T>"
+    "struct A<T *> { T a; };",
+    classTemplateSpecialization().bind("id"),
+    "struct A {\n}"));
+    // WRONG; Should be: "template<typename T> struct A<T *> { ... }"
+}
+
+TEST(DeclPrinter, TestClassTemplateSpecializationDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "struct A { T a; };"
+    "template<>"
+    "struct A<int> { int a; };",
+    classTemplateSpecialization().bind("id"),
+    "struct A {\n}"));
+    // WRONG; Should be: "template<> struct A<int> { ... }"
+}
+
+TEST(DeclPrinter, TestFunctionTemplateDecl1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "void A(T &t);",
+    functionTemplate(hasName("A")).bind("id"),
+    "template <typename T> void A(T &t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionTemplateDecl2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T>"
+    "void A(T &t) { }",
+    functionTemplate(hasName("A")).bind("id"),
+    "template <typename T> void A(T &t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionTemplateDecl3) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename... T>"
+    "void A(T... a);",
+    functionTemplate(hasName("A")).bind("id"),
+    "template <typename ... T> void A(T a...)"));
+    // WRONG; Should be: "template <typename ... T> void A(T... a)"
+    //        (not "T a...")
+    // Should be: with semicolon.
+}
+
+TEST(DeclPrinter, TestFunctionTemplateDecl4) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z { template<typename T> void A(T t); };",
+    functionTemplate(hasName("A")).bind("id"),
+    "template <typename T> void A(T t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionTemplateDecl5) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "struct Z { template<typename T> void A(T t) {} };",
+    functionTemplate(hasName("A")).bind("id"),
+    "template <typename T> void A(T t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestFunctionTemplateDecl6) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T >struct Z {"
+    "  template<typename U> void A(U t) {}"
+    "};",
+    functionTemplate(hasName("A")).bind("id"),
+    "template <typename U> void A(U t)"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList1) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T> struct Z {};"
+    "struct X {};"
+    "Z<X> A;",
+    "A",
+    "Z<X> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList2) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T, typename U> struct Z {};"
+    "struct X {};"
+    "typedef int Y;"
+    "Z<X, Y> A;",
+    "A",
+    "Z<X, Y> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList3) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<typename T> struct Z {};"
+    "template<typename T> struct X {};"
+    "Z<X<int> > A;",
+    "A",
+    "Z<X<int> > A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList4) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename T> struct Z {};"
+    "template<typename T> struct X {};"
+    "Z<X<int>> A;",
+    "A",
+    "Z<X<int> > A"));
+    // Should be: with semicolon, without extra space in "> >"
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList5) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename T> struct Z {};"
+    "template<typename T> struct X { Z<T> A; };",
+    "A",
+    "Z<T> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList6) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<template<typename T> class U> struct Z {};"
+    "template<typename T> struct X {};"
+    "Z<X> A;",
+    "A",
+    "Z<X> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList7) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<template<typename T> class U> struct Z {};"
+    "template<template<typename T> class U> struct Y {"
+    "  Z<U> A;"
+    "};",
+    "A",
+    "Z<U> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList8) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename T> struct Z {};"
+    "template<template<typename T> class U> struct Y {"
+    "  Z<U<int> > A;"
+    "};",
+    "A",
+    "Z<U<int> > A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList9) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<unsigned I> struct Z {};"
+    "Z<0> A;",
+    "A",
+    "Z<0> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList10) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<unsigned I> struct Z {};"
+    "template<unsigned I> struct X { Z<I> A; };",
+    "A",
+    "Z<I> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList11) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<int I> struct Z {};"
+    "Z<42 * 10 - 420 / 1> A;",
+    "A",
+    "Z<42 * 10 - 420 / 1> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList12) {
+  ASSERT_TRUE(PrintedDeclMatches(
+    "template<const char *p> struct Z {};"
+    "extern const char X[] = \"aaa\";"
+    "Z<X> A;",
+    "A",
+    "Z<X> A"));
+    // Should be: with semicolon
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList13) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename... T> struct Z {};"
+    "template<typename... T> struct X {"
+    "  Z<T...> A;"
+    "};",
+    "A",
+    "Z<T...> A"));
+    // Should be: with semicolon, without extra space in "> >"
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList14) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<typename... T> struct Z {};"
+    "template<typename T> struct Y {};"
+    "template<typename... T> struct X {"
+    "  Z<Y<T>...> A;"
+    "};",
+    "A",
+    "Z<Y<T>...> A"));
+    // Should be: with semicolon, without extra space in "> >"
+}
+
+TEST(DeclPrinter, TestTemplateArgumentList15) {
+  ASSERT_TRUE(PrintedDeclCXX11Matches(
+    "template<unsigned I> struct Z {};"
+    "template<typename... T> struct X {"
+    "  Z<sizeof...(T)> A;"
+    "};",
+    "A",
+    "Z<sizeof...(T)> A"));
+    // Should be: with semicolon, without extra space in "> >"
+}
+
diff --git a/unittests/AST/Makefile b/unittests/AST/Makefile
index 31cd5de..74f17b2 100644
--- a/unittests/AST/Makefile
+++ b/unittests/AST/Makefile
@@ -9,7 +9,10 @@
 
 CLANG_LEVEL = ../..
 TESTNAME = AST
-LINK_COMPONENTS := support mc
-USEDLIBS = clangAST.a clangLex.a clangBasic.a
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
+USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
+           clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \
+           clangAST.a clangASTMatchers.a clangLex.a clangBasic.a clangEdit.a
 
 include $(CLANG_LEVEL)/unittests/Makefile
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index f76a596..a7c64b3 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -39,6 +39,12 @@
 }
 #endif
 
+TEST(Decl, MatchesDeclarations) {
+  EXPECT_TRUE(notMatches("", decl(usingDecl())));
+  EXPECT_TRUE(matches("namespace x { class X {}; } using x::X;",
+                      decl(usingDecl())));
+}
+
 TEST(NameableDeclaration, MatchesVariousDecls) {
   DeclarationMatcher NamedX = nameableDeclaration(hasName("X"));
   EXPECT_TRUE(matches("typedef int X;", NamedX));
@@ -286,6 +292,32 @@
       record(isDerivedFrom(record(hasName("X")).bind("test")))));
 }
 
+TEST(ClassTemplate, DoesNotMatchClass) {
+  DeclarationMatcher ClassX = classTemplate(hasName("X"));
+  EXPECT_TRUE(notMatches("class X;", ClassX));
+  EXPECT_TRUE(notMatches("class X {};", ClassX));
+}
+
+TEST(ClassTemplate, MatchesClassTemplate) {
+  DeclarationMatcher ClassX = classTemplate(hasName("X"));
+  EXPECT_TRUE(matches("template<typename T> class X {};", ClassX));
+  EXPECT_TRUE(matches("class Z { template<class T> class X {}; };", ClassX));
+}
+
+TEST(ClassTemplate, DoesNotMatchClassTemplateExplicitSpecialization) {
+  EXPECT_TRUE(notMatches("template<typename T> class X { };"
+                         "template<> class X<int> { int a; };",
+              classTemplate(hasName("X"),
+                            hasDescendant(field(hasName("a"))))));
+}
+
+TEST(ClassTemplate, DoesNotMatchClassTemplatePartialSpecialization) {
+  EXPECT_TRUE(notMatches("template<typename T, typename U> class X { };"
+                         "template<typename T> class X<T, int> { int a; };",
+              classTemplate(hasName("X"),
+                            hasDescendant(field(hasName("a"))))));
+}
+
 TEST(AllOf, AllOverloadsWork) {
   const char Program[] =
       "struct T { }; int f(int, T*); void g(int x) { T t; f(x, &t); }";
@@ -853,6 +885,12 @@
       "}", Reference));
 }
 
+TEST(Matcher, FindsVarDeclInFuncitonParameter) {
+  EXPECT_TRUE(matches(
+      "void f(int i) {}",
+      variable(hasName("i"))));
+}
+
 TEST(Matcher, CalledVariable) {
   StatementMatcher CallOnVariableY = expression(
       memberCall(on(declarationReference(to(variable(hasName("y")))))));
@@ -1005,6 +1043,27 @@
                  CallFunctionF));
 }
 
+TEST(FunctionTemplate, MatchesFunctionTemplateDeclarations) {
+  EXPECT_TRUE(
+      matches("template <typename T> void f(T t) {}",
+      functionTemplate(hasName("f"))));
+}
+
+TEST(FunctionTemplate, DoesNotMatchFunctionDeclarations) {
+  EXPECT_TRUE(
+      notMatches("void f(double d); void f(int t) {}",
+      functionTemplate(hasName("f"))));
+}
+
+TEST(FunctionTemplate, DoesNotMatchFunctionTemplateSpecializations) {
+  EXPECT_TRUE(
+      notMatches("void g(); template <typename T> void f(T t) {}"
+                 "template <> void f(int t) { g(); }",
+      functionTemplate(hasName("f"),
+                       hasDescendant(declarationReference(
+                                            to(function(hasName("g"))))))));
+}
+
 TEST(Matcher, Argument) {
   StatementMatcher CallArgumentY = expression(call(
       hasArgument(0, declarationReference(to(variable(hasName("y")))))));
@@ -1087,6 +1146,12 @@
                       function(returns(hasDeclaration(record(hasName("Y")))))));
 }
 
+TEST(IsExternC, MatchesExternCFunctionDeclarations) {
+  EXPECT_TRUE(matches("extern \"C\" void f() {}", function(isExternC())));
+  EXPECT_TRUE(matches("extern \"C\" { void f() {} }", function(isExternC())));
+  EXPECT_TRUE(notMatches("void f() {}", function(isExternC())));
+}
+
 TEST(HasAnyParameter, DoesntMatchIfInnerMatcherDoesntMatch) {
   EXPECT_TRUE(notMatches("class Y {}; class X { void x(int) {} };",
       method(hasAnyParameter(hasType(record(hasName("X")))))));
@@ -1104,6 +1169,46 @@
       method(hasAnyParameter(hasName("x")))));
 }
 
+TEST(Matcher, MatchesClassTemplateSpecialization) {
+  EXPECT_TRUE(matches("template<typename T> struct A {};"
+                      "template<> struct A<int> {};",
+                      classTemplateSpecialization()));
+  EXPECT_TRUE(matches("template<typename T> struct A {}; A<int> a;",
+                      classTemplateSpecialization()));
+  EXPECT_TRUE(notMatches("template<typename T> struct A {};",
+                         classTemplateSpecialization()));
+}
+
+TEST(Matcher, MatchesTypeTemplateArgument) {
+  EXPECT_TRUE(matches(
+      "template<typename T> struct B {};"
+      "B<int> b;",
+      classTemplateSpecialization(hasAnyTemplateArgument(refersToType(
+          asString("int"))))));
+}
+
+TEST(Matcher, MatchesDeclarationReferenceTemplateArgument) {
+  EXPECT_TRUE(matches(
+      "struct B { int next; };"
+      "template<int(B::*next_ptr)> struct A {};"
+      "A<&B::next> a;",
+      classTemplateSpecialization(hasAnyTemplateArgument(
+          refersToDeclaration(field(hasName("next")))))));
+}
+
+TEST(Matcher, MatchesSpecificArgument) {
+  EXPECT_TRUE(matches(
+      "template<typename T, typename U> class A {};"
+      "A<bool, int> a;",
+      classTemplateSpecialization(hasTemplateArgument(
+          1, refersToType(asString("int"))))));
+  EXPECT_TRUE(notMatches(
+      "template<typename T, typename U> class A {};"
+      "A<int, bool> a;",
+      classTemplateSpecialization(hasTemplateArgument(
+          1, refersToType(asString("int"))))));
+}
+
 TEST(Matcher, ConstructorCall) {
   StatementMatcher Constructor = expression(constructorCall());
 
@@ -1908,6 +2013,19 @@
                       memberExpression(member(hasName("first")))));
 }
 
+TEST(Member, MatchesMemberAllocationFunction) {
+  EXPECT_TRUE(matches("namespace std { typedef typeof(sizeof(int)) size_t; }"
+                      "class X { void *operator new(std::size_t); };",
+                      method(ofClass(hasName("X")))));
+
+  EXPECT_TRUE(matches("class X { void operator delete(void*); };",
+                      method(ofClass(hasName("X")))));
+
+  EXPECT_TRUE(matches("namespace std { typedef typeof(sizeof(int)) size_t; }"
+                      "class X { void operator delete[](void*, std::size_t); };",
+                      method(ofClass(hasName("X")))));
+}
+
 TEST(HasObjectExpression, DoesNotMatchMember) {
   EXPECT_TRUE(notMatches(
       "class X {}; struct Z { X m; }; void f(Z z) { z.m; }",
@@ -1971,6 +2089,28 @@
                          variable(hasType(isConstQualified()))));
 }
 
+TEST(CastExpression, MatchesExplicitCasts) {
+  EXPECT_TRUE(matches("char *p = reinterpret_cast<char *>(&p);",
+                      expression(castExpr())));
+  EXPECT_TRUE(matches("void *p = (void *)(&p);", expression(castExpr())));
+  EXPECT_TRUE(matches("char q, *p = const_cast<char *>(&q);",
+                      expression(castExpr())));
+  EXPECT_TRUE(matches("char c = char(0);", expression(castExpr())));
+}
+TEST(CastExpression, MatchesImplicitCasts) {
+  // This test creates an implicit cast from int to char.
+  EXPECT_TRUE(matches("char c = 0;", expression(castExpr())));
+  // This test creates an implicit cast from lvalue to rvalue.
+  EXPECT_TRUE(matches("char c = 0, d = c;", expression(castExpr())));
+}
+
+TEST(CastExpression, DoesNotMatchNonCasts) {
+  EXPECT_TRUE(notMatches("char c = '0';", expression(castExpr())));
+  EXPECT_TRUE(notMatches("char c, &q = c;", expression(castExpr())));
+  EXPECT_TRUE(notMatches("int i = (0);", expression(castExpr())));
+  EXPECT_TRUE(notMatches("int i = 0;", expression(castExpr())));
+}
+
 TEST(ReinterpretCast, MatchesSimpleCase) {
   EXPECT_TRUE(matches("char* p = reinterpret_cast<char*>(&p);",
                       expression(reinterpretCast())));
@@ -2037,13 +2177,215 @@
                               pointsTo(TypeMatcher(anything())))))));
 }
 
-TEST(HasSourceExpression, MatchesSimpleCase) {
+TEST(HasImplicitDestinationType, MatchesSimpleCase) {
+  // This test creates an implicit const cast.
+  EXPECT_TRUE(matches("int x; const int i = x;",
+                      expression(implicitCast(
+                          hasImplicitDestinationType(isInteger())))));
+  // This test creates an implicit array-to-pointer cast.
+  EXPECT_TRUE(matches("int arr[3]; int *p = arr;",
+                      expression(implicitCast(hasImplicitDestinationType(
+                          pointsTo(TypeMatcher(anything())))))));
+}
+
+TEST(HasImplicitDestinationType, DoesNotMatchIncorrectly) {
+  // This test creates an implicit cast from int to char.
+  EXPECT_TRUE(notMatches("char c = 0;",
+                      expression(implicitCast(hasImplicitDestinationType(
+                          unless(anything()))))));
+  // This test creates an implicit array-to-pointer cast.
+  EXPECT_TRUE(notMatches("int arr[3]; int *p = arr;",
+                      expression(implicitCast(hasImplicitDestinationType(
+                          unless(anything()))))));
+}
+
+TEST(ImplicitCast, MatchesSimpleCase) {
+  // This test creates an implicit const cast.
+  EXPECT_TRUE(matches("int x = 0; const int y = x;",
+                      variable(hasInitializer(implicitCast()))));
+  // This test creates an implicit cast from int to char.
+  EXPECT_TRUE(matches("char c = 0;",
+                      variable(hasInitializer(implicitCast()))));
+  // This test creates an implicit array-to-pointer cast.
+  EXPECT_TRUE(matches("int arr[6]; int *p = arr;",
+                      variable(hasInitializer(implicitCast()))));
+}
+
+TEST(ImplicitCast, DoesNotMatchIncorrectly) {
+  // This test verifies that implicitCast() matches exactly when implicit casts
+  // are present, and that it ignores explicit and paren casts.
+
+  // These two test cases have no casts.
+  EXPECT_TRUE(notMatches("int x = 0;",
+                         variable(hasInitializer(implicitCast()))));
+  EXPECT_TRUE(notMatches("int x = 0, &y = x;",
+                         variable(hasInitializer(implicitCast()))));
+
+  EXPECT_TRUE(notMatches("int x = 0; double d = (double) x;",
+                         variable(hasInitializer(implicitCast()))));
+  EXPECT_TRUE(notMatches("const int *p; int *q = const_cast<int *>(p);",
+                         variable(hasInitializer(implicitCast()))));
+
+  EXPECT_TRUE(notMatches("int x = (0);",
+                         variable(hasInitializer(implicitCast()))));
+}
+
+TEST(IgnoringImpCasts, MatchesImpCasts) {
+  // This test checks that ignoringImpCasts matches when implicit casts are
+  // present and its inner matcher alone does not match.
+  // Note that this test creates an implicit const cast.
+  EXPECT_TRUE(matches("int x = 0; const int y = x;",
+                      variable(hasInitializer(ignoringImpCasts(
+                          declarationReference(to(variable(hasName("x")))))))));
+  // This test creates an implict cast from int to char.
+  EXPECT_TRUE(matches("char x = 0;",
+                      variable(hasInitializer(ignoringImpCasts(
+                          integerLiteral(equals(0)))))));
+}
+
+TEST(IgnoringImpCasts, DoesNotMatchIncorrectly) {
+  // These tests verify that ignoringImpCasts does not match if the inner
+  // matcher does not match.
+  // Note that the first test creates an implicit const cast.
+  EXPECT_TRUE(notMatches("int x; const int y = x;",
+                         variable(hasInitializer(ignoringImpCasts(
+                             unless(anything()))))));
+  EXPECT_TRUE(notMatches("int x; int y = x;",
+                         variable(hasInitializer(ignoringImpCasts(
+                             unless(anything()))))));
+
+  // These tests verify that ignoringImplictCasts does not look through explicit
+  // casts or parentheses.
+  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
+                      variable(hasInitializer(ignoringImpCasts(
+                          integerLiteral())))));
+  EXPECT_TRUE(notMatches("int i = (0);",
+                      variable(hasInitializer(ignoringImpCasts(
+                          integerLiteral())))));
+  EXPECT_TRUE(notMatches("float i = (float)0;",
+                      variable(hasInitializer(ignoringImpCasts(
+                          integerLiteral())))));
+  EXPECT_TRUE(notMatches("float i = float(0);",
+                      variable(hasInitializer(ignoringImpCasts(
+                          integerLiteral())))));
+}
+
+TEST(IgnoringImpCasts, MatchesWithoutImpCasts) {
+  // This test verifies that expressions that do not have implicit casts
+  // still match the inner matcher.
+  EXPECT_TRUE(matches("int x = 0; int &y = x;",
+                      variable(hasInitializer(ignoringImpCasts(
+                          declarationReference(to(variable(hasName("x")))))))));
+}
+
+TEST(IgnoringParenCasts, MatchesParenCasts) {
+  // This test checks that ignoringParenCasts matches when parentheses and/or
+  // casts are present and its inner matcher alone does not match.
+  EXPECT_TRUE(matches("int x = (0);",
+                         variable(hasInitializer(ignoringParenCasts(
+                             integerLiteral(equals(0)))))));
+  EXPECT_TRUE(matches("int x = (((((0)))));",
+                         variable(hasInitializer(ignoringParenCasts(
+                             integerLiteral(equals(0)))))));
+
+  // This test creates an implict cast from int to char in addition to the
+  // parentheses.
+  EXPECT_TRUE(matches("char x = (0);",
+                         variable(hasInitializer(ignoringParenCasts(
+                             integerLiteral(equals(0)))))));
+
+  EXPECT_TRUE(matches("char x = (char)0;",
+                         variable(hasInitializer(ignoringParenCasts(
+                             integerLiteral(equals(0)))))));
+  EXPECT_TRUE(matches("char* p = static_cast<char*>(0);",
+                      variable(hasInitializer(ignoringParenCasts(
+                          integerLiteral(equals(0)))))));
+}
+
+TEST(IgnoringParenCasts, MatchesWithoutParenCasts) {
+  // This test verifies that expressions that do not have any casts still match.
+  EXPECT_TRUE(matches("int x = 0;",
+                         variable(hasInitializer(ignoringParenCasts(
+                             integerLiteral(equals(0)))))));
+}
+
+TEST(IgnoringParenCasts, DoesNotMatchIncorrectly) {
+  // These tests verify that ignoringImpCasts does not match if the inner
+  // matcher does not match.
+  EXPECT_TRUE(notMatches("int x = ((0));",
+                         variable(hasInitializer(ignoringParenCasts(
+                             unless(anything()))))));
+
+  // This test creates an implicit cast from int to char in addition to the
+  // parentheses.
+  EXPECT_TRUE(notMatches("char x = ((0));",
+                         variable(hasInitializer(ignoringParenCasts(
+                             unless(anything()))))));
+
+  EXPECT_TRUE(notMatches("char *x = static_cast<char *>((0));",
+                         variable(hasInitializer(ignoringParenCasts(
+                             unless(anything()))))));
+}
+
+TEST(IgnoringParenAndImpCasts, MatchesParenImpCasts) {
+  // This test checks that ignoringParenAndImpCasts matches when
+  // parentheses and/or implicit casts are present and its inner matcher alone
+  // does not match.
+  // Note that this test creates an implicit const cast.
+  EXPECT_TRUE(matches("int x = 0; const int y = x;",
+                      variable(hasInitializer(ignoringParenImpCasts(
+                          declarationReference(to(variable(hasName("x")))))))));
+  // This test creates an implicit cast from int to char.
+  EXPECT_TRUE(matches("const char x = (0);",
+                         variable(hasInitializer(ignoringParenImpCasts(
+                             integerLiteral(equals(0)))))));
+}
+
+TEST(IgnoringParenAndImpCasts, MatchesWithoutParenImpCasts) {
+  // This test verifies that expressions that do not have parentheses or
+  // implicit casts still match.
+  EXPECT_TRUE(matches("int x = 0; int &y = x;",
+                      variable(hasInitializer(ignoringParenImpCasts(
+                          declarationReference(to(variable(hasName("x")))))))));
+  EXPECT_TRUE(matches("int x = 0;",
+                         variable(hasInitializer(ignoringParenImpCasts(
+                             integerLiteral(equals(0)))))));
+}
+
+TEST(IgnoringParenAndImpCasts, DoesNotMatchIncorrectly) {
+  // These tests verify that ignoringParenImpCasts does not match if
+  // the inner matcher does not match.
+  // This test creates an implicit cast.
+  EXPECT_TRUE(notMatches("char c = ((3));",
+                         variable(hasInitializer(ignoringParenImpCasts(
+                             unless(anything()))))));
+  // These tests verify that ignoringParenAndImplictCasts does not look
+  // through explicit casts.
+  EXPECT_TRUE(notMatches("float y = (float(0));",
+                      variable(hasInitializer(ignoringParenImpCasts(
+                          integerLiteral())))));
+  EXPECT_TRUE(notMatches("float y = (float)0;",
+                      variable(hasInitializer(ignoringParenImpCasts(
+                          integerLiteral())))));
+  EXPECT_TRUE(notMatches("char* p = static_cast<char*>(0);",
+                      variable(hasInitializer(ignoringParenImpCasts(
+                          integerLiteral())))));
+}
+
+TEST(HasSourceExpression, MatchesImplicitCasts) {
   EXPECT_TRUE(matches("class string {}; class URL { public: URL(string s); };"
                       "void r() {string a_string; URL url = a_string; }",
                       expression(implicitCast(
                           hasSourceExpression(constructorCall())))));
 }
 
+TEST(HasSourceExpression, MatchesExplicitCasts) {
+  EXPECT_TRUE(matches("float x = static_cast<float>(42);",
+                      expression(explicitCast(
+                        hasSourceExpression(hasDescendant(
+                          expression(integerLiteral())))))));
+}
+
 TEST(Statement, DoesNotMatchDeclarations) {
   EXPECT_TRUE(notMatches("class X {};", statement()));
 }
@@ -2095,6 +2437,40 @@
       declarationReference(throughUsingDecl(anything()))));
 }
 
+TEST(SingleDecl, IsSingleDecl) {
+  StatementMatcher SingleDeclStmt =
+      declarationStatement(hasSingleDecl(variable(hasInitializer(anything()))));
+  EXPECT_TRUE(matches("void f() {int a = 4;}", SingleDeclStmt));
+  EXPECT_TRUE(notMatches("void f() {int a;}", SingleDeclStmt));
+  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
+                          SingleDeclStmt));
+}
+
+TEST(DeclStmt, ContainsDeclaration) {
+  DeclarationMatcher MatchesInit = variable(hasInitializer(anything()));
+
+  EXPECT_TRUE(matches("void f() {int a = 4;}",
+                      declarationStatement(containsDeclaration(0,
+                                                               MatchesInit))));
+  EXPECT_TRUE(matches("void f() {int a = 4, b = 3;}",
+                      declarationStatement(containsDeclaration(0, MatchesInit),
+                                           containsDeclaration(1,
+                                                               MatchesInit))));
+  unsigned WrongIndex = 42;
+  EXPECT_TRUE(notMatches("void f() {int a = 4, b = 3;}",
+                         declarationStatement(containsDeclaration(WrongIndex,
+                                                      MatchesInit))));
+}
+
+TEST(DeclCount, DeclCountIsCorrect) {
+  EXPECT_TRUE(matches("void f() {int i,j;}",
+                      declarationStatement(declCountIs(2))));
+  EXPECT_TRUE(notMatches("void f() {int i,j; int k;}",
+                         declarationStatement(declCountIs(3))));
+  EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}",
+                         declarationStatement(declCountIs(3))));
+}
+
 TEST(While, MatchesWhileLoops) {
   EXPECT_TRUE(notMatches("void x() {}", whileStmt()));
   EXPECT_TRUE(matches("void x() { while(true); }", whileStmt()));
@@ -2249,5 +2625,49 @@
       record(isTemplateInstantiation())));
 }
 
+TEST(IsExplicitTemplateSpecialization,
+     DoesNotMatchPrimaryTemplate) {
+  EXPECT_TRUE(notMatches(
+      "template <typename T> class X {};",
+      record(isExplicitTemplateSpecialization())));
+  EXPECT_TRUE(notMatches(
+      "template <typename T> void f(T t);",
+      function(isExplicitTemplateSpecialization())));
+}
+
+TEST(IsExplicitTemplateSpecialization,
+     DoesNotMatchExplicitTemplateInstantiations) {
+  EXPECT_TRUE(notMatches(
+      "template <typename T> class X {};"
+      "template class X<int>; extern template class X<long>;",
+      record(isExplicitTemplateSpecialization())));
+  EXPECT_TRUE(notMatches(
+      "template <typename T> void f(T t) {}"
+      "template void f(int t); extern template void f(long t);",
+      function(isExplicitTemplateSpecialization())));
+}
+
+TEST(IsExplicitTemplateSpecialization,
+     DoesNotMatchImplicitTemplateInstantiations) {
+  EXPECT_TRUE(notMatches(
+      "template <typename T> class X {}; X<int> x;",
+      record(isExplicitTemplateSpecialization())));
+  EXPECT_TRUE(notMatches(
+      "template <typename T> void f(T t); void g() { f(10); }",
+      function(isExplicitTemplateSpecialization())));
+}
+
+TEST(IsExplicitTemplateSpecialization,
+     MatchesExplicitTemplateSpecializations) {
+  EXPECT_TRUE(matches(
+      "template <typename T> class X {};"
+      "template<> class X<int> {};",
+      record(isExplicitTemplateSpecialization())));
+  EXPECT_TRUE(matches(
+      "template <typename T> void f(T t) {}"
+      "template<> void f(int t) {}",
+      function(isExplicitTemplateSpecialization())));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
diff --git a/unittests/ASTMatchers/CMakeLists.txt b/unittests/ASTMatchers/CMakeLists.txt
index 8e61732..b56d756 100644
--- a/unittests/ASTMatchers/CMakeLists.txt
+++ b/unittests/ASTMatchers/CMakeLists.txt
@@ -1,3 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
+  support
+  mc
+  )
+
 add_clang_unittest(ASTMatchersTests
   ASTMatchersTest.cpp)
 
diff --git a/unittests/ASTMatchers/Makefile b/unittests/ASTMatchers/Makefile
index 8718dde..d3e4aa3 100644
--- a/unittests/ASTMatchers/Makefile
+++ b/unittests/ASTMatchers/Makefile
@@ -10,7 +10,8 @@
 CLANG_LEVEL = ../..
 
 TESTNAME = ASTMatchers
-LINK_COMPONENTS := support mc
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
            clangRewrite.a clangParse.a clangSema.a clangAnalysis.a \
            clangAST.a clangASTMatchers.a clangLex.a clangBasic.a clangEdit.a
diff --git a/unittests/Frontend/CMakeLists.txt b/unittests/Frontend/CMakeLists.txt
index 729c648..139cf42 100644
--- a/unittests/Frontend/CMakeLists.txt
+++ b/unittests/Frontend/CMakeLists.txt
@@ -1,3 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
+  support
+  mc
+  )
+
 add_clang_unittest(FrontendTests
   FrontendActionTest.cpp
   )
diff --git a/unittests/Frontend/Makefile b/unittests/Frontend/Makefile
index f3e6396..bfc3494 100644
--- a/unittests/Frontend/Makefile
+++ b/unittests/Frontend/Makefile
@@ -9,7 +9,8 @@
 
 CLANG_LEVEL = ../..
 TESTNAME = Frontend
-LINK_COMPONENTS := support mc
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
            clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
            clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt
index 3b5aaf8..4eaf339 100644
--- a/unittests/Tooling/CMakeLists.txt
+++ b/unittests/Tooling/CMakeLists.txt
@@ -1,3 +1,10 @@
+set(LLVM_LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  asmparser
+  support
+  mc
+  )
+
 add_clang_unittest(ToolingTests
   CommentHandlerTest.cpp
   CompilationDatabaseTest.cpp
diff --git a/unittests/Tooling/Makefile b/unittests/Tooling/Makefile
index f0a75ae..5d2224d 100644
--- a/unittests/Tooling/Makefile
+++ b/unittests/Tooling/Makefile
@@ -9,7 +9,8 @@
 
 CLANG_LEVEL = ../..
 TESTNAME = Tooling
-LINK_COMPONENTS := support mc
+include $(CLANG_LEVEL)/../../Makefile.config
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser support mc
 USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
            clangParse.a clangRewrite.a clangSema.a clangAnalysis.a clangEdit.a \
            clangAST.a clangASTMatchers.a clangLex.a clangBasic.a
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index f3ba646..1952c7b 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -385,4 +385,19 @@
       "int main() { Simple s; Simple t(s); }\n"));
 }
 
+TEST(RecursiveASTVisitor, VisitsExtension) {
+  DeclRefExprVisitor Visitor;
+  Visitor.ExpectMatch("s", 1, 24);
+  EXPECT_TRUE(Visitor.runOver(
+    "int s = __extension__ (s);\n"));
+}
+
+TEST(RecursiveASTVisitor, VisitsCompoundLiteralType) {
+  TypeLocVisitor Visitor;
+  Visitor.ExpectMatch("struct S", 1, 26);
+  EXPECT_TRUE(Visitor.runOver(
+      "int f() { return (struct S { int a; }){.a = 0}.a; }",
+      TypeLocVisitor::Lang_C));
+}
+
 } // end namespace clang
diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h
index d439d81..63571d3 100644
--- a/unittests/Tooling/TestVisitor.h
+++ b/unittests/Tooling/TestVisitor.h
@@ -37,9 +37,13 @@
 
   virtual ~TestVisitor() { }
 
+  enum Language { Lang_C, Lang_CXX };
+
   /// \brief Runs the current AST visitor over the given code.
-  bool runOver(StringRef Code) {
-    return tooling::runToolOnCode(CreateTestAction(), Code);
+  bool runOver(StringRef Code, Language L = Lang_CXX) {
+    // FIXME: The input language is determined based on the provided filename.
+    static const StringRef Filenames[] = { "input.c", "input.cc" };
+    return tooling::runToolOnCode(CreateTestAction(), Code, Filenames[L]);
   }
 
   bool shouldVisitTemplateInstantiations() const {
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 1b1a478..ef1ad3e 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -349,7 +349,9 @@
          << "Type(), Record);\n";
     }
     void writeValue(raw_ostream &OS) const {
-      OS << "\" << get" << getUpperName() << "(Ctx) << \"";
+      OS << "\";\n"
+         << "  " << getLowerName() << "Expr->printPretty(OS, 0, Policy);\n"
+         << "  OS << \"";
     }
   };
 
@@ -728,7 +730,8 @@
     OS << "  }\n\n";
 
     OS << "  virtual " << R.getName() << "Attr *clone (ASTContext &C) const;\n";
-    OS << "  virtual void printPretty(llvm::raw_ostream &OS, ASTContext &Ctx) const;\n";
+    OS << "  virtual void printPretty(llvm::raw_ostream &OS,"
+       << "                           const PrintingPolicy &Policy) const;\n";
 
     for (ai = Args.begin(); ai != ae; ++ai) {
       (*ai)->writeAccessors(OS);
@@ -786,7 +789,7 @@
     OS << ");\n}\n\n";
 
     OS << "void " << R.getName() << "Attr::printPretty("
-       << "llvm::raw_ostream &OS, ASTContext &Ctx) const {\n";
+       << "llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
     if (Spellings.begin() != Spellings.end()) {
       std::string Spelling = (*Spellings.begin())->getValueAsString("Name");
       OS << "  OS << \" __attribute__((" << Spelling;
diff --git a/utils/TableGen/ClangDiagnosticsEmitter.cpp b/utils/TableGen/ClangDiagnosticsEmitter.cpp
index 0e3527f..8615d2d 100644
--- a/utils/TableGen/ClangDiagnosticsEmitter.cpp
+++ b/utils/TableGen/ClangDiagnosticsEmitter.cpp
@@ -21,6 +21,7 @@
 #include "llvm/TableGen/Record.h"
 #include "llvm/TableGen/TableGenBackend.h"
 #include <algorithm>
+#include <cctype>
 #include <functional>
 #include <map>
 #include <set>
@@ -203,6 +204,9 @@
   /// Determine if the diagnostic is an extension.
   bool isExtension(const Record *Diag);
 
+  /// Determine if the diagnostic is off by default.
+  bool isOffByDefault(const Record *Diag);
+
   /// Increment the count for a group, and transitively marked
   /// parent groups when appropriate.
   void markGroup(const Record *Group);
@@ -233,6 +237,11 @@
   return ClsName == "CLASS_EXTENSION";
 }
 
+bool InferPedantic::isOffByDefault(const Record *Diag) {
+  const std::string &DefMap = Diag->getValueAsDef("DefaultMapping")->getName();
+  return DefMap == "MAP_IGNORE";
+}
+
 bool InferPedantic::groupInPedantic(const Record *Group, bool increment) {
   GMap::mapped_type &V = GroupCount[Group];
   // Lazily compute the threshold value for the group count.
@@ -264,12 +273,12 @@
 
 void InferPedantic::compute(VecOrSet DiagsInPedantic,
                             VecOrSet GroupsInPedantic) {
-  // All extensions are implicitly in the "pedantic" group.  For those that
-  // aren't explicitly included in -Wpedantic, mark them for consideration
-  // to be included in -Wpedantic directly.
+  // All extensions that are not on by default are implicitly in the
+  // "pedantic" group.  For those that aren't explicitly included in -Wpedantic,
+  // mark them for consideration to be included in -Wpedantic directly.
   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
     Record *R = Diags[i];
-    if (isExtension(R)) {
+    if (isExtension(R) && isOffByDefault(R)) {
       DiagsSet.insert(R);
       if (DefInit *Group = dynamic_cast<DefInit*>(R->getValueInit("Group"))) {
         const Record *GroupRec = Group->getDef();
@@ -339,6 +348,11 @@
 // Warning Tables (.inc file) generation.
 //===----------------------------------------------------------------------===//
 
+static bool isError(const Record &Diag) {
+  const std::string &ClsName = Diag.getValueAsDef("Class")->getName();
+  return ClsName == "CLASS_ERROR";
+}
+
 /// ClangDiagsDefsEmitter - The top-level class emits .def files containing
 /// declarations of Clang diagnostics.
 namespace clang {
@@ -373,6 +387,18 @@
 
   for (unsigned i = 0, e = Diags.size(); i != e; ++i) {
     const Record &R = *Diags[i];
+    
+    // Check if this is an error that is accidentally in a warning
+    // group.
+    if (isError(R)) {
+      if (DefInit *Group = dynamic_cast<DefInit*>(R.getValueInit("Group"))) {
+        const Record *GroupRec = Group->getDef();
+        const std::string &GroupName = GroupRec->getValueAsString("GroupName");
+        throw "Error " + R.getName() + " cannot be in a warning group [" +
+              GroupName + "]";
+      }
+    }
+
     // Filter by component.
     if (!Component.empty() && Component != R.getValueAsString("Component"))
       continue;
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 5cb40c5..6837306 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -1234,7 +1234,7 @@
     s += " __attribute__((unavailable));\n";
     return s;
   } else
-    s += " { \\\n  ";
+    s += " {\n  ";
 
   if (kind != OpNone)
     s += GenOpString(kind, proto, outTypeStr);
@@ -1504,7 +1504,7 @@
       throw TGError(R->getLoc(), "Builtin has no class kind");
 
     int si = -1, qi = -1;
-    unsigned mask = 0, qmask = 0;
+    uint64_t mask = 0, qmask = 0;
     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
       // Generate the switch case(s) for this builtin for the type validation.
       bool quad = false, poly = false, usgn = false;
@@ -1512,10 +1512,10 @@
 
       if (quad) {
         qi = ti;
-        qmask |= 1 << GetNeonEnum(Proto, TypeVec[ti]);
+        qmask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
       } else {
         si = ti;
-        mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]);
+        mask |= 1ULL << GetNeonEnum(Proto, TypeVec[ti]);
       }
     }
 
@@ -1552,7 +1552,7 @@
     if (mask) {
       OS << "case ARM::BI__builtin_neon_"
          << MangleName(name, TypeVec[si], ClassB)
-         << ": mask = " << "0x" << utohexstr(mask);
+         << ": mask = " << "0x" << utohexstr(mask) << "ULL";
       if (PtrArgNum >= 0)
         OS << "; PtrArgNum = " << PtrArgNum;
       if (HasConstPtr)
@@ -1562,7 +1562,7 @@
     if (qmask) {
       OS << "case ARM::BI__builtin_neon_"
          << MangleName(name, TypeVec[qi], ClassB)
-         << ": mask = " << "0x" << utohexstr(qmask);
+         << ": mask = " << "0x" << utohexstr(qmask) << "ULL";
       if (PtrArgNum >= 0)
         OS << "; PtrArgNum = " << PtrArgNum;
       if (HasConstPtr)
diff --git a/utils/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py
index 6013345..c8f05cb 100755
--- a/utils/analyzer/CmpRuns.py
+++ b/utils/analyzer/CmpRuns.py
@@ -16,8 +16,12 @@
 
     # Load the results of both runs, to obtain lists of the corresponding
     # AnalysisDiagnostic objects.
-    resultsA = loadResults(dirA, opts, deleteEmpty)
-    resultsB = loadResults(dirB, opts, deleteEmpty)
+    #
+    # root - the name of the root directory, which will be disregarded when 
+    # determining the source file name
+    # 
+    resultsA = loadResults(dirA, opts, root, deleteEmpty)
+    resultsB = loadResults(dirB, opts, root, deleteEmpty)
     
     # Generate a relation from diagnostics in run A to diagnostics in run B 
     # to obtain a list of triples (a, b, confidence). 
@@ -54,10 +58,10 @@
     def getIssueIdentifier(self) :
         id = ''
         if 'issue_context' in self._data :
-          id += self._data['issue_context']
+          id += self._data['issue_context'] + ":"
         if 'issue_hash' in self._data :
-          id += str(self._data['issue_hash'])
-        return id
+          id += str(self._data['issue_hash']) + ":"
+        return id + ":" + self.getFileName()
 
     def getReport(self):
         if self._htmlReport is None:
@@ -96,8 +100,9 @@
 #
 
 class CmpOptions:
-    def __init__(self, verboseLog=None, root=""):
-        self.root = root
+    def __init__(self, verboseLog=None, rootA="", rootB=""):
+        self.rootA = rootA
+        self.rootB = rootB
         self.verboseLog = verboseLog
 
 class AnalysisReport:
@@ -106,20 +111,21 @@
         self.files = files
 
 class AnalysisRun:
-    def __init__(self, path, opts):
+    def __init__(self, path, root, opts):
         self.path = path
+        self.root = root
         self.reports = []
         self.diagnostics = []
         self.opts = opts
 
     def getSourceName(self, path):
-        if path.startswith(self.opts.root):
-            return path[len(self.opts.root):]
+        if path.startswith(self.root):
+            return path[len(self.root):]
         return path
 
-def loadResults(path, opts, deleteEmpty=True):
-    run = AnalysisRun(path, opts)
-
+def loadResults(path, opts, root = "", deleteEmpty=True):
+    run = AnalysisRun(path, root, opts)
+    
     for f in os.listdir(path):
         if (not f.startswith('report') or
             not f.endswith('plist')):
@@ -140,7 +146,9 @@
             for d in data['diagnostics']:
                 # FIXME: Why is this named files, when does it have multiple
                 # files?
-                assert len(d['HTMLDiagnostics_files']) == 1
+                # TODO: Add the assert back in after we fix the 
+                # plist-html output.
+                # assert len(d['HTMLDiagnostics_files']) == 1
                 htmlFiles.append(d.pop('HTMLDiagnostics_files')[0])
         else:
             htmlFiles = [None] * len(data['diagnostics'])
@@ -209,8 +217,8 @@
 
 def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True):
     # Load the run results.
-    resultsA = loadResults(dirA, opts, deleteEmpty)
-    resultsB = loadResults(dirB, opts, deleteEmpty)
+    resultsA = loadResults(dirA, opts, opts.rootA, deleteEmpty)
+    resultsB = loadResults(dirB, opts, opts.rootB, deleteEmpty)
     
     # Open the verbose log, if given.
     if opts.verboseLog:
@@ -259,8 +267,11 @@
 def main():
     from optparse import OptionParser
     parser = OptionParser("usage: %prog [options] [dir A] [dir B]")
-    parser.add_option("", "--root", dest="root",
-                      help="Prefix to ignore on source files",
+    parser.add_option("", "--rootA", dest="rootA",
+                      help="Prefix to ignore on source files for directory A",
+                      action="store", type=str, default="")
+    parser.add_option("", "--rootB", dest="rootB",
+                      help="Prefix to ignore on source files for directory B",
                       action="store", type=str, default="")
     parser.add_option("", "--verbose-log", dest="verboseLog",
                       help="Write additional information to LOG [default=None]",
@@ -273,7 +284,7 @@
 
     dirA,dirB = args
 
-    cmpScanBuildResults(dirA, dirB, opts)    
+    dumpScanBuildResultsDiff(dirA, dirB, opts)    
 
 if __name__ == '__main__':
     main()
diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py
index 93a3a72..fd4bc8a 100755
--- a/utils/analyzer/SATestBuild.py
+++ b/utils/analyzer/SATestBuild.py
@@ -72,7 +72,7 @@
 
 # The list of checkers used during analyzes.
 # Currently, consists of all the non experimental checkers.
-Checkers="experimental.security.taint,core,deadcode,cplusplus,security,unix,osx,cocoa"
+Checkers="experimental.security.taint,core,deadcode,security,unix,osx"
 
 Verbose = 1
 
diff --git a/www/analyzer/installation.html b/www/analyzer/installation.html
index ebccd07..2eb7937 100644
--- a/www/analyzer/installation.html
+++ b/www/analyzer/installation.html
@@ -93,7 +93,7 @@
 <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 <tt>$(OBJDIR)/Debug+Asserts/bin</tt>
 (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
+can also do <tt>make install</tt> to install the LLVM/Clang libraries and
 binaries to the installation directory of your choice (specified when you run
 <tt>configure</tt>).</p></li>
 
diff --git a/www/builtins.py b/www/builtins.py
index 5e85770..18f86ab 100755
--- a/www/builtins.py
+++ b/www/builtins.py
@@ -45,6 +45,7 @@
 '__builtin_ia32_xorpd': '_mm_xor_pd',
 '__builtin_ia32_xorps': '_mm_xor_ps',
 '__builtin_ia32_pxor128': '_mm_xor_si128',
+'__builtin_ia32_cvtps2dq': '_mm_cvtps_epi32',
 '__builtin_ia32_cvtsd2ss': '_mm_cvtsd_ss',
 '__builtin_ia32_cvtsi2sd': '_mm_cvtsi32_sd',
 '__builtin_ia32_cvtss2sd': '_mm_cvtss_sd',
@@ -120,6 +121,8 @@
 '__builtin_ia32_pshufd': '_mm_shuffle_epi32',
 '__builtin_ia32_movshdup': '_mm_movehdup_ps',
 '__builtin_ia32_movsldup': '_mm_moveldup_ps',
+'__builtin_ia32_maxps': '_mm_max_ps',
+'__builtin_ia32_pslldi128': '_mm_slli_epi32',
 '__builtin_ia32_vec_set_v16qi': '_mm_insert_epi8',
 '__builtin_ia32_vec_set_v8hi': '_mm_insert_epi16',
 '__builtin_ia32_vec_set_v4si': '_mm_insert_epi32',
@@ -157,4 +160,4 @@
         report_cant(unh)
   sys.stdout.write(line)
 
-sys.exit(err)
\ No newline at end of file
+sys.exit(err)
diff --git a/www/comparison.html b/www/comparison.html
index 58c4b31..01b8aea 100644
--- a/www/comparison.html
+++ b/www/comparison.html
@@ -103,9 +103,9 @@
         sometimes acceptable, but are often confusing and it does not support
         expressive diagnostics.  Clang also preserves typedefs in diagnostics
         consistently, showing macro expansions and many other features.</li>
-    <li>GCC is licensed under the GPL license.  clang uses a BSD license, which
-        allows it to be used by projects that do not themselves want to be
-        GPL.</li>
+    <li>GCC is licensed under the GPL license. <a href="features.html#license">
+        clang uses a BSD license,</a> which allows it to be embedded in
+        software that is not GPL-licensed.</li>
     <li>Clang inherits a number of features from its use of LLVM as a backend,
         including support for a bytecode representation for intermediate code,
         pluggable optimizers, link-time optimization support, Just-In-Time
diff --git a/www/features.html b/www/features.html
index d55391a..2d3191e 100644
--- a/www/features.html
+++ b/www/features.html
@@ -329,13 +329,15 @@
 <!--=======================================================================-->
 
 <p>We actively intend for clang (and LLVM as a whole) to be used for
-commercial projects, and the BSD license is the simplest way to allow this.  We
-feel that the license encourages contributors to pick up the source and work
-with it, and believe that those individuals and organizations will contribute
-back their work if they do not want to have to maintain a fork forever (which is
-time consuming and expensive when merges are involved).  Further, nobody makes
-money on compilers these days, but many people need them to get bigger goals
-accomplished: it makes sense for everyone to work together.</p>
+commercial projects, not only as a stand-alone compiler but also as a library
+embedded inside a proprietary application.  The BSD license is the simplest way
+to allow this.  We feel that the license encourages contributors to pick up the
+source and work with it, and believe that those individuals and organizations
+will contribute back their work if they do not want to have to maintain a fork
+forever (which is time consuming and expensive when merges are involved).
+Further, nobody makes money on compilers these days, but many people need them
+to get bigger goals accomplished: it makes sense for everyone to work
+together.</p>
 
 <p>For more information about the LLVM/clang license, please see the <a 
 href="http://llvm.org/docs/DeveloperPolicy.html#license">LLVM License 
diff --git a/www/get_started.html b/www/get_started.html
index 8e339b2..7756f9e 100644
--- a/www/get_started.html
+++ b/www/get_started.html
@@ -53,21 +53,29 @@
   </li>
   <li>Checkout Clang:
   <ul>
-    <li><tt>cd llvm/tools</tt>
+    <li><tt>cd llvm/tools</tt></li>
     <li><tt>svn co http://llvm.org/svn/llvm-project/cfe/trunk clang</tt></li>
+    <li><tt>cd ../..</tt></li>
+  </ul>
+  </li>
+  <li>Checkout extra Clang Tools: (optional)
+  <ul>
+    <li><tt>cd llvm/tools/clang/tools</tt></li>
+    <li><tt>svn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk
+        extra</tt></li>
+    <li><tt>cd ../../../..</tt></li>
   </ul>
   </li>
   <li>Checkout Compiler-RT:
   <ul>
-    <li><tt>cd ../..</tt>  (back to where you started)</li>
-    <li><tt>cd llvm/projects</tt>
+    <li><tt>cd llvm/projects</tt></li>
     <li><tt>svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk
         compiler-rt</tt></li>
+    <li><tt>cd ../..</tt></li>
   </ul>
   </li>
   <li>Build LLVM and Clang:
   <ul>
-    <li><tt>cd ../..</tt>  (back to where you started)</li>
     <li><tt>mkdir build</tt> (for building without polluting the source dir)
     </li>
     <li><tt>cd build</tt></li>