From 36c49e3f258dced101949edabd72e9bc3f1dedc4 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Fri, 17 Sep 2010 15:54:40 +0000
Subject: Vendor import of clang r114020 (from the release_28 branch):
 http://llvm.org/svn/llvm-project/cfe/branches/release_28@114020

Approved by:	rpaulo (mentor)
---
 lib/Sema/AnalysisBasedWarnings.cpp       |   39 +-
 lib/Sema/AnalysisBasedWarnings.h         |   55 -
 lib/Sema/AttributeList.cpp               |  136 +
 lib/Sema/CMakeLists.txt                  |    3 +-
 lib/Sema/CXXFieldCollector.h             |   79 -
 lib/Sema/CodeCompleteConsumer.cpp        |  233 +-
 lib/Sema/DeclSpec.cpp                    |  667 +++++
 lib/Sema/IdentifierResolver.cpp          |   35 +-
 lib/Sema/IdentifierResolver.h            |  203 --
 lib/Sema/JumpDiagnostics.cpp             |   29 +-
 lib/Sema/Lookup.h                        |  654 -----
 lib/Sema/Makefile                        |    1 -
 lib/Sema/ParseAST.cpp                    |  125 -
 lib/Sema/Sema.cpp                        |  261 +-
 lib/Sema/Sema.h                          | 4655 ------------------------------
 lib/Sema/SemaAccess.cpp                  |  218 +-
 lib/Sema/SemaAttr.cpp                    |  135 +-
 lib/Sema/SemaCXXCast.cpp                 |  183 +-
 lib/Sema/SemaCXXScopeSpec.cpp            |   42 +-
 lib/Sema/SemaChecking.cpp                |  870 +++---
 lib/Sema/SemaCodeComplete.cpp            | 2077 ++++++++++---
 lib/Sema/SemaDecl.cpp                    | 1400 +++++----
 lib/Sema/SemaDeclAttr.cpp                |  453 ++-
 lib/Sema/SemaDeclCXX.cpp                 | 1068 ++++---
 lib/Sema/SemaDeclObjC.cpp                |  442 ++-
 lib/Sema/SemaExceptionSpec.cpp           |   10 +-
 lib/Sema/SemaExpr.cpp                    | 1704 +++++------
 lib/Sema/SemaExprCXX.cpp                 |  604 ++--
 lib/Sema/SemaExprObjC.cpp                |  136 +-
 lib/Sema/SemaInit.cpp                    |  383 ++-
 lib/Sema/SemaInit.h                      |  765 -----
 lib/Sema/SemaLookup.cpp                  |  168 +-
 lib/Sema/SemaObjCProperty.cpp            |  175 +-
 lib/Sema/SemaOverload.cpp                | 1374 +++++----
 lib/Sema/SemaOverload.h                  |  617 ----
 lib/Sema/SemaStmt.cpp                    |  382 ++-
 lib/Sema/SemaTemplate.cpp                |  550 ++--
 lib/Sema/SemaTemplate.h                  |  151 -
 lib/Sema/SemaTemplateDeduction.cpp       |  191 +-
 lib/Sema/SemaTemplateInstantiate.cpp     |   87 +-
 lib/Sema/SemaTemplateInstantiateDecl.cpp |  397 +--
 lib/Sema/SemaType.cpp                    |  154 +-
 lib/Sema/TargetAttributesSema.cpp        |   17 +-
 lib/Sema/TargetAttributesSema.h          |    2 +-
 lib/Sema/TreeTransform.h                 | 2028 +++++++------
 45 files changed, 10189 insertions(+), 13769 deletions(-)
 delete mode 100644 lib/Sema/AnalysisBasedWarnings.h
 create mode 100644 lib/Sema/AttributeList.cpp
 delete mode 100644 lib/Sema/CXXFieldCollector.h
 create mode 100644 lib/Sema/DeclSpec.cpp
 delete mode 100644 lib/Sema/IdentifierResolver.h
 delete mode 100644 lib/Sema/Lookup.h
 delete mode 100644 lib/Sema/ParseAST.cpp
 delete mode 100644 lib/Sema/Sema.h
 delete mode 100644 lib/Sema/SemaInit.h
 delete mode 100644 lib/Sema/SemaOverload.h
 delete mode 100644 lib/Sema/SemaTemplate.h

(limited to 'lib/Sema')

diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 448d161..cfebed6 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -13,9 +13,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtObjC.h"
@@ -197,6 +199,8 @@ static ControlFlowKind CheckFallThrough(AnalysisContext &AC) {
   return AlwaysFallThrough;
 }
 
+namespace {
+
 struct CheckFallThroughDiagnostics {
   unsigned diag_MaybeFallThrough_HasNoReturn;
   unsigned diag_MaybeFallThrough_ReturnsNonVoid;
@@ -266,6 +270,8 @@ struct CheckFallThroughDiagnostics {
   }
 };
 
+}
+
 /// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
 /// function that should return a value.  Check that we don't fall off the end
 /// of a noreturn function.  We assume that functions and blocks not marked
@@ -375,19 +381,16 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
       S.SourceMgr.isInSystemHeader(D->getLocation()))
     return;
 
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-    // For function templates, class templates and member function templates
-    // we'll do the analysis at instantiation time.
-    if (FD->isDependentContext())
-      return;
-  }
+  // For code in dependent contexts, we'll do this at instantiation time.
+  if (cast<DeclContext>(D)->isDependentContext())
+    return;
 
   const Stmt *Body = D->getBody();
   assert(Body);
 
   // Don't generate EH edges for CallExprs as we'd like to avoid the n^2
   // explosion for destrutors that can result and the compile time hit.
-  AnalysisContext AC(D, false);
+  AnalysisContext AC(D, 0, false);
 
   // Warning: check missing 'return'
   if (P.enableCheckFallThrough) {
@@ -401,3 +404,21 @@ AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
   if (P.enableCheckUnreachable)
     CheckUnreachable(S, AC);
 }
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const BlockExpr *E) {
+  return IssueWarnings(P, E->getBlockDecl(), E->getType());
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const ObjCMethodDecl *D) {
+  return IssueWarnings(P, D, QualType());
+}
+
+void clang::sema::
+AnalysisBasedWarnings::IssueWarnings(sema::AnalysisBasedWarnings::Policy P,
+                                     const FunctionDecl *D) {
+  return IssueWarnings(P, D, QualType());
+}
diff --git a/lib/Sema/AnalysisBasedWarnings.h b/lib/Sema/AnalysisBasedWarnings.h
deleted file mode 100644
index dea19ba..0000000
--- a/lib/Sema/AnalysisBasedWarnings.h
+++ /dev/null
@@ -1,55 +0,0 @@
-//=- AnalysisBasedWarnings.h - Sema warnings based on libAnalysis -*- C++ -*-=//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines AnalysisBasedWarnings, a worker object used by Sema
-// that issues warnings based on dataflow-analysis.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
-#define LLVM_CLANG_SEMA_ANALYSIS_WARNINGS_H
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseMap.h"
-
-namespace clang {
-
-class Sema;
-
-namespace sema {
-
-class AnalysisBasedWarnings {
-public:
-  class Policy {
-    friend class AnalysisBasedWarnings;
-    // The warnings to run.
-    unsigned enableCheckFallThrough : 1;
-    unsigned enableCheckUnreachable : 1;
-  public:
-    Policy();
-    void disableCheckFallThrough() { enableCheckFallThrough = 0; }
-  };
-
-private:
-  Sema &S;
-  Policy DefaultPolicy;
-
-  enum VisitFlag { NotVisited = 0, Visited = 1, Pending = 2 };
-  llvm::DenseMap<const FunctionDecl*, VisitFlag> VisitedFD;
-
-public:
-  AnalysisBasedWarnings(Sema &s);
-
-  Policy getDefaultPolicy() { return DefaultPolicy; }
-
-  void IssueWarnings(Policy P, const Decl *D, QualType BlockTy = QualType());
-};
-
-}} // end namespace clang::sema
-
-#endif
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
new file mode 100644
index 0000000..8ccb2ca
--- /dev/null
+++ b/lib/Sema/AttributeList.cpp
@@ -0,0 +1,136 @@
+//===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AttributeList class implementation
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/AttributeList.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "llvm/ADT/StringSwitch.h"
+using namespace clang;
+
+AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
+                             IdentifierInfo *sName, SourceLocation sLoc,
+                             IdentifierInfo *pName, SourceLocation pLoc,
+                             Expr **ExprList, unsigned numArgs,
+                             AttributeList *n, bool declspec, bool cxx0x)
+  : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
+    ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
+    DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
+
+  if (numArgs == 0)
+    Args = 0;
+  else {
+    Args = new Expr*[numArgs];
+    memcpy(Args, ExprList, numArgs*sizeof(Args[0]));
+  }
+}
+
+AttributeList::~AttributeList() {
+  if (Args) {
+    // FIXME: before we delete the vector, we need to make sure the Expr's
+    // have been deleted. Since ActionBase::ExprTy is "void", we are dependent
+    // on the actions module for actually freeing the memory. The specific
+    // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType,
+    // ParseField, ParseTag. Once these routines have freed the expression,
+    // they should zero out the Args slot (to indicate the memory has been
+    // freed). If any element of the vector is non-null, we should assert.
+    delete [] Args;
+  }
+  delete Next;
+}
+
+AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
+  llvm::StringRef AttrName = Name->getName();
+
+  // Normalize the attribute name, __foo__ becomes foo.
+  if (AttrName.startswith("__") && AttrName.endswith("__"))
+    AttrName = AttrName.substr(2, AttrName.size() - 4);
+
+  return llvm::StringSwitch<AttributeList::Kind>(AttrName)
+    .Case("weak", AT_weak)
+    .Case("weakref", AT_weakref)
+    .Case("pure", AT_pure)
+    .Case("mode", AT_mode)
+    .Case("used", AT_used)
+    .Case("alias", AT_alias)
+    .Case("align", AT_aligned)
+    .Case("final", AT_final)
+    .Case("cdecl", AT_cdecl)
+    .Case("const", AT_const)
+    .Case("blocks", AT_blocks)
+    .Case("format", AT_format)
+    .Case("hiding", AT_hiding)
+    .Case("malloc", AT_malloc)
+    .Case("packed", AT_packed)
+    .Case("unused", AT_unused)
+    .Case("aligned", AT_aligned)
+    .Case("cleanup", AT_cleanup)
+    .Case("nodebug", AT_nodebug)
+    .Case("nonnull", AT_nonnull)
+    .Case("nothrow", AT_nothrow)
+    .Case("objc_gc", AT_objc_gc)
+    .Case("regparm", AT_regparm)
+    .Case("section", AT_section)
+    .Case("stdcall", AT_stdcall)
+    .Case("annotate", AT_annotate)
+    .Case("fastcall", AT_fastcall)
+    .Case("ibaction", AT_IBAction)
+    .Case("iboutlet", AT_IBOutlet)
+    .Case("iboutletcollection", AT_IBOutletCollection)
+    .Case("noreturn", AT_noreturn)
+    .Case("noinline", AT_noinline)
+    .Case("override", AT_override)
+    .Case("sentinel", AT_sentinel)
+    .Case("NSObject", AT_nsobject)
+    .Case("dllimport", AT_dllimport)
+    .Case("dllexport", AT_dllexport)
+    .Case("may_alias", IgnoredAttribute) // FIXME: TBAA
+    .Case("base_check", AT_base_check)
+    .Case("deprecated", AT_deprecated)
+    .Case("visibility", AT_visibility)
+    .Case("destructor", AT_destructor)
+    .Case("format_arg", AT_format_arg)
+    .Case("gnu_inline", AT_gnu_inline)
+    .Case("weak_import", AT_weak_import)
+    .Case("vecreturn", AT_vecreturn)
+    .Case("vector_size", AT_vector_size)
+    .Case("constructor", AT_constructor)
+    .Case("unavailable", AT_unavailable)
+    .Case("overloadable", AT_overloadable)
+    .Case("address_space", AT_address_space)
+    .Case("always_inline", AT_always_inline)
+    .Case("returns_twice", IgnoredAttribute)
+    .Case("vec_type_hint", IgnoredAttribute)
+    .Case("objc_exception", AT_objc_exception)
+    .Case("ext_vector_type", AT_ext_vector_type)
+    .Case("transparent_union", AT_transparent_union)
+    .Case("analyzer_noreturn", AT_analyzer_noreturn)
+    .Case("warn_unused_result", AT_warn_unused_result)
+    .Case("carries_dependency", AT_carries_dependency)
+    .Case("ns_returns_not_retained", AT_ns_returns_not_retained)
+    .Case("ns_returns_retained", AT_ns_returns_retained)
+    .Case("cf_returns_not_retained", AT_cf_returns_not_retained)
+    .Case("cf_returns_retained", AT_cf_returns_retained)
+    .Case("ownership_returns", AT_ownership_returns)
+    .Case("ownership_holds", AT_ownership_holds)
+    .Case("ownership_takes", AT_ownership_takes)
+    .Case("reqd_work_group_size", AT_reqd_wg_size)
+    .Case("init_priority", AT_init_priority)
+    .Case("no_instrument_function", AT_no_instrument_function)
+    .Case("thiscall", AT_thiscall)
+    .Case("pascal", AT_pascal)
+    .Case("__cdecl", AT_cdecl)
+    .Case("__stdcall", AT_stdcall)
+    .Case("__fastcall", AT_fastcall)
+    .Case("__thiscall", AT_thiscall)
+    .Case("__pascal", AT_pascal)
+    .Default(UnknownAttribute);
+}
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 70b4792..e65bb22 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -2,10 +2,11 @@ set(LLVM_NO_RTTI 1)
 
 add_clang_library(clangSema
   AnalysisBasedWarnings.cpp
+  AttributeList.cpp
   CodeCompleteConsumer.cpp
+  DeclSpec.cpp
   IdentifierResolver.cpp
   JumpDiagnostics.cpp
-  ParseAST.cpp
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
diff --git a/lib/Sema/CXXFieldCollector.h b/lib/Sema/CXXFieldCollector.h
deleted file mode 100644
index 63c6ee3..0000000
--- a/lib/Sema/CXXFieldCollector.h
+++ /dev/null
@@ -1,79 +0,0 @@
-//===- CXXFieldCollector.h - Utility class for C++ class semantic analysis ===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file provides CXXFieldCollector that is used during parsing & semantic
-//  analysis of C++ classes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-#define LLVM_CLANG_SEMA_CXXFIELDCOLLECTOR_H
-
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-  class FieldDecl;
-
-/// CXXFieldCollector - Used to keep track of CXXFieldDecls during parsing of
-/// C++ classes.
-class CXXFieldCollector {
-  /// Fields - Contains all FieldDecls collected during parsing of a C++
-  /// class. When a nested class is entered, its fields are appended to the
-  /// fields of its parent class, when it is exited its fields are removed.
-  llvm::SmallVector<FieldDecl*, 32> Fields;
-
-  /// FieldCount - Each entry represents the number of fields collected during
-  /// the parsing of a C++ class. When a nested class is entered, a new field
-  /// count is pushed, when it is exited, the field count is popped.
-  llvm::SmallVector<size_t, 4> FieldCount;
-
-  // Example:
-  //
-  // class C {
-  //   int x,y;
-  //   class NC {
-  //     int q;
-  //     // At this point, Fields contains [x,y,q] decls and FieldCount contains
-  //     // [2,1].
-  //   };
-  //   int z;
-  //   // At this point, Fields contains [x,y,z] decls and FieldCount contains
-  //   // [3].
-  // };
-
-public:
-  /// StartClass - Called by Sema::ActOnStartCXXClassDef.
-  void StartClass() { FieldCount.push_back(0); }
-
-  /// Add - Called by Sema::ActOnCXXMemberDeclarator.
-  void Add(FieldDecl *D) {
-    Fields.push_back(D);
-    ++FieldCount.back();
-  }
-
-  /// getCurNumField - The number of fields added to the currently parsed class.
-  size_t getCurNumFields() const {
-    assert(!FieldCount.empty() && "no currently-parsed class");
-    return FieldCount.back();
-  }
-
-  /// getCurFields - Pointer to array of fields added to the currently parsed
-  /// class.
-  FieldDecl **getCurFields() { return &*(Fields.end() - getCurNumFields()); }
-
-  /// FinishClass - Called by Sema::ActOnFinishCXXClassDef.
-  void FinishClass() {
-    Fields.resize(Fields.size() - getCurNumFields());
-    FieldCount.pop_back();
-  }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/lib/Sema/CodeCompleteConsumer.cpp b/lib/Sema/CodeCompleteConsumer.cpp
index 6cefc61..58a1627 100644
--- a/lib/Sema/CodeCompleteConsumer.cpp
+++ b/lib/Sema/CodeCompleteConsumer.cpp
@@ -11,11 +11,13 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Sema/CodeCompleteConsumer.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Sema.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/Parse/Scope.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang-c/Index.h"
-#include "Sema.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
@@ -234,8 +236,7 @@ std::string CodeCompletionString::getAsString() const {
     default: OS << C->Text; break;
     }
   }
-  OS.flush();
-  return Result;
+  return OS.str();
 }
 
 const char *CodeCompletionString::getTypedText() const {
@@ -246,8 +247,10 @@ const char *CodeCompletionString::getTypedText() const {
   return 0;
 }
 
-CodeCompletionString *CodeCompletionString::Clone() const {
-  CodeCompletionString *Result = new CodeCompletionString;
+CodeCompletionString *
+CodeCompletionString::Clone(CodeCompletionString *Result) const {
+  if (!Result)
+    Result = new CodeCompletionString;
   for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
     Result->AddChunk(C->Clone());
   return Result;
@@ -373,19 +376,19 @@ bool CodeCompletionString::Deserialize(const char *&Str, const char *StrEnd) {
   return true;
 }
 
-void CodeCompleteConsumer::Result::Destroy() {
+void CodeCompletionResult::Destroy() {
   if (Kind == RK_Pattern) {
     delete Pattern;
     Pattern = 0;
   }
 }
 
-unsigned CodeCompleteConsumer::Result::getPriorityFromDecl(NamedDecl *ND) {
+unsigned CodeCompletionResult::getPriorityFromDecl(NamedDecl *ND) {
   if (!ND)
     return CCP_Unlikely;
   
   // Context-based decisions.
-  DeclContext *DC = ND->getDeclContext()->getLookupContext();
+  DeclContext *DC = ND->getDeclContext()->getRedeclContext();
   if (DC->isFunctionOrMethod() || isa<BlockDecl>(DC))
     return CCP_LocalDeclaration;
   if (DC->isRecord() || isa<ObjCContainerDecl>(DC))
@@ -437,13 +440,16 @@ CodeCompleteConsumer::~CodeCompleteConsumer() { }
 
 void 
 PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
-                                                         Result *Results, 
+                                                 CodeCompletionContext Context,
+                                                 CodeCompletionResult *Results,
                                                          unsigned NumResults) {
+  std::stable_sort(Results, Results + NumResults);
+  
   // Print the results.
   for (unsigned I = 0; I != NumResults; ++I) {
     OS << "COMPLETION: ";
     switch (Results[I].Kind) {
-    case Result::RK_Declaration:
+    case CodeCompletionResult::RK_Declaration:
       OS << Results[I].Declaration;
       if (Results[I].Hidden)
         OS << " (Hidden)";
@@ -456,11 +462,11 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
       OS << '\n';
       break;
       
-    case Result::RK_Keyword:
+    case CodeCompletionResult::RK_Keyword:
       OS << Results[I].Keyword << '\n';
       break;
         
-    case Result::RK_Macro: {
+    case CodeCompletionResult::RK_Macro: {
       OS << Results[I].Macro->getName();
       if (CodeCompletionString *CCS 
             = Results[I].CreateCodeCompletionString(SemaRef)) {
@@ -471,7 +477,7 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
       break;
     }
         
-    case Result::RK_Pattern: {
+    case CodeCompletionResult::RK_Pattern: {
       OS << "Pattern : " 
          << Results[I].Pattern->getAsString() << '\n';
       break;
@@ -494,116 +500,104 @@ PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
   }
 }
 
+void CodeCompletionResult::computeCursorKindAndAvailability() {
+  switch (Kind) {
+  case RK_Declaration:
+    // Set the availability based on attributes.
+    Availability = CXAvailability_Available;      
+    if (Declaration->getAttr<UnavailableAttr>())
+      Availability = CXAvailability_NotAvailable;
+    else if (Declaration->getAttr<DeprecatedAttr>())
+      Availability = CXAvailability_Deprecated;
+      
+    if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
+      if (Function->isDeleted())
+        Availability = CXAvailability_NotAvailable;
+      
+    CursorKind = getCursorKindForDecl(Declaration);
+    if (CursorKind == CXCursor_UnexposedDecl)
+      CursorKind = CXCursor_NotImplemented;
+    break;
+
+  case RK_Macro:
+    Availability = CXAvailability_Available;      
+    CursorKind = CXCursor_MacroDefinition;
+    break;
+      
+  case RK_Keyword:
+    Availability = CXAvailability_Available;      
+    CursorKind = CXCursor_NotImplemented;
+    break;
+      
+  case RK_Pattern:
+    // Do nothing: Patterns can come with cursor kinds!
+    break;
+  }
+}
+
+/// \brief Retrieve the name that should be used to order a result.
+///
+/// If the name needs to be constructed as a string, that string will be
+/// saved into Saved and the returned StringRef will refer to it.
+static llvm::StringRef getOrderedName(const CodeCompletionResult &R,
+                                    std::string &Saved) {
+  switch (R.Kind) {
+    case CodeCompletionResult::RK_Keyword:
+      return R.Keyword;
+      
+    case CodeCompletionResult::RK_Pattern:
+      return R.Pattern->getTypedText();
+      
+    case CodeCompletionResult::RK_Macro:
+      return R.Macro->getName();
+      
+    case CodeCompletionResult::RK_Declaration:
+      // Handle declarations below.
+      break;
+  }
+  
+  DeclarationName Name = R.Declaration->getDeclName();
+  
+  // If the name is a simple identifier (by far the common case), or a
+  // zero-argument selector, just return a reference to that identifier.
+  if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
+    return Id->getName();
+  if (Name.isObjCZeroArgSelector())
+    if (IdentifierInfo *Id
+        = Name.getObjCSelector().getIdentifierInfoForSlot(0))
+      return Id->getName();
+  
+  Saved = Name.getAsString();
+  return Saved;
+}
+    
+bool clang::operator<(const CodeCompletionResult &X, 
+                      const CodeCompletionResult &Y) {
+  std::string XSaved, YSaved;
+  llvm::StringRef XStr = getOrderedName(X, XSaved);
+  llvm::StringRef YStr = getOrderedName(Y, YSaved);
+  int cmp = XStr.compare_lower(YStr);
+  if (cmp)
+    return cmp < 0;
+  
+  // If case-insensitive comparison fails, try case-sensitive comparison.
+  cmp = XStr.compare(YStr);
+  if (cmp)
+    return cmp < 0;
+  
+  return false;
+}
+
 void 
 CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
-                                                       Result *Results, 
+                                                 CodeCompletionContext Context,
+                                                 CodeCompletionResult *Results,
                                                        unsigned NumResults) {
   // Print the results.
   for (unsigned I = 0; I != NumResults; ++I) {
-    CXCursorKind Kind = CXCursor_NotImplemented;
-
-    switch (Results[I].Kind) {
-    case Result::RK_Declaration:
-      switch (Results[I].Declaration->getKind()) {
-      case Decl::Record:
-      case Decl::CXXRecord:
-      case Decl::ClassTemplateSpecialization: {
-        RecordDecl *Record = cast<RecordDecl>(Results[I].Declaration);
-        if (Record->isStruct())
-          Kind = CXCursor_StructDecl;
-        else if (Record->isUnion())
-          Kind = CXCursor_UnionDecl;
-        else
-          Kind = CXCursor_ClassDecl;
-        break;
-      }
-        
-      case Decl::ObjCMethod: {
-        ObjCMethodDecl *Method = cast<ObjCMethodDecl>(Results[I].Declaration);
-        if (Method->isInstanceMethod())
-            Kind = CXCursor_ObjCInstanceMethodDecl;
-        else
-          Kind = CXCursor_ObjCClassMethodDecl;
-        break;
-      }
-        
-      case Decl::Typedef:
-        Kind = CXCursor_TypedefDecl;
-        break;
-        
-      case Decl::Enum:
-        Kind = CXCursor_EnumDecl;
-        break;
-        
-      case Decl::Field:
-        Kind = CXCursor_FieldDecl;
-        break;
-        
-      case Decl::EnumConstant:
-        Kind = CXCursor_EnumConstantDecl;
-        break;
-        
-      case Decl::Function:
-      case Decl::CXXMethod:
-      case Decl::CXXConstructor:
-      case Decl::CXXDestructor:
-      case Decl::CXXConversion:
-        Kind = CXCursor_FunctionDecl;
-        break;
-        
-      case Decl::Var:
-        Kind = CXCursor_VarDecl;
-        break;
-        
-      case Decl::ParmVar:
-        Kind = CXCursor_ParmDecl;
-        break;
-        
-      case Decl::ObjCInterface:
-        Kind = CXCursor_ObjCInterfaceDecl;
-        break;
-        
-      case Decl::ObjCCategory:
-        Kind = CXCursor_ObjCCategoryDecl;
-        break;
-        
-      case Decl::ObjCProtocol:
-        Kind = CXCursor_ObjCProtocolDecl;
-        break;
-        
-      case Decl::ObjCProperty:
-        Kind = CXCursor_ObjCPropertyDecl;
-        break;
-        
-      case Decl::ObjCIvar:
-        Kind = CXCursor_ObjCIvarDecl;
-        break;
-        
-      case Decl::ObjCImplementation:
-        Kind = CXCursor_ObjCImplementationDecl;
-        break;
-        
-      case Decl::ObjCCategoryImpl:
-        Kind = CXCursor_ObjCCategoryImplDecl;
-        break;
-        
-      default:
-        break;
-      }
-      break;
-
-    case Result::RK_Macro:
-      Kind = CXCursor_MacroDefinition;
-      break;
-
-    case Result::RK_Keyword:
-    case Result::RK_Pattern:
-      Kind = CXCursor_NotImplemented;
-      break;
-    }
-
-    WriteUnsigned(OS, Kind);
+    WriteUnsigned(OS, Results[I].CursorKind);
     WriteUnsigned(OS, Results[I].Priority);
+    WriteUnsigned(OS, Results[I].Availability);
     CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(SemaRef);
     assert(CCS && "No code-completion string?");
     CCS->Serialize(OS);
@@ -618,7 +612,8 @@ CIndexCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
                                                        unsigned NumCandidates) {
   for (unsigned I = 0; I != NumCandidates; ++I) {
     WriteUnsigned(OS, CXCursor_NotImplemented);
-    WriteUnsigned(OS, /*Priority=*/0);
+    WriteUnsigned(OS, /*Priority=*/I);
+    WriteUnsigned(OS, /*Availability=*/CXAvailability_Available);
     CodeCompletionString *CCS
       = Candidates[I].CreateSignatureString(CurrentArg, SemaRef);
     assert(CCS && "No code-completion string?");
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
new file mode 100644
index 0000000..b46e8af
--- /dev/null
+++ b/lib/Sema/DeclSpec.cpp
@@ -0,0 +1,667 @@
+//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements semantic analysis for declaration specifiers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Parse/ParseDiagnostic.h" // FIXME: remove this back-dependency!
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cstring>
+using namespace clang;
+
+
+static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc,
+                              SourceManager &SrcMgr, unsigned DiagID) {
+  return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID);
+}
+
+
+void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) {
+  assert(TemplateId && "NULL template-id annotation?");
+  Kind = IK_TemplateId;
+  this->TemplateId = TemplateId;
+  StartLocation = TemplateId->TemplateNameLoc;
+  EndLocation = TemplateId->RAngleLoc;
+}
+
+void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
+  assert(TemplateId && "NULL template-id annotation?");
+  Kind = IK_ConstructorTemplateId;
+  this->TemplateId = TemplateId;
+  StartLocation = TemplateId->TemplateNameLoc;
+  EndLocation = TemplateId->RAngleLoc;
+}
+
+/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
+/// "TheDeclarator" is the declarator that this will be added to.
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+                                             SourceLocation EllipsisLoc,
+                                             ParamInfo *ArgInfo,
+                                             unsigned NumArgs,
+                                             unsigned TypeQuals,
+                                             bool hasExceptionSpec,
+                                             SourceLocation ThrowLoc,
+                                             bool hasAnyExceptionSpec,
+                                             ParsedType *Exceptions,
+                                             SourceRange *ExceptionRanges,
+                                             unsigned NumExceptions,
+                                             SourceLocation LPLoc,
+                                             SourceLocation RPLoc,
+                                             Declarator &TheDeclarator) {
+  DeclaratorChunk I;
+  I.Kind                 = Function;
+  I.Loc                  = LPLoc;
+  I.EndLoc               = RPLoc;
+  I.Fun.hasPrototype     = hasProto;
+  I.Fun.isVariadic       = isVariadic;
+  I.Fun.EllipsisLoc      = EllipsisLoc.getRawEncoding();
+  I.Fun.DeleteArgInfo    = false;
+  I.Fun.TypeQuals        = TypeQuals;
+  I.Fun.NumArgs          = NumArgs;
+  I.Fun.ArgInfo          = 0;
+  I.Fun.hasExceptionSpec = hasExceptionSpec;
+  I.Fun.ThrowLoc         = ThrowLoc.getRawEncoding();
+  I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
+  I.Fun.NumExceptions    = NumExceptions;
+  I.Fun.Exceptions       = 0;
+
+  // new[] an argument array if needed.
+  if (NumArgs) {
+    // If the 'InlineParams' in Declarator is unused and big enough, put our
+    // parameter list there (in an effort to avoid new/delete traffic).  If it
+    // is already used (consider a function returning a function pointer) or too
+    // small (function taking too many arguments), go to the heap.
+    if (!TheDeclarator.InlineParamsUsed &&
+        NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) {
+      I.Fun.ArgInfo = TheDeclarator.InlineParams;
+      I.Fun.DeleteArgInfo = false;
+      TheDeclarator.InlineParamsUsed = true;
+    } else {
+      I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs];
+      I.Fun.DeleteArgInfo = true;
+    }
+    memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs);
+  }
+  // new[] an exception array if needed
+  if (NumExceptions) {
+    I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions];
+    for (unsigned i = 0; i != NumExceptions; ++i) {
+      I.Fun.Exceptions[i].Ty = Exceptions[i];
+      I.Fun.Exceptions[i].Range = ExceptionRanges[i];
+    }
+  }
+  return I;
+}
+
+/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this
+/// declaration specifier includes.
+///
+unsigned DeclSpec::getParsedSpecifiers() const {
+  unsigned Res = 0;
+  if (StorageClassSpec != SCS_unspecified ||
+      SCS_thread_specified)
+    Res |= PQ_StorageClassSpecifier;
+
+  if (TypeQualifiers != TQ_unspecified)
+    Res |= PQ_TypeQualifier;
+
+  if (hasTypeSpecifier())
+    Res |= PQ_TypeSpecifier;
+
+  if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified)
+    Res |= PQ_FunctionSpecifier;
+  return Res;
+}
+
+template <class T> static bool BadSpecifier(T TNew, T TPrev,
+                                            const char *&PrevSpec,
+                                            unsigned &DiagID) {
+  PrevSpec = DeclSpec::getSpecifierName(TPrev);
+  DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
+            : diag::err_invalid_decl_spec_combination);
+  return true;
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) {
+  switch (S) {
+  case DeclSpec::SCS_unspecified: return "unspecified";
+  case DeclSpec::SCS_typedef:     return "typedef";
+  case DeclSpec::SCS_extern:      return "extern";
+  case DeclSpec::SCS_static:      return "static";
+  case DeclSpec::SCS_auto:        return "auto";
+  case DeclSpec::SCS_register:    return "register";
+  case DeclSpec::SCS_private_extern: return "__private_extern__";
+  case DeclSpec::SCS_mutable:     return "mutable";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TSW W) {
+  switch (W) {
+  case TSW_unspecified: return "unspecified";
+  case TSW_short:       return "short";
+  case TSW_long:        return "long";
+  case TSW_longlong:    return "long long";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TSC C) {
+  switch (C) {
+  case TSC_unspecified: return "unspecified";
+  case TSC_imaginary:   return "imaginary";
+  case TSC_complex:     return "complex";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+
+const char *DeclSpec::getSpecifierName(TSS S) {
+  switch (S) {
+  case TSS_unspecified: return "unspecified";
+  case TSS_signed:      return "signed";
+  case TSS_unsigned:    return "unsigned";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
+  switch (T) {
+  case DeclSpec::TST_unspecified: return "unspecified";
+  case DeclSpec::TST_void:        return "void";
+  case DeclSpec::TST_char:        return "char";
+  case DeclSpec::TST_wchar:       return "wchar_t";
+  case DeclSpec::TST_char16:      return "char16_t";
+  case DeclSpec::TST_char32:      return "char32_t";
+  case DeclSpec::TST_int:         return "int";
+  case DeclSpec::TST_float:       return "float";
+  case DeclSpec::TST_double:      return "double";
+  case DeclSpec::TST_bool:        return "_Bool";
+  case DeclSpec::TST_decimal32:   return "_Decimal32";
+  case DeclSpec::TST_decimal64:   return "_Decimal64";
+  case DeclSpec::TST_decimal128:  return "_Decimal128";
+  case DeclSpec::TST_enum:        return "enum";
+  case DeclSpec::TST_class:       return "class";
+  case DeclSpec::TST_union:       return "union";
+  case DeclSpec::TST_struct:      return "struct";
+  case DeclSpec::TST_typename:    return "type-name";
+  case DeclSpec::TST_typeofType:
+  case DeclSpec::TST_typeofExpr:  return "typeof";
+  case DeclSpec::TST_auto:        return "auto";
+  case DeclSpec::TST_decltype:    return "(decltype)";
+  case DeclSpec::TST_error:       return "(error)";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+const char *DeclSpec::getSpecifierName(TQ T) {
+  switch (T) {
+  case DeclSpec::TQ_unspecified: return "unspecified";
+  case DeclSpec::TQ_const:       return "const";
+  case DeclSpec::TQ_restrict:    return "restrict";
+  case DeclSpec::TQ_volatile:    return "volatile";
+  }
+  llvm_unreachable("Unknown typespec!");
+}
+
+bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc,
+                                   const char *&PrevSpec,
+                                   unsigned &DiagID) {
+  if (StorageClassSpec != SCS_unspecified) {
+    // Changing storage class is allowed only if the previous one
+    // was the 'extern' that is part of a linkage specification and
+    // the new storage class is 'typedef'.
+    if (!(SCS_extern_in_linkage_spec &&
+          StorageClassSpec == SCS_extern &&
+          S == SCS_typedef))
+      return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID);
+  }
+  StorageClassSpec = S;
+  StorageClassSpecLoc = Loc;
+  assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield");
+  return false;
+}
+
+bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc,
+                                         const char *&PrevSpec,
+                                         unsigned &DiagID) {
+  if (SCS_thread_specified) {
+    PrevSpec = "__thread";
+    DiagID = diag::ext_duplicate_declspec;
+    return true;
+  }
+  SCS_thread_specified = true;
+  SCS_threadLoc = Loc;
+  return false;
+}
+
+/// These methods set the specified attribute of the DeclSpec, but return true
+/// and ignore the request if invalid (e.g. "extern" then "auto" is
+/// specified).
+bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc,
+                                const char *&PrevSpec,
+                                unsigned &DiagID) {
+  if (TypeSpecWidth != TSW_unspecified &&
+      // Allow turning long -> long long.
+      (W != TSW_longlong || TypeSpecWidth != TSW_long))
+    return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID);
+  TypeSpecWidth = W;
+  TSWLoc = Loc;
+  if (TypeAltiVecVector && !TypeAltiVecBool &&
+      ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::warn_vector_long_decl_spec_combination;
+    return true;
+  }
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc,
+                                  const char *&PrevSpec,
+                                  unsigned &DiagID) {
+  if (TypeSpecComplex != TSC_unspecified)
+    return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
+  TypeSpecComplex = C;
+  TSCLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID) {
+  if (TypeSpecSign != TSS_unspecified)
+    return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID);
+  TypeSpecSign = S;
+  TSSLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               ParsedType Rep) {
+  assert(isTypeRep(T) && "T does not store a type");
+  assert(Rep && "no type provided!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  TypeRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               Expr *Rep) {
+  assert(isExprRep(T) && "T does not store an expr");
+  assert(Rep && "no expression provided!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  ExprRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID,
+                               Decl *Rep, bool Owned) {
+  assert(isDeclRep(T) && "T does not store a decl");
+  // Unlike the other cases, we don't assert that we actually get a decl.
+
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  TypeSpecType = T;
+  DeclRep = Rep;
+  TSTLoc = Loc;
+  TypeSpecOwned = Owned;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc,
+                               const char *&PrevSpec,
+                               unsigned &DiagID) {
+  assert(!isDeclRep(T) && !isTypeRep(T) && !isExprRep(T) &&
+         "rep required for these type-spec kinds!");
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_decl_spec_combination;
+    return true;
+  }
+  if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
+    TypeAltiVecBool = true;
+    TSTLoc = Loc;
+    return false;
+  }
+  TypeSpecType = T;
+  TSTLoc = Loc;
+  TypeSpecOwned = false;
+  if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_vector_decl_spec;
+    return true;
+  }
+  return false;
+}
+
+bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc,
+                          const char *&PrevSpec, unsigned &DiagID) {
+  if (TypeSpecType != TST_unspecified) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_vector_decl_spec_combination;
+    return true;
+  }
+  TypeAltiVecVector = isAltiVecVector;
+  AltiVecLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,
+                          const char *&PrevSpec, unsigned &DiagID) {
+  if (!TypeAltiVecVector || TypeAltiVecPixel ||
+      (TypeSpecType != TST_unspecified)) {
+    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+    DiagID = diag::err_invalid_pixel_decl_spec_combination;
+    return true;
+  }
+  TypeAltiVecPixel = isAltiVecPixel;
+  TSTLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetTypeSpecError() {
+  TypeSpecType = TST_error;
+  TypeSpecOwned = false;
+  TSTLoc = SourceLocation();
+  return false;
+}
+
+bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
+                           unsigned &DiagID, const LangOptions &Lang) {
+  // Duplicates turn into warnings pre-C99.
+  if ((TypeQualifiers & T) && !Lang.C99)
+    return BadSpecifier(T, T, PrevSpec, DiagID);
+  TypeQualifiers |= T;
+
+  switch (T) {
+  default: assert(0 && "Unknown type qualifier!");
+  case TQ_const:    TQ_constLoc = Loc; break;
+  case TQ_restrict: TQ_restrictLoc = Loc; break;
+  case TQ_volatile: TQ_volatileLoc = Loc; break;
+  }
+  return false;
+}
+
+bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec,
+                                     unsigned &DiagID) {
+  // 'inline inline' is ok.
+  FS_inline_specified = true;
+  FS_inlineLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec,
+                                      unsigned &DiagID) {
+  // 'virtual virtual' is ok.
+  FS_virtual_specified = true;
+  FS_virtualLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec,
+                                       unsigned &DiagID) {
+  // 'explicit explicit' is ok.
+  FS_explicit_specified = true;
+  FS_explicitLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec,
+                             unsigned &DiagID) {
+  if (Friend_specified) {
+    PrevSpec = "friend";
+    DiagID = diag::ext_duplicate_declspec;
+    return true;
+  }
+
+  Friend_specified = true;
+  FriendLoc = Loc;
+  return false;
+}
+
+bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec,
+                                unsigned &DiagID) {
+  // 'constexpr constexpr' is ok.
+  Constexpr_specified = true;
+  ConstexprLoc = Loc;
+  return false;
+}
+
+void DeclSpec::setProtocolQualifiers(Decl * const *Protos,
+                                     unsigned NP,
+                                     SourceLocation *ProtoLocs,
+                                     SourceLocation LAngleLoc) {
+  if (NP == 0) return;
+  ProtocolQualifiers = new Decl*[NP];
+  ProtocolLocs = new SourceLocation[NP];
+  memcpy((void*)ProtocolQualifiers, Protos, sizeof(Decl*)*NP);
+  memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP);
+  NumProtocolQualifiers = NP;
+  ProtocolLAngleLoc = LAngleLoc;
+}
+
+void DeclSpec::SaveWrittenBuiltinSpecs() {
+  writtenBS.Sign = getTypeSpecSign();
+  writtenBS.Width = getTypeSpecWidth();
+  writtenBS.Type = getTypeSpecType();
+  // Search the list of attributes for the presence of a mode attribute.
+  writtenBS.ModeAttr = false;
+  AttributeList* attrs = getAttributes();
+  while (attrs) {
+    if (attrs->getKind() == AttributeList::AT_mode) {
+      writtenBS.ModeAttr = true;
+      break;
+    }
+    attrs = attrs->getNext();
+  }
+}
+
+void DeclSpec::SaveStorageSpecifierAsWritten() {
+  if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern)
+    // If 'extern' is part of a linkage specification,
+    // then it is not a storage class "as written".
+    StorageClassSpecAsWritten = SCS_unspecified;
+  else
+    StorageClassSpecAsWritten = StorageClassSpec;
+}
+
+/// Finish - This does final analysis of the declspec, rejecting things like
+/// "_Imaginary" (lacking an FP type).  This returns a diagnostic to issue or
+/// diag::NUM_DIAGNOSTICS if there is no error.  After calling this method,
+/// DeclSpec is guaranteed self-consistent, even if an error occurred.
+void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) {
+  // Before possibly changing their values, save specs as written.
+  SaveWrittenBuiltinSpecs();
+  SaveStorageSpecifierAsWritten();
+
+  // Check the type specifier components first.
+  SourceManager &SrcMgr = PP.getSourceManager();
+
+  // Validate and finalize AltiVec vector declspec.
+  if (TypeAltiVecVector) {
+    if (TypeAltiVecBool) {
+      // Sign specifiers are not allowed with vector bool. (PIM 2.1)
+      if (TypeSpecSign != TSS_unspecified) {
+        Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+          << getSpecifierName((TSS)TypeSpecSign);
+      }
+
+      // Only char/int are valid with vector bool. (PIM 2.1)
+      if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) &&
+           (TypeSpecType != TST_int)) || TypeAltiVecPixel) {
+        Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+          << (TypeAltiVecPixel ? "__pixel" :
+                                 getSpecifierName((TST)TypeSpecType));
+      }
+
+      // Only 'short' is valid with vector bool. (PIM 2.1)
+      if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short))
+        Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec)
+          << getSpecifierName((TSW)TypeSpecWidth);
+
+      // Elements of vector bool are interpreted as unsigned. (PIM 2.1)
+      if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
+          (TypeSpecWidth != TSW_unspecified))
+        TypeSpecSign = TSS_unsigned;
+    }
+
+    if (TypeAltiVecPixel) {
+      //TODO: perform validation
+      TypeSpecType = TST_int;
+      TypeSpecSign = TSS_unsigned;
+      TypeSpecWidth = TSW_short;
+      TypeSpecOwned = false;
+    }
+  }
+
+  // signed/unsigned are only valid with int/char/wchar_t.
+  if (TypeSpecSign != TSS_unspecified) {
+    if (TypeSpecType == TST_unspecified)
+      TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
+    else if (TypeSpecType != TST_int  &&
+             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
+      Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec)
+        << getSpecifierName((TST)TypeSpecType);
+      // signed double -> double.
+      TypeSpecSign = TSS_unspecified;
+    }
+  }
+
+  // Validate the width of the type.
+  switch (TypeSpecWidth) {
+  case TSW_unspecified: break;
+  case TSW_short:    // short int
+  case TSW_longlong: // long long int
+    if (TypeSpecType == TST_unspecified)
+      TypeSpecType = TST_int; // short -> short int, long long -> long long int.
+    else if (TypeSpecType != TST_int) {
+      Diag(D, TSWLoc, SrcMgr,
+           TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec
+                                      : diag::err_invalid_longlong_spec)
+        <<  getSpecifierName((TST)TypeSpecType);
+      TypeSpecType = TST_int;
+      TypeSpecOwned = false;
+    }
+    break;
+  case TSW_long:  // long double, long int
+    if (TypeSpecType == TST_unspecified)
+      TypeSpecType = TST_int;  // long -> long int.
+    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
+      Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec)
+        << getSpecifierName((TST)TypeSpecType);
+      TypeSpecType = TST_int;
+      TypeSpecOwned = false;
+    }
+    break;
+  }
+
+  // TODO: if the implementation does not implement _Complex or _Imaginary,
+  // disallow their use.  Need information about the backend.
+  if (TypeSpecComplex != TSC_unspecified) {
+    if (TypeSpecType == TST_unspecified) {
+      Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex)
+        << FixItHint::CreateInsertion(
+                              PP.getLocForEndOfToken(getTypeSpecComplexLoc()),
+                                                 " double");
+      TypeSpecType = TST_double;   // _Complex -> _Complex double.
+    } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
+      // Note that this intentionally doesn't include _Complex _Bool.
+      Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex);
+    } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) {
+      Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec)
+        << getSpecifierName((TST)TypeSpecType);
+      TypeSpecComplex = TSC_unspecified;
+    }
+  }
+
+  // C++ [class.friend]p6:
+  //   No storage-class-specifier shall appear in the decl-specifier-seq
+  //   of a friend declaration.
+  if (isFriendSpecified() && getStorageClassSpec()) {
+    DeclSpec::SCS SC = getStorageClassSpec();
+    const char *SpecName = getSpecifierName(SC);
+
+    SourceLocation SCLoc = getStorageClassSpecLoc();
+    SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName));
+
+    Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec)
+      << SpecName
+      << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc));
+
+    ClearStorageClassSpecs();
+  }
+
+  assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
+
+  // Okay, now we can infer the real type.
+
+  // TODO: return "auto function" and other bad things based on the real type.
+
+  // 'data definition has no type or storage class'?
+}
+
+bool DeclSpec::isMissingDeclaratorOk() {
+  TST tst = getTypeSpecType();
+  return isDeclRep(tst) && getRepAsDecl() != 0 &&
+    StorageClassSpec != DeclSpec::SCS_typedef;
+}
+
+void UnqualifiedId::clear() {
+  if (Kind == IK_TemplateId)
+    TemplateId->Destroy();
+  
+  Kind = IK_Identifier;
+  Identifier = 0;
+  StartLocation = SourceLocation();
+  EndLocation = SourceLocation();
+}
+
+void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, 
+                                          OverloadedOperatorKind Op,
+                                          SourceLocation SymbolLocations[3]) {
+  Kind = IK_OperatorFunctionId;
+  StartLocation = OperatorLoc;
+  EndLocation = OperatorLoc;
+  OperatorFunctionId.Operator = Op;
+  for (unsigned I = 0; I != 3; ++I) {
+    OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding();
+    
+    if (SymbolLocations[I].isValid())
+      EndLocation = SymbolLocations[I];
+  }
+}
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index b09526e..3f16ed7 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -12,7 +12,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "IdentifierResolver.h"
+#include "clang/Sema/IdentifierResolver.h"
+#include "clang/Sema/Scope.h"
+#include "clang/AST/Decl.h"
 #include "clang/Basic/LangOptions.h"
 
 using namespace clang;
@@ -103,7 +105,7 @@ IdentifierResolver::~IdentifierResolver() {
 /// true if 'D' belongs to the given declaration context.
 bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
                                        ASTContext &Context, Scope *S) const {
-  Ctx = Ctx->getLookupContext();
+  Ctx = Ctx->getRedeclContext();
 
   if (Ctx->isFunctionOrMethod()) {
     // Ignore the scopes associated within transparent declaration contexts.
@@ -111,7 +113,7 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
            ((DeclContext *)S->getEntity())->isTransparentContext())
       S = S->getParent();
 
-    if (S->isDeclScope(Action::DeclPtrTy::make(D)))
+    if (S->isDeclScope(D))
       return true;
     if (LangOpt.CPlusPlus) {
       // C++ 3.3.2p3:
@@ -128,17 +130,20 @@ bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
       //
       assert(S->getParent() && "No TUScope?");
       if (S->getParent()->getFlags() & Scope::ControlScope)
-        return S->getParent()->isDeclScope(Action::DeclPtrTy::make(D));
+        return S->getParent()->isDeclScope(D);
     }
     return false;
   }
 
-  return D->getDeclContext()->getLookupContext()->Equals(Ctx);
+  return D->getDeclContext()->getRedeclContext()->Equals(Ctx);
 }
 
 /// AddDecl - Link the decl to its shadowed decl chain.
 void IdentifierResolver::AddDecl(NamedDecl *D) {
   DeclarationName Name = D->getDeclName();
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+    II->setIsFromAST(false);
+
   void *Ptr = Name.getFETokenInfo<void>();
 
   if (!Ptr) {
@@ -164,6 +169,9 @@ void IdentifierResolver::AddDecl(NamedDecl *D) {
 void IdentifierResolver::RemoveDecl(NamedDecl *D) {
   assert(D && "null param passed");
   DeclarationName Name = D->getDeclName();
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+    II->setIsFromAST(false);
+
   void *Ptr = Name.getFETokenInfo<void>();
 
   assert(Ptr && "Didn't find this decl on its identifier's chain!");
@@ -182,6 +190,9 @@ bool IdentifierResolver::ReplaceDecl(NamedDecl *Old, NamedDecl *New) {
          "Cannot replace a decl with another decl of a different name");
 
   DeclarationName Name = Old->getDeclName();
+  if (IdentifierInfo *II = Name.getAsIdentifierInfo())
+    II->setIsFromAST(false);
+
   void *Ptr = Name.getFETokenInfo<void>();
 
   if (!Ptr)
@@ -218,6 +229,7 @@ IdentifierResolver::begin(DeclarationName Name) {
 
 void IdentifierResolver::AddDeclToIdentifierChain(IdentifierInfo *II,
                                                   NamedDecl *D) {
+  II->setIsFromAST(false);
   void *Ptr = II->getFETokenInfo<void>();
 
   if (!Ptr) {
@@ -261,3 +273,16 @@ IdentifierResolver::IdDeclInfoMap::operator[](DeclarationName Name) {
   ++CurIndex;
   return *IDI;
 }
+
+void IdentifierResolver::iterator::incrementSlowCase() {
+  NamedDecl *D = **this;
+  void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
+  assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
+  IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
+
+  BaseIter I = getIterator();
+  if (I != Info->decls_begin())
+    *this = iterator(I-1);
+  else // No more decls.
+    *this = iterator();
+}
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
deleted file mode 100644
index 59bd834..0000000
--- a/lib/Sema/IdentifierResolver.h
+++ /dev/null
@@ -1,203 +0,0 @@
-//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the IdentifierResolver class, which is used for lexical
-// scoped lookup, based on declaration names.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
-
-#include "clang/Basic/IdentifierTable.h"
-#include "clang/Parse/Scope.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/DeclCXX.h"
-
-namespace clang {
-
-/// IdentifierResolver - Keeps track of shadowed decls on enclosing
-/// scopes.  It manages the shadowing chains of declaration names and
-/// implements efficent decl lookup based on a declaration name.
-class IdentifierResolver {
-
-  /// IdDeclInfo - Keeps track of information about decls associated
-  /// to a particular declaration name. IdDeclInfos are lazily
-  /// constructed and assigned to a declaration name the first time a
-  /// decl with that declaration name is shadowed in some scope.
-  class IdDeclInfo {
-  public:
-    typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy;
-
-    inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
-    inline DeclsTy::iterator decls_end() { return Decls.end(); }
-
-    void AddDecl(NamedDecl *D) { Decls.push_back(D); }
-
-    /// RemoveDecl - Remove the decl from the scope chain.
-    /// The decl must already be part of the decl chain.
-    void RemoveDecl(NamedDecl *D);
-
-    /// Replaces the Old declaration with the New declaration. If the
-    /// replacement is successful, returns true. If the old
-    /// declaration was not found, returns false.
-    bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
-
-  private:
-    DeclsTy Decls;
-  };
-
-public:
-
-  /// iterator - Iterate over the decls of a specified declaration name.
-  /// It will walk or not the parent declaration contexts depending on how
-  /// it was instantiated.
-  class iterator {
-  public:
-    typedef NamedDecl *             value_type;
-    typedef NamedDecl *             reference;
-    typedef NamedDecl *             pointer;
-    typedef std::input_iterator_tag iterator_category;
-    typedef std::ptrdiff_t          difference_type;
-
-    /// Ptr - There are 3 forms that 'Ptr' represents:
-    /// 1) A single NamedDecl. (Ptr & 0x1 == 0)
-    /// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
-    ///    same declaration context. (Ptr & 0x3 == 0x1)
-    /// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
-    ///    declaration contexts too. (Ptr & 0x3 == 0x3)
-    uintptr_t Ptr;
-    typedef IdDeclInfo::DeclsTy::iterator BaseIter;
-
-    /// A single NamedDecl. (Ptr & 0x1 == 0)
-    iterator(NamedDecl *D) {
-      Ptr = reinterpret_cast<uintptr_t>(D);
-      assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
-    }
-    /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
-    /// contexts depending on 'LookInParentCtx'.
-    iterator(BaseIter I) {
-      Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
-    }
-
-    bool isIterator() const { return (Ptr & 0x1); }
-
-    BaseIter getIterator() const {
-      assert(isIterator() && "Ptr not an iterator!");
-      return reinterpret_cast<BaseIter>(Ptr & ~0x3);
-    }
-
-    friend class IdentifierResolver;
-  public:
-    iterator() : Ptr(0) {}
-
-    NamedDecl *operator*() const {
-      if (isIterator())
-        return *getIterator();
-      else
-        return reinterpret_cast<NamedDecl*>(Ptr);
-    }
-
-    bool operator==(const iterator &RHS) const {
-      return Ptr == RHS.Ptr;
-    }
-    bool operator!=(const iterator &RHS) const {
-      return Ptr != RHS.Ptr;
-    }
-
-    // Preincrement.
-    iterator& operator++() {
-      if (!isIterator()) // common case.
-        Ptr = 0;
-      else {
-        NamedDecl *D = **this;
-        void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
-        assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
-        IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
-
-        BaseIter I = getIterator();
-        if (I != Info->decls_begin())
-          *this = iterator(I-1);
-        else // No more decls.
-          *this = iterator();
-      }
-      return *this;
-    }
-
-    uintptr_t getAsOpaqueValue() const { return Ptr; }
-
-    static iterator getFromOpaqueValue(uintptr_t P) {
-      iterator Result;
-      Result.Ptr = P;
-      return Result;
-    }
-  };
-
-  /// begin - Returns an iterator for decls with the name 'Name'.
-  static iterator begin(DeclarationName Name);
-
-  /// end - Returns an iterator that has 'finished'.
-  static iterator end() {
-    return iterator();
-  }
-
-  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
-  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
-  /// true if 'D' belongs to the given declaration context.
-  bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
-                     Scope *S = 0) const;
-
-  /// AddDecl - Link the decl to its shadowed decl chain.
-  void AddDecl(NamedDecl *D);
-
-  /// RemoveDecl - Unlink the decl from its shadowed decl chain.
-  /// The decl must already be part of the decl chain.
-  void RemoveDecl(NamedDecl *D);
-
-  /// Replace the decl Old with the new declaration New on its
-  /// identifier chain. Returns true if the old declaration was found
-  /// (and, therefore, replaced).
-  bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
-
-  /// \brief Link the declaration into the chain of declarations for
-  /// the given identifier.
-  ///
-  /// This is a lower-level routine used by the PCH reader to link a
-  /// declaration into a specific IdentifierInfo before the
-  /// declaration actually has a name.
-  void AddDeclToIdentifierChain(IdentifierInfo *II, NamedDecl *D);
-
-  explicit IdentifierResolver(const LangOptions &LangOpt);
-  ~IdentifierResolver();
-
-private:
-  const LangOptions &LangOpt;
-
-  class IdDeclInfoMap;
-  IdDeclInfoMap *IdDeclInfos;
-
-  /// FETokenInfo contains a Decl pointer if lower bit == 0.
-  static inline bool isDeclPtr(void *Ptr) {
-    return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
-  }
-
-  /// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
-  static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
-    assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
-          && "Ptr not a IdDeclInfo* !");
-    return reinterpret_cast<IdDeclInfo*>(
-                    reinterpret_cast<uintptr_t>(Ptr) & ~0x1
-                                                            );
-  }
-};
-
-} // end namespace clang
-
-#endif
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 3431ac6..b23f615 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -12,11 +12,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/ADT/BitVector.h"
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/StmtCXX.h"
+#include "llvm/ADT/BitVector.h"
 using namespace clang;
 
 namespace {
@@ -180,12 +181,6 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
   
   // If we found a label, remember that it is in ParentScope scope.
   switch (S->getStmtClass()) {
-  case Stmt::LabelStmtClass:
-  case Stmt::DefaultStmtClass:
-  case Stmt::CaseStmtClass:
-    LabelAndGotoScopes[S] = ParentScope;
-    break;
-
   case Stmt::AddrLabelExprClass:
     IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
     break;
@@ -225,6 +220,24 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
     Stmt *SubStmt = *CI;
     if (SubStmt == 0) continue;
 
+    // Cases, labels, and defaults aren't "scope parents".  It's also
+    // important to handle these iteratively instead of recursively in
+    // order to avoid blowing out the stack.
+    while (true) {
+      Stmt *Next;
+      if (isa<CaseStmt>(SubStmt))
+        Next = cast<CaseStmt>(SubStmt)->getSubStmt();
+      else if (isa<DefaultStmt>(SubStmt))
+        Next = cast<DefaultStmt>(SubStmt)->getSubStmt();
+      else if (isa<LabelStmt>(SubStmt))
+        Next = cast<LabelStmt>(SubStmt)->getSubStmt();
+      else
+        break;
+
+      LabelAndGotoScopes[SubStmt] = ParentScope;
+      SubStmt = Next;
+    }
+
     // If this is a declstmt with a VLA definition, it defines a scope from here
     // to the end of the containing context.
     if (DeclStmt *DS = dyn_cast<DeclStmt>(SubStmt)) {
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
deleted file mode 100644
index 271bb5b..0000000
--- a/lib/Sema/Lookup.h
+++ /dev/null
@@ -1,654 +0,0 @@
-//===--- Lookup.h - Classes for name lookup ---------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the LookupResult class, which is integral to
-// Sema's name-lookup subsystem.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_LOOKUP_H
-#define LLVM_CLANG_SEMA_LOOKUP_H
-
-#include "Sema.h"
-
-namespace clang {
-
-/// @brief Represents the results of name lookup.
-///
-/// An instance of the LookupResult class captures the results of a
-/// single name lookup, which can return no result (nothing found),
-/// a single declaration, a set of overloaded functions, or an
-/// ambiguity. Use the getKind() method to determine which of these
-/// results occurred for a given lookup.
-class LookupResult {
-public:
-  enum LookupResultKind {
-    /// @brief No entity found met the criteria.
-    NotFound = 0,
-
-    /// @brief No entity found met the criteria within the current 
-    /// instantiation,, but there were dependent base classes of the 
-    /// current instantiation that could not be searched.
-    NotFoundInCurrentInstantiation,
-    
-    /// @brief Name lookup found a single declaration that met the
-    /// criteria.  getFoundDecl() will return this declaration.
-    Found,
-
-    /// @brief Name lookup found a set of overloaded functions that
-    /// met the criteria.
-    FoundOverloaded,
-
-    /// @brief Name lookup found an unresolvable value declaration
-    /// and cannot yet complete.  This only happens in C++ dependent
-    /// contexts with dependent using declarations.
-    FoundUnresolvedValue,
-
-    /// @brief Name lookup results in an ambiguity; use
-    /// getAmbiguityKind to figure out what kind of ambiguity
-    /// we have.
-    Ambiguous
-  };
-
-  enum AmbiguityKind {
-    /// Name lookup results in an ambiguity because multiple
-    /// entities that meet the lookup criteria were found in
-    /// subobjects of different types. For example:
-    /// @code
-    /// struct A { void f(int); }
-    /// struct B { void f(double); }
-    /// struct C : A, B { };
-    /// void test(C c) {
-    ///   c.f(0); // error: A::f and B::f come from subobjects of different
-    ///           // types. overload resolution is not performed.
-    /// }
-    /// @endcode
-    AmbiguousBaseSubobjectTypes,
-
-    /// Name lookup results in an ambiguity because multiple
-    /// nonstatic entities that meet the lookup criteria were found
-    /// in different subobjects of the same type. For example:
-    /// @code
-    /// struct A { int x; };
-    /// struct B : A { };
-    /// struct C : A { };
-    /// struct D : B, C { };
-    /// int test(D d) {
-    ///   return d.x; // error: 'x' is found in two A subobjects (of B and C)
-    /// }
-    /// @endcode
-    AmbiguousBaseSubobjects,
-
-    /// Name lookup results in an ambiguity because multiple definitions
-    /// of entity that meet the lookup criteria were found in different
-    /// declaration contexts.
-    /// @code
-    /// namespace A {
-    ///   int i;
-    ///   namespace B { int i; }
-    ///   int test() {
-    ///     using namespace B;
-    ///     return i; // error 'i' is found in namespace A and A::B
-    ///    }
-    /// }
-    /// @endcode
-    AmbiguousReference,
-
-    /// Name lookup results in an ambiguity because an entity with a
-    /// tag name was hidden by an entity with an ordinary name from
-    /// a different context.
-    /// @code
-    /// namespace A { struct Foo {}; }
-    /// namespace B { void Foo(); }
-    /// namespace C {
-    ///   using namespace A;
-    ///   using namespace B;
-    /// }
-    /// void test() {
-    ///   C::Foo(); // error: tag 'A::Foo' is hidden by an object in a
-    ///             // different namespace
-    /// }
-    /// @endcode
-    AmbiguousTagHiding
-  };
-
-  /// A little identifier for flagging temporary lookup results.
-  enum TemporaryToken {
-    Temporary
-  };
-
-  typedef UnresolvedSetImpl::iterator iterator;
-
-  LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
-               Sema::LookupNameKind LookupKind,
-               Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
-    : ResultKind(NotFound),
-      Paths(0),
-      NamingClass(0),
-      SemaRef(SemaRef),
-      Name(Name),
-      NameLoc(NameLoc),
-      LookupKind(LookupKind),
-      IDNS(0),
-      Redecl(Redecl != Sema::NotForRedeclaration),
-      HideTags(true),
-      Diagnose(Redecl == Sema::NotForRedeclaration)
-  {
-    configure();
-  }
-
-  /// Creates a temporary lookup result, initializing its core data
-  /// using the information from another result.  Diagnostics are always
-  /// disabled.
-  LookupResult(TemporaryToken _, const LookupResult &Other)
-    : ResultKind(NotFound),
-      Paths(0),
-      NamingClass(0),
-      SemaRef(Other.SemaRef),
-      Name(Other.Name),
-      NameLoc(Other.NameLoc),
-      LookupKind(Other.LookupKind),
-      IDNS(Other.IDNS),
-      Redecl(Other.Redecl),
-      HideTags(Other.HideTags),
-      Diagnose(false)
-  {}
-
-  ~LookupResult() {
-    if (Diagnose) diagnose();
-    if (Paths) deletePaths(Paths);
-  }
-
-  /// Gets the name to look up.
-  DeclarationName getLookupName() const {
-    return Name;
-  }
-
-  /// \brief Sets the name to look up.
-  void setLookupName(DeclarationName Name) {
-    this->Name = Name;
-  }
-
-  /// Gets the kind of lookup to perform.
-  Sema::LookupNameKind getLookupKind() const {
-    return LookupKind;
-  }
-
-  /// True if this lookup is just looking for an existing declaration.
-  bool isForRedeclaration() const {
-    return Redecl;
-  }
-
-  /// Sets whether tag declarations should be hidden by non-tag
-  /// declarations during resolution.  The default is true.
-  void setHideTags(bool Hide) {
-    HideTags = Hide;
-  }
-
-  bool isAmbiguous() const {
-    return getResultKind() == Ambiguous;
-  }
-
-  /// Determines if this names a single result which is not an
-  /// unresolved value using decl.  If so, it is safe to call
-  /// getFoundDecl().
-  bool isSingleResult() const {
-    return getResultKind() == Found;
-  }
-
-  /// Determines if the results are overloaded.
-  bool isOverloadedResult() const {
-    return getResultKind() == FoundOverloaded;
-  }
-
-  bool isUnresolvableResult() const {
-    return getResultKind() == FoundUnresolvedValue;
-  }
-
-  LookupResultKind getResultKind() const {
-    sanity();
-    return ResultKind;
-  }
-
-  AmbiguityKind getAmbiguityKind() const {
-    assert(isAmbiguous());
-    return Ambiguity;
-  }
-
-  const UnresolvedSetImpl &asUnresolvedSet() const {
-    return Decls;
-  }
-
-  iterator begin() const { return iterator(Decls.begin()); }
-  iterator end() const { return iterator(Decls.end()); }
-
-  /// \brief Return true if no decls were found
-  bool empty() const { return Decls.empty(); }
-
-  /// \brief Return the base paths structure that's associated with
-  /// these results, or null if none is.
-  CXXBasePaths *getBasePaths() const {
-    return Paths;
-  }
-
-  /// \brief Tests whether the given declaration is acceptable.
-  bool isAcceptableDecl(NamedDecl *D) const {
-    return D->isInIdentifierNamespace(IDNS);
-  }
-
-  /// \brief Returns the identifier namespace mask for this lookup.
-  unsigned getIdentifierNamespace() const {
-    return IDNS;
-  }
-
-  /// \brief Returns whether these results arose from performing a
-  /// lookup into a class.
-  bool isClassLookup() const {
-    return NamingClass != 0;
-  }
-
-  /// \brief Returns the 'naming class' for this lookup, i.e. the
-  /// class which was looked into to find these results.
-  ///
-  /// C++0x [class.access.base]p5:
-  ///   The access to a member is affected by the class in which the
-  ///   member is named. This naming class is the class in which the
-  ///   member name was looked up and found. [Note: this class can be
-  ///   explicit, e.g., when a qualified-id is used, or implicit,
-  ///   e.g., when a class member access operator (5.2.5) is used
-  ///   (including cases where an implicit "this->" is added). If both
-  ///   a class member access operator and a qualified-id are used to
-  ///   name the member (as in p->T::m), the class naming the member
-  ///   is the class named by the nested-name-specifier of the
-  ///   qualified-id (that is, T). -- end note ]
-  ///
-  /// This is set by the lookup routines when they find results in a class.
-  CXXRecordDecl *getNamingClass() const {
-    return NamingClass;
-  }
-
-  /// \brief Sets the 'naming class' for this lookup.
-  void setNamingClass(CXXRecordDecl *Record) {
-    NamingClass = Record;
-  }
-
-  /// \brief Returns the base object type associated with this lookup;
-  /// important for [class.protected].  Most lookups do not have an
-  /// associated base object.
-  QualType getBaseObjectType() const {
-    return BaseObjectType;
-  }
-
-  /// \brief Sets the base object type for this lookup.
-  void setBaseObjectType(QualType T) {
-    BaseObjectType = T;
-  }
-
-  /// \brief Add a declaration to these results with its natural access.
-  /// Does not test the acceptance criteria.
-  void addDecl(NamedDecl *D) {
-    addDecl(D, D->getAccess());
-  }
-
-  /// \brief Add a declaration to these results with the given access.
-  /// Does not test the acceptance criteria.
-  void addDecl(NamedDecl *D, AccessSpecifier AS) {
-    Decls.addDecl(D, AS);
-    ResultKind = Found;
-  }
-
-  /// \brief Add all the declarations from another set of lookup
-  /// results.
-  void addAllDecls(const LookupResult &Other) {
-    Decls.append(Other.Decls.begin(), Other.Decls.end());
-    ResultKind = Found;
-  }
-
-  /// \brief Determine whether no result was found because we could not
-  /// search into dependent base classes of the current instantiation.
-  bool wasNotFoundInCurrentInstantiation() const {
-    return ResultKind == NotFoundInCurrentInstantiation;
-  }
-  
-  /// \brief Note that while no result was found in the current instantiation,
-  /// there were dependent base classes that could not be searched.
-  void setNotFoundInCurrentInstantiation() {
-    assert(ResultKind == NotFound && Decls.empty());
-    ResultKind = NotFoundInCurrentInstantiation;
-  }
-  
-  /// \brief Resolves the result kind of the lookup, possibly hiding
-  /// decls.
-  ///
-  /// This should be called in any environment where lookup might
-  /// generate multiple lookup results.
-  void resolveKind();
-
-  /// \brief Re-resolves the result kind of the lookup after a set of
-  /// removals has been performed.
-  void resolveKindAfterFilter() {
-    if (Decls.empty()) {
-      if (ResultKind != NotFoundInCurrentInstantiation)
-        ResultKind = NotFound;
-    } else {
-      ResultKind = Found;
-      resolveKind();
-      
-      if (Paths && (ResultKind != Ambiguous)) {
-        deletePaths(Paths);
-        Paths = 0;
-      }
-    }
-  }
-
-  template <class DeclClass>
-  DeclClass *getAsSingle() const {
-    if (getResultKind() != Found) return 0;
-    return dyn_cast<DeclClass>(getFoundDecl());
-  }
-
-  /// \brief Fetch the unique decl found by this lookup.  Asserts
-  /// that one was found.
-  ///
-  /// This is intended for users who have examined the result kind
-  /// and are certain that there is only one result.
-  NamedDecl *getFoundDecl() const {
-    assert(getResultKind() == Found
-           && "getFoundDecl called on non-unique result");
-    return (*begin())->getUnderlyingDecl();
-  }
-
-  /// Fetches a representative decl.  Useful for lazy diagnostics.
-  NamedDecl *getRepresentativeDecl() const {
-    assert(!Decls.empty() && "cannot get representative of empty set");
-    return *begin();
-  }
-
-  /// \brief Asks if the result is a single tag decl.
-  bool isSingleTagDecl() const {
-    return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
-  }
-
-  /// \brief Make these results show that the name was found in
-  /// base classes of different types.
-  ///
-  /// The given paths object is copied and invalidated.
-  void setAmbiguousBaseSubobjectTypes(CXXBasePaths &P);
-
-  /// \brief Make these results show that the name was found in
-  /// distinct base classes of the same type.
-  ///
-  /// The given paths object is copied and invalidated.
-  void setAmbiguousBaseSubobjects(CXXBasePaths &P);
-
-  /// \brief Make these results show that the name was found in
-  /// different contexts and a tag decl was hidden by an ordinary
-  /// decl in a different context.
-  void setAmbiguousQualifiedTagHiding() {
-    setAmbiguous(AmbiguousTagHiding);
-  }
-
-  /// \brief Clears out any current state.
-  void clear() {
-    ResultKind = NotFound;
-    Decls.clear();
-    if (Paths) deletePaths(Paths);
-    Paths = NULL;
-  }
-
-  /// \brief Clears out any current state and re-initializes for a
-  /// different kind of lookup.
-  void clear(Sema::LookupNameKind Kind) {
-    clear();
-    LookupKind = Kind;
-    configure();
-  }
-
-  /// \brief Change this lookup's redeclaration kind.
-  void setRedeclarationKind(Sema::RedeclarationKind RK) {
-    Redecl = RK;
-    configure();
-  }
-
-  void print(llvm::raw_ostream &);
-
-  /// Suppress the diagnostics that would normally fire because of this
-  /// lookup.  This happens during (e.g.) redeclaration lookups.
-  void suppressDiagnostics() {
-    Diagnose = false;
-  }
-
-  /// Determines whether this lookup is suppressing diagnostics.
-  bool isSuppressingDiagnostics() const {
-    return Diagnose;
-  }
-
-  /// Sets a 'context' source range.
-  void setContextRange(SourceRange SR) {
-    NameContextRange = SR;
-  }
-
-  /// Gets the source range of the context of this name; for C++
-  /// qualified lookups, this is the source range of the scope
-  /// specifier.
-  SourceRange getContextRange() const {
-    return NameContextRange;
-  }
-
-  /// Gets the location of the identifier.  This isn't always defined:
-  /// sometimes we're doing lookups on synthesized names.
-  SourceLocation getNameLoc() const {
-    return NameLoc;
-  }
-
-  /// \brief Get the Sema object that this lookup result is searching
-  /// with.
-  Sema &getSema() const { return SemaRef; }
-
-  /// A class for iterating through a result set and possibly
-  /// filtering out results.  The results returned are possibly
-  /// sugared.
-  class Filter {
-    LookupResult &Results;
-    LookupResult::iterator I;
-    bool Changed;
-#ifndef NDEBUG
-    bool CalledDone;
-#endif
-    
-    friend class LookupResult;
-    Filter(LookupResult &Results)
-      : Results(Results), I(Results.begin()), Changed(false)
-#ifndef NDEBUG
-      , CalledDone(false)
-#endif
-    {}
-
-  public:
-#ifndef NDEBUG
-    ~Filter() {
-      assert(CalledDone &&
-             "LookupResult::Filter destroyed without done() call");
-    }
-#endif
-
-    bool hasNext() const {
-      return I != Results.end();
-    }
-
-    NamedDecl *next() {
-      assert(I != Results.end() && "next() called on empty filter");
-      return *I++;
-    }
-
-    /// Erase the last element returned from this iterator.
-    void erase() {
-      Results.Decls.erase(--I);
-      Changed = true;
-    }
-
-    /// Replaces the current entry with the given one, preserving the
-    /// access bits.
-    void replace(NamedDecl *D) {
-      Results.Decls.replace(I-1, D);
-      Changed = true;
-    }
-
-    /// Replaces the current entry with the given one.
-    void replace(NamedDecl *D, AccessSpecifier AS) {
-      Results.Decls.replace(I-1, D, AS);
-      Changed = true;
-    }
-
-    void done() {
-#ifndef NDEBUG
-      assert(!CalledDone && "done() called twice");
-      CalledDone = true;
-#endif
-
-      if (Changed)
-        Results.resolveKindAfterFilter();
-    }
-  };
-
-  /// Create a filter for this result set.
-  Filter makeFilter() {
-    return Filter(*this);
-  }
-
-private:
-  void diagnose() {
-    if (isAmbiguous())
-      SemaRef.DiagnoseAmbiguousLookup(*this);
-    else if (isClassLookup() && SemaRef.getLangOptions().AccessControl)
-      SemaRef.CheckLookupAccess(*this);
-  }
-
-  void setAmbiguous(AmbiguityKind AK) {
-    ResultKind = Ambiguous;
-    Ambiguity = AK;
-  }
-
-  void addDeclsFromBasePaths(const CXXBasePaths &P);
-  void configure();
-
-  // Sanity checks.
-  void sanity() const {
-    assert(ResultKind != NotFound || Decls.size() == 0);
-    assert(ResultKind != Found || Decls.size() == 1);
-    assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
-           (Decls.size() == 1 &&
-            isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
-    assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
-    assert(ResultKind != Ambiguous || Decls.size() > 1 ||
-           (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
-    assert((Paths != NULL) == (ResultKind == Ambiguous &&
-                               (Ambiguity == AmbiguousBaseSubobjectTypes ||
-                                Ambiguity == AmbiguousBaseSubobjects)));
-  }
-
-  bool sanityCheckUnresolved() const {
-    for (iterator I = begin(), E = end(); I != E; ++I)
-      if (isa<UnresolvedUsingValueDecl>(*I))
-        return true;
-    return false;
-  }
-
-  static void deletePaths(CXXBasePaths *);
-
-  // Results.
-  LookupResultKind ResultKind;
-  AmbiguityKind Ambiguity; // ill-defined unless ambiguous
-  UnresolvedSet<8> Decls;
-  CXXBasePaths *Paths;
-  CXXRecordDecl *NamingClass;
-  QualType BaseObjectType;
-
-  // Parameters.
-  Sema &SemaRef;
-  DeclarationName Name;
-  SourceLocation NameLoc;
-  SourceRange NameContextRange;
-  Sema::LookupNameKind LookupKind;
-  unsigned IDNS; // set by configure()
-
-  bool Redecl;
-
-  /// \brief True if tag declarations should be hidden if non-tags
-  ///   are present
-  bool HideTags;
-
-  bool Diagnose;
-};
-
-  /// \brief Consumes visible declarations found when searching for
-  /// all visible names within a given scope or context.
-  ///
-  /// This abstract class is meant to be subclassed by clients of \c
-  /// Sema::LookupVisibleDecls(), each of which should override the \c
-  /// FoundDecl() function to process declarations as they are found.
-  class VisibleDeclConsumer {
-  public:
-    /// \brief Destroys the visible declaration consumer.
-    virtual ~VisibleDeclConsumer();
-
-    /// \brief Invoked each time \p Sema::LookupVisibleDecls() finds a
-    /// declaration visible from the current scope or context.
-    ///
-    /// \param ND the declaration found.
-    ///
-    /// \param Hiding a declaration that hides the declaration \p ND,
-    /// or NULL if no such declaration exists.
-    ///
-    /// \param InBaseClass whether this declaration was found in base
-    /// class of the context we searched.
-    virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, 
-                           bool InBaseClass) = 0;
-  };
-
-/// \brief A class for storing results from argument-dependent lookup.
-class ADLResult {
-private:
-  /// A map from canonical decls to the 'most recent' decl.
-  llvm::DenseMap<NamedDecl*, NamedDecl*> Decls;
-
-public:
-  /// Adds a new ADL candidate to this map.
-  void insert(NamedDecl *D);
-
-  /// Removes any data associated with a given decl.
-  void erase(NamedDecl *D) {
-    Decls.erase(cast<NamedDecl>(D->getCanonicalDecl()));
-  }
-
-  class iterator {
-    typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator;
-    inner_iterator iter;
-
-    friend class ADLResult;
-    iterator(const inner_iterator &iter) : iter(iter) {}
-  public:
-    iterator() {}
-
-    iterator &operator++() { ++iter; return *this; }
-    iterator operator++(int) { return iterator(iter++); }
-
-    NamedDecl *operator*() const { return iter->second; }
-
-    bool operator==(const iterator &other) const { return iter == other.iter; }
-    bool operator!=(const iterator &other) const { return iter != other.iter; }
-  };
-
-  iterator begin() { return iterator(Decls.begin()); }
-  iterator end() { return iterator(Decls.end()); }
-};
-
-}
-
-#endif
diff --git a/lib/Sema/Makefile b/lib/Sema/Makefile
index 90f2dff..2c02739 100644
--- a/lib/Sema/Makefile
+++ b/lib/Sema/Makefile
@@ -14,7 +14,6 @@
 
 CLANG_LEVEL := ../..
 LIBRARYNAME := clangSema
-BUILD_ARCHIVE = 1
 
 include $(CLANG_LEVEL)/Makefile
 
diff --git a/lib/Sema/ParseAST.cpp b/lib/Sema/ParseAST.cpp
deleted file mode 100644
index bb0bd9e..0000000
--- a/lib/Sema/ParseAST.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the clang::ParseAST method.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Sema/ParseAST.h"
-#include "Sema.h"
-#include "clang/Sema/CodeCompleteConsumer.h"
-#include "clang/Sema/SemaConsumer.h"
-#include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Parse/Parser.h"
-#include <cstdio>
-
-using namespace clang;
-
-static void DumpRecordLayouts(ASTContext &C) {
-  for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end();
-       I != E; ++I) {
-    const RecordType *RT = dyn_cast<RecordType>(*I);
-    if (!RT)
-      continue;
-
-    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
-    if (!RD || RD->isImplicit() || RD->isDependentType() ||
-        RD->isInvalidDecl() || !RD->getDefinition())
-      continue;
-
-    // FIXME: Do we really need to hard code this?
-    if (RD->getQualifiedNameAsString() == "__va_list_tag")
-      continue;
-
-    C.DumpRecordLayout(RD, llvm::errs());
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// Public interface to the file
-//===----------------------------------------------------------------------===//
-
-/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
-/// the file is parsed.  This inserts the parsed decls into the translation unit
-/// held by Ctx.
-///
-void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
-                     ASTContext &Ctx, bool PrintStats,
-                     bool CompleteTranslationUnit,
-                     CodeCompleteConsumer *CompletionConsumer) {
-  // Collect global stats on Decls/Stmts (until we have a module streamer).
-  if (PrintStats) {
-    Decl::CollectingStats(true);
-    Stmt::CollectingStats(true);
-  }
-
-  Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer);
-  Parser P(PP, S);
-  PP.EnterMainSourceFile();
-
-  // Initialize the parser.
-  P.Initialize();
-
-  Consumer->Initialize(Ctx);
-
-  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
-    SC->InitializeSema(S);
-
-  if (ExternalASTSource *External = Ctx.getExternalSource()) {
-    if (ExternalSemaSource *ExternalSema =
-          dyn_cast<ExternalSemaSource>(External))
-      ExternalSema->InitializeSema(S);
-
-    External->StartTranslationUnit(Consumer);
-  }
-
-  Parser::DeclGroupPtrTy ADecl;
-
-  while (!P.ParseTopLevelDecl(ADecl)) {  // Not end of file.
-    // If we got a null return and something *was* parsed, ignore it.  This
-    // is due to a top-level semicolon, an action override, or a parse error
-    // skipping something.
-    if (ADecl)
-      Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
-  };
-  // Check for any pending objective-c implementation decl.
-  while ((ADecl = P.RetrievePendingObjCImpDecl()))
-    Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>());
-
-  // Process any TopLevelDecls generated by #pragma weak.
-  for (llvm::SmallVector<Decl*,2>::iterator
-        I = S.WeakTopLevelDecls().begin(),
-        E = S.WeakTopLevelDecls().end(); I != E; ++I)
-    Consumer->HandleTopLevelDecl(DeclGroupRef(*I));
-
-  // Dump record layouts, if requested.
-  if (PP.getLangOptions().DumpRecordLayouts)
-    DumpRecordLayouts(Ctx);
-
-  Consumer->HandleTranslationUnit(Ctx);
-
-  if (ExternalSemaSource *ESS =
-        dyn_cast_or_null<ExternalSemaSource>(Ctx.getExternalSource()))
-    ESS->ForgetSema();
-
-  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer))
-    SC->ForgetSema();
-
-  if (PrintStats) {
-    fprintf(stderr, "\nSTATISTICS:\n");
-    P.getActions().PrintStats();
-    Ctx.PrintStats();
-    Decl::PrintStats();
-    Stmt::PrintStats();
-    Consumer->PrintStats();
-  }
-}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index cddc84e..17817d4 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -12,26 +12,36 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.h"
 #include "TargetAttributesSema.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/APFloat.h"
+#include "clang/Sema/CXXFieldCollector.h"
 #include "clang/Sema/ExternalSemaSource.h"
-#include "clang/AST/ASTConsumer.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 using namespace clang;
+using namespace sema;
 
 FunctionScopeInfo::~FunctionScopeInfo() { }
 
 void FunctionScopeInfo::Clear(unsigned NumErrors) {
-  NeedsScopeChecking = false;
+  HasBranchProtectedScope = false;
+  HasBranchIntoScope = false;
+  HasIndirectGoto = false;
+  
   LabelMap.clear();
   SwitchStack.clear();
   Returns.clear();
@@ -40,13 +50,13 @@ void FunctionScopeInfo::Clear(unsigned NumErrors) {
 
 BlockScopeInfo::~BlockScopeInfo() { }
 
-void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
+void Sema::ActOnTranslationUnitScope(Scope *S) {
   TUScope = S;
   PushDeclContext(S, Context.getTranslationUnitDecl());
 
   VAListTagName = PP.getIdentifierInfo("__va_list_tag");
 
-  if (!Context.isInt128Installed() && // May be set by PCHReader.
+  if (!Context.isInt128Installed() && // May be set by ASTReader.
       PP.getTargetInfo().getPointerWidth(0) >= 64) {
     TypeSourceInfo *TInfo;
 
@@ -68,7 +78,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
 
   if (!PP.getLangOptions().ObjC1) return;
 
-  // Built-in ObjC types may already be set by PCHReader (hence isNull checks).
+  // Built-in ObjC types may already be set by ASTReader (hence isNull checks).
   if (Context.getObjCSelType().isNull()) {
     // Create the built-in typedef for 'SEL'.
     QualType SelT = Context.getPointerType(Context.ObjCBuiltinSelTy);
@@ -113,7 +123,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
     PushOnScopeChains(ClassTypedef, TUScope);
     Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
     Context.ObjCClassRedefinitionType = Context.getObjCClassType();
-  }
+  }  
 }
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
@@ -123,9 +133,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
     LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
-    PackContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
-    IdResolver(pp.getLangOptions()), StdNamespace(0), StdBadAlloc(0),
-    GlobalNewDeleteDeclared(false), 
+    PackContext(0), VisContext(0), ParsingDeclDepth(0),
+    IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false), 
     CompleteTranslationUnit(CompleteTranslationUnit),
     NumSFINAEErrors(0), SuppressAccessChecking(false),
     NonInstantiationEntries(0), CurrentInstantiationScope(0), TyposCorrected(0),
@@ -140,22 +149,52 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
                                        &Context);
 
   ExprEvalContexts.push_back(
-                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));
+                  ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0));  
+
+  FunctionScopes.push_back(new FunctionScopeInfo(Diags.getNumErrors()));
+}
+
+void Sema::Initialize() {
+  // Tell the AST consumer about this Sema object.
+  Consumer.Initialize(Context);
+  
+  // FIXME: Isn't this redundant with the initialization above?
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+    SC->InitializeSema(*this);
+  
+  // Tell the external Sema source about this Sema object.
+  if (ExternalSemaSource *ExternalSema
+      = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+    ExternalSema->InitializeSema(*this);
 }
 
 Sema::~Sema() {
   if (PackContext) FreePackedContext();
+  if (VisContext) FreeVisContext();
   delete TheTargetAttributesSema;
-  while (!FunctionScopes.empty())
-    PopFunctionOrBlockScope();
+
+  // Kill all the active scopes.
+  for (unsigned I = 1, E = FunctionScopes.size(); I != E; ++I)
+    delete FunctionScopes[I];
+  if (FunctionScopes.size() == 1)
+    delete FunctionScopes[0];
+  
+  // Tell the SemaConsumer to forget about us; we're going out of scope.
+  if (SemaConsumer *SC = dyn_cast<SemaConsumer>(&Consumer))
+    SC->ForgetSema();
+
+  // Detach from the external Sema source.
+  if (ExternalSemaSource *ExternalSema
+        = dyn_cast_or_null<ExternalSemaSource>(Context.getExternalSource()))
+    ExternalSema->ForgetSema();
 }
 
 /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
 /// If there is already an implicit cast, merge into the existing one.
-/// If isLvalue, the result of the cast is an lvalue.
+/// The result is of the given category.
 void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
-                             CastExpr::CastKind Kind, 
-                             bool isLvalue, CXXBaseSpecifierArray BasePath) {
+                             CastKind Kind, ExprValueKind VK,
+                             const CXXCastPath *BasePath) {
   QualType ExprTy = Context.getCanonicalType(Expr->getType());
   QualType TypeTy = Context.getCanonicalType(Ty);
 
@@ -173,8 +212,8 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
 
   // If this is a derived-to-base cast to a through a virtual base, we
   // need a vtable.
-  if (Kind == CastExpr::CK_DerivedToBase && 
-      BasePathInvolvesVirtualBase(BasePath)) {
+  if (Kind == CK_DerivedToBase && 
+      BasePathInvolvesVirtualBase(*BasePath)) {
     QualType T = Expr->getType();
     if (const PointerType *Pointer = T->getAs<PointerType>())
       T = Pointer->getPointeeType();
@@ -184,53 +223,96 @@ void Sema::ImpCastExprToType(Expr *&Expr, QualType Ty,
   }
 
   if (ImplicitCastExpr *ImpCast = dyn_cast<ImplicitCastExpr>(Expr)) {
-    if (ImpCast->getCastKind() == Kind && BasePath.empty()) {
+    if (ImpCast->getCastKind() == Kind && (!BasePath || BasePath->empty())) {
       ImpCast->setType(Ty);
-      ImpCast->setLvalueCast(isLvalue);
+      ImpCast->setValueKind(VK);
       return;
     }
   }
 
-  Expr = new (Context) ImplicitCastExpr(Ty, Kind, Expr, BasePath, isLvalue);
+  Expr = ImplicitCastExpr::Create(Context, Ty, Kind, Expr, BasePath, VK);
 }
 
-void Sema::DeleteExpr(ExprTy *E) {
-  if (E) static_cast<Expr*>(E)->Destroy(Context);
+ExprValueKind Sema::CastCategory(Expr *E) {
+  Expr::Classification Classification = E->Classify(Context);
+  return Classification.isRValue() ? VK_RValue :
+      (Classification.isLValue() ? VK_LValue : VK_XValue);
 }
-void Sema::DeleteStmt(StmtTy *S) {
-  if (S) static_cast<Stmt*>(S)->Destroy(Context);
+
+/// \brief Used to prune the decls of Sema's UnusedFileScopedDecls vector.
+static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
+  if (D->isUsed())
+    return true;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // UnusedFileScopedDecls stores the first declaration.
+    // The declaration may have become definition so check again.
+    const FunctionDecl *DeclToCheck;
+    if (FD->hasBody(DeclToCheck))
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+
+    // Later redecls may add new information resulting in not having to warn,
+    // so check again.
+    DeclToCheck = FD->getMostRecentDeclaration();
+    if (DeclToCheck != FD)
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    // UnusedFileScopedDecls stores the first declaration.
+    // The declaration may have become definition so check again.
+    const VarDecl *DeclToCheck = VD->getDefinition(); 
+    if (DeclToCheck)
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+
+    // Later redecls may add new information resulting in not having to warn,
+    // so check again.
+    DeclToCheck = VD->getMostRecentDeclaration();
+    if (DeclToCheck != VD)
+      return !SemaRef->ShouldWarnIfUnusedFileScopedDecl(DeclToCheck);
+  }
+
+  return false;
 }
 
 /// ActOnEndOfTranslationUnit - This is called at the very end of the
 /// translation unit when EOF is reached and all but the top-level scope is
 /// popped.
-void Sema::ActOnEndOfTranslationUnit() {  
-  while (1) {
-    // C++: Perform implicit template instantiations.
-    //
-    // FIXME: When we perform these implicit instantiations, we do not carefully
-    // keep track of the point of instantiation (C++ [temp.point]). This means
-    // that name lookup that occurs within the template instantiation will
-    // always happen at the end of the translation unit, so it will find
-    // some names that should not be found. Although this is common behavior
-    // for C++ compilers, it is technically wrong. In the future, we either need
-    // to be able to filter the results of name lookup or we need to perform
-    // template instantiations earlier.
-    PerformPendingImplicitInstantiations();
-    
-    /// If DefinedUsedVTables ends up marking any virtual member
-    /// functions it might lead to more pending template
-    /// instantiations, which is why we need to loop here.
-    if (!DefineUsedVTables())
-      break;
-  }
+void Sema::ActOnEndOfTranslationUnit() {
+  // At PCH writing, implicit instantiations and VTable handling info are
+  // stored and performed when the PCH is included.
+  if (CompleteTranslationUnit)
+    while (1) {
+      // C++: Perform implicit template instantiations.
+      //
+      // FIXME: When we perform these implicit instantiations, we do not
+      // carefully keep track of the point of instantiation (C++ [temp.point]).
+      // This means that name lookup that occurs within the template
+      // instantiation will always happen at the end of the translation unit,
+      // so it will find some names that should not be found. Although this is
+      // common behavior for C++ compilers, it is technically wrong. In the
+      // future, we either need to be able to filter the results of name lookup
+      // or we need to perform template instantiations earlier.
+      PerformPendingInstantiations();
+
+      /// If DefinedUsedVTables ends up marking any virtual member
+      /// functions it might lead to more pending template
+      /// instantiations, which is why we need to loop here.
+      if (!DefineUsedVTables())
+        break;
+    }
   
-  // Remove functions that turned out to be used.
-  UnusedStaticFuncs.erase(std::remove_if(UnusedStaticFuncs.begin(), 
-                                         UnusedStaticFuncs.end(), 
-                             std::bind2nd(std::mem_fun(&FunctionDecl::isUsed),
-                                          true)), 
-                          UnusedStaticFuncs.end());
+  // Remove file scoped decls that turned out to be used.
+  UnusedFileScopedDecls.erase(std::remove_if(UnusedFileScopedDecls.begin(),
+                                             UnusedFileScopedDecls.end(),
+                              std::bind1st(std::ptr_fun(ShouldRemoveFromUnused),
+                                           this)),
+                              UnusedFileScopedDecls.end());
+
+  if (!CompleteTranslationUnit) {
+    TUScope = 0;
+    return;
+  }
 
   // Check for #pragma weak identifiers that were never declared
   // FIXME: This will cause diagnostics to be emitted in a non-determinstic
@@ -244,9 +326,6 @@ void Sema::ActOnEndOfTranslationUnit() {
       << I->first;
   }
 
-  if (!CompleteTranslationUnit)
-    return;
-
   // C99 6.9.2p2:
   //   A declaration of an identifier for an object that has file
   //   scope without an initializer, and without a storage-class
@@ -293,14 +372,28 @@ void Sema::ActOnEndOfTranslationUnit() {
 
   }
   
-  // Output warning for unused functions.
-  for (std::vector<FunctionDecl*>::iterator
-       F = UnusedStaticFuncs.begin(),
-       FEnd = UnusedStaticFuncs.end();
-       F != FEnd;
-       ++F)
-    Diag((*F)->getLocation(), diag::warn_unused_function) << (*F)->getDeclName();
-  
+  // Output warning for unused file scoped decls.
+  for (llvm::SmallVectorImpl<const DeclaratorDecl*>::iterator
+         I = UnusedFileScopedDecls.begin(),
+         E = UnusedFileScopedDecls.end(); I != E; ++I) {
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
+      const FunctionDecl *DiagD;
+      if (!FD->hasBody(DiagD))
+        DiagD = FD;
+      Diag(DiagD->getLocation(),
+           isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
+                                     : diag::warn_unused_function)
+            << DiagD->getDeclName();
+    } else {
+      const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
+      if (!DiagD)
+        DiagD = cast<VarDecl>(*I);
+      Diag(DiagD->getLocation(), diag::warn_unused_variable)
+            << DiagD->getDeclName();
+    }
+  }
+
+  TUScope = 0;
 }
 
 
@@ -418,11 +511,11 @@ Scope *Sema::getScopeForContext(DeclContext *Ctx) {
 
 /// \brief Enter a new function scope
 void Sema::PushFunctionScope() {
-  if (FunctionScopes.empty()) {
-    // Use the "top" function scope rather than having to allocate memory for
-    // a new scope.
-    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
-    FunctionScopes.push_back(&TopFunctionScope);
+  if (FunctionScopes.size() == 1) {
+    // Use the "top" function scope rather than having to allocate
+    // memory for a new scope.
+    FunctionScopes.back()->Clear(getDiagnostics().getNumErrors());
+    FunctionScopes.push_back(FunctionScopes.back());
     return;
   }
   
@@ -436,21 +529,17 @@ void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) {
 }
 
 void Sema::PopFunctionOrBlockScope() {
-  if (FunctionScopes.back() != &TopFunctionScope)
-    delete FunctionScopes.back();
-  else
-    TopFunctionScope.Clear(getDiagnostics().getNumErrors());
-  
-  FunctionScopes.pop_back();
+  FunctionScopeInfo *Scope = FunctionScopes.pop_back_val();
+  assert(!FunctionScopes.empty() && "mismatched push/pop!");
+  if (FunctionScopes.back() != Scope)
+    delete Scope;
 }
 
 /// \brief Determine whether any errors occurred within this function/method/
 /// block.
 bool Sema::hasAnyErrorsInThisFunction() const {
-  unsigned NumErrors = TopFunctionScope.NumErrorsAtStartOfFunction;
-  if (!FunctionScopes.empty())
-    NumErrors = FunctionScopes.back()->NumErrorsAtStartOfFunction;
-  return NumErrors != getDiagnostics().getNumErrors();
+  return getCurFunction()->NumErrorsAtStartOfFunction
+             != getDiagnostics().getNumErrors();
 }
 
 BlockScopeInfo *Sema::getCurBlock() {
@@ -462,3 +551,21 @@ BlockScopeInfo *Sema::getCurBlock() {
 
 // Pin this vtable to this file.
 ExternalSemaSource::~ExternalSemaSource() {}
+
+void PrettyDeclStackTraceEntry::print(llvm::raw_ostream &OS) const {
+  SourceLocation Loc = this->Loc;
+  if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
+  if (Loc.isValid()) {
+    Loc.print(OS, S.getSourceManager());
+    OS << ": ";
+  }
+  OS << Message;
+
+  if (TheDecl && isa<NamedDecl>(TheDecl)) {
+    std::string Name = cast<NamedDecl>(TheDecl)->getNameAsString();
+    if (!Name.empty())
+      OS << " '" << Name << '\'';
+  }
+
+  OS << '\n';
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
deleted file mode 100644
index 8336918..0000000
--- a/lib/Sema/Sema.h
+++ /dev/null
@@ -1,4655 +0,0 @@
-//===--- Sema.h - Semantic Analysis & AST Building --------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the Sema class, which performs semantic analysis and
-// builds ASTs.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_SEMA_H
-#define LLVM_CLANG_AST_SEMA_H
-
-#include "IdentifierResolver.h"
-#include "CXXFieldCollector.h"
-#include "SemaOverload.h"
-#include "SemaTemplate.h"
-#include "AnalysisBasedWarnings.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/FullExpr.h"
-#include "clang/Parse/Action.h"
-#include "clang/Sema/SemaDiagnostic.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/OwningPtr.h"
-#include <deque>
-#include <list>
-#include <map>
-#include <string>
-#include <vector>
-
-namespace llvm {
-  class APSInt;
-}
-
-namespace clang {
-  class ASTContext;
-  class ASTConsumer;
-  class CodeCompleteConsumer;
-  class Preprocessor;
-  class Decl;
-  class DeclContext;
-  class DeclSpec;
-  class ExternalSemaSource;
-  class NamedDecl;
-  class Stmt;
-  class Expr;
-  class InitListExpr;
-  class ParenListExpr;
-  class DesignatedInitExpr;
-  class CallExpr;
-  class DeclRefExpr;
-  class UnresolvedLookupExpr;
-  class UnresolvedMemberExpr;
-  class VarDecl;
-  class ParmVarDecl;
-  class TypedefDecl;
-  class FunctionDecl;
-  class QualType;
-  class LangOptions;
-  class Token;
-  class IntegerLiteral;
-  class StringLiteral;
-  class ArrayType;
-  class LabelStmt;
-  class SwitchStmt;
-  class CXXTryStmt;
-  class ExtVectorType;
-  class TypedefDecl;
-  class TemplateDecl;
-  class TemplateArgument;
-  class TemplateArgumentLoc;
-  class TemplateArgumentList;
-  class TemplateParameterList;
-  class TemplateTemplateParmDecl;
-  class ClassTemplatePartialSpecializationDecl;
-  class ClassTemplateDecl;
-  class ObjCInterfaceDecl;
-  class ObjCCompatibleAliasDecl;
-  class ObjCProtocolDecl;
-  class ObjCImplDecl;
-  class ObjCImplementationDecl;
-  class ObjCCategoryImplDecl;
-  class ObjCCategoryDecl;
-  class ObjCIvarDecl;
-  class ObjCMethodDecl;
-  class ObjCPropertyDecl;
-  class ObjCContainerDecl;
-  class PseudoDestructorTypeStorage;
-  class FunctionProtoType;
-  class CXXBasePath;
-  class CXXBasePaths;
-  class CXXTemporary;
-  class LookupResult;
-  class InitializedEntity;
-  class InitializationKind;
-  class InitializationSequence;
-  class VisibleDeclConsumer;
-  class TargetAttributesSema;
-  class ADLResult;
-
-/// \brief Retains information about a function, method, or block that is
-/// currently being parsed.
-struct FunctionScopeInfo {
-  /// \brief Whether this scope information structure defined information for
-  /// a block.
-  bool IsBlockInfo;
-
-  /// \brief Set true when a function, method contains a VLA or ObjC try block,
-  /// which introduce scopes that need to be checked for goto conditions.  If a
-  /// function does not contain this, then it need not have the jump checker run
-  /// on it.
-  bool NeedsScopeChecking;
-
-  /// \brief The number of errors that had occurred before starting this
-  /// function or block.
-  unsigned NumErrorsAtStartOfFunction;
-
-  /// LabelMap - This is a mapping from label identifiers to the LabelStmt for
-  /// it (which acts like the label decl in some ways).  Forward referenced
-  /// labels have a LabelStmt created for them with a null location & SubStmt.
-  llvm::DenseMap<IdentifierInfo*, LabelStmt*> LabelMap;
-
-  /// SwitchStack - This is the current set of active switch statements in the
-  /// block.
-  llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
-
-  /// \brief The list of return statements that occur within the function or
-  /// block, if there is any chance of applying the named return value
-  /// optimization.
-  llvm::SmallVector<ReturnStmt *, 4> Returns;
-  
-  FunctionScopeInfo(unsigned NumErrors)
-    : IsBlockInfo(false), NeedsScopeChecking(false),
-      NumErrorsAtStartOfFunction(NumErrors) { }
-
-  virtual ~FunctionScopeInfo();
-
-  /// \brief Clear out the information in this function scope, making it
-  /// suitable for reuse.
-  void Clear(unsigned NumErrors);
-
-  static bool classof(const FunctionScopeInfo *FSI) { return true; }
-};
-
-
-/// \brief Retains information about a block that is currently being parsed.
-struct BlockScopeInfo : FunctionScopeInfo {
-  bool hasBlockDeclRefExprs;
-
-  BlockDecl *TheDecl;
-  
-  /// TheScope - This is the scope for the block itself, which contains
-  /// arguments etc.
-  Scope *TheScope;
-
-  /// ReturnType - The return type of the block, or null if the block
-  /// signature didn't provide an explicit return type.
-  QualType ReturnType;
-
-  /// BlockType - The function type of the block, if one was given.
-  /// Its return type may be BuiltinType::Dependent.
-  QualType FunctionType;
-
-  BlockScopeInfo(unsigned NumErrors, Scope *BlockScope, BlockDecl *Block)
-    : FunctionScopeInfo(NumErrors), hasBlockDeclRefExprs(false),
-      TheDecl(Block), TheScope(BlockScope)
-  {
-    IsBlockInfo = true;
-  }
-
-  virtual ~BlockScopeInfo();
-
-  static bool classof(const FunctionScopeInfo *FSI) { return FSI->IsBlockInfo; }
-  static bool classof(const BlockScopeInfo *BSI) { return true; }
-};
-
-/// \brief Holds a QualType and a TypeSourceInfo* that came out of a declarator
-/// parsing.
-///
-/// LocInfoType is a "transient" type, only needed for passing to/from Parser
-/// and Sema, when we want to preserve type source info for a parsed type.
-/// It will not participate in the type system semantics in any way.
-class LocInfoType : public Type {
-  enum {
-    // The last number that can fit in Type's TC.
-    // Avoids conflict with an existing Type class.
-    LocInfo = Type::TypeLast + 1
-  };
-
-  TypeSourceInfo *DeclInfo;
-
-  LocInfoType(QualType ty, TypeSourceInfo *TInfo)
-    : Type((TypeClass)LocInfo, ty, ty->isDependentType()), DeclInfo(TInfo) {
-    assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?");
-  }
-  friend class Sema;
-
-public:
-  QualType getType() const { return getCanonicalTypeInternal(); }
-  TypeSourceInfo *getTypeSourceInfo() const { return DeclInfo; }
-
-  virtual void getAsStringInternal(std::string &Str,
-                                   const PrintingPolicy &Policy) const;
-
-  static bool classof(const Type *T) {
-    return T->getTypeClass() == (TypeClass)LocInfo;
-  }
-  static bool classof(const LocInfoType *) { return true; }
-};
-
-/// Sema - This implements semantic analysis and AST building for C.
-class Sema : public Action {
-  Sema(const Sema&);           // DO NOT IMPLEMENT
-  void operator=(const Sema&); // DO NOT IMPLEMENT
-  mutable const TargetAttributesSema* TheTargetAttributesSema;
-public:
-  const LangOptions &LangOpts;
-  Preprocessor &PP;
-  ASTContext &Context;
-  ASTConsumer &Consumer;
-  Diagnostic &Diags;
-  SourceManager &SourceMgr;
-
-  /// \brief Source of additional semantic information.
-  ExternalSemaSource *ExternalSource;
-
-  /// \brief Code-completion consumer.
-  CodeCompleteConsumer *CodeCompleter;
-
-  /// CurContext - This is the current declaration context of parsing.
-  DeclContext *CurContext;
-
-  /// VAListTagName - The declaration name corresponding to __va_list_tag.
-  /// This is used as part of a hack to omit that class from ADL results.
-  DeclarationName VAListTagName;
-
-  /// A RAII object to temporarily push a declaration context.
-  class ContextRAII {
-  private:
-    Sema &S;
-    DeclContext *SavedContext;
-
-  public:
-    ContextRAII(Sema &S, DeclContext *ContextToPush)
-      : S(S), SavedContext(S.CurContext) {
-      assert(ContextToPush && "pushing null context");
-      S.CurContext = ContextToPush;
-    }
-
-    void pop() {
-      if (!SavedContext) return;
-      S.CurContext = SavedContext;
-      SavedContext = 0;
-    }
-
-    ~ContextRAII() {
-      pop();
-    }
-  };
-
-  /// PackContext - Manages the stack for #pragma pack. An alignment
-  /// of 0 indicates default alignment.
-  void *PackContext; // Really a "PragmaPackStack*"
-
-  /// \brief Stack containing information about each of the nested function,
-  /// block, and method scopes that are currently active.
-  llvm::SmallVector<FunctionScopeInfo *, 4> FunctionScopes;
-
-  /// \brief Cached function scope object used for the top function scope
-  /// and when there is no function scope (in error cases).
-  ///
-  /// This should never be accessed directly; rather, it's address will be
-  /// pushed into \c FunctionScopes when we want to re-use it.
-  FunctionScopeInfo TopFunctionScope;
-
-  /// ExprTemporaries - This is the stack of temporaries that are created by
-  /// the current full expression.
-  llvm::SmallVector<CXXTemporary*, 8> ExprTemporaries;
-
-  /// ExtVectorDecls - This is a list all the extended vector types. This allows
-  /// us to associate a raw vector type with one of the ext_vector type names.
-  /// This is only necessary for issuing pretty diagnostics.
-  llvm::SmallVector<TypedefDecl*, 24> ExtVectorDecls;
-
-  /// FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
-  llvm::OwningPtr<CXXFieldCollector> FieldCollector;
-
-  typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy;
-
-  /// PureVirtualClassDiagSet - a set of class declarations which we have
-  /// emitted a list of pure virtual functions. Used to prevent emitting the
-  /// same list more than once.
-  llvm::OwningPtr<RecordDeclSetTy> PureVirtualClassDiagSet;
-
-  /// \brief A mapping from external names to the most recent
-  /// locally-scoped external declaration with that name.
-  ///
-  /// This map contains external declarations introduced in local
-  /// scoped, e.g.,
-  ///
-  /// \code
-  /// void f() {
-  ///   void foo(int, int);
-  /// }
-  /// \endcode
-  ///
-  /// Here, the name "foo" will be associated with the declaration on
-  /// "foo" within f. This name is not visible outside of
-  /// "f". However, we still find it in two cases:
-  ///
-  ///   - If we are declaring another external with the name "foo", we
-  ///     can find "foo" as a previous declaration, so that the types
-  ///     of this external declaration can be checked for
-  ///     compatibility.
-  ///
-  ///   - If we would implicitly declare "foo" (e.g., due to a call to
-  ///     "foo" in C when no prototype or definition is visible), then
-  ///     we find this declaration of "foo" and complain that it is
-  ///     not visible.
-  llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternalDecls;
-
-  /// \brief All the tentative definitions encountered in the TU.
-  std::vector<VarDecl *> TentativeDefinitions;
-
-  /// \brief The set of static functions seen so far that have not been used.
-  std::vector<FunctionDecl*> UnusedStaticFuncs;
-
-  class AccessedEntity {
-  public:
-    /// A member declaration found through lookup.  The target is the
-    /// member.
-    enum MemberNonce { Member };
-
-    /// A hierarchy (base-to-derived or derived-to-base) conversion.
-    /// The target is the base class.
-    enum BaseNonce { Base };
-
-    bool isMemberAccess() const { return IsMember; }
-
-    AccessedEntity(ASTContext &Context,
-                   MemberNonce _,
-                   CXXRecordDecl *NamingClass,
-                   DeclAccessPair FoundDecl,
-                   QualType BaseObjectType)
-      : Access(FoundDecl.getAccess()), IsMember(true),
-        Target(FoundDecl.getDecl()), NamingClass(NamingClass),
-        BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) {
-    }
-
-    AccessedEntity(ASTContext &Context,
-                   BaseNonce _,
-                   CXXRecordDecl *BaseClass,
-                   CXXRecordDecl *DerivedClass,
-                   AccessSpecifier Access)
-      : Access(Access), IsMember(false),
-        Target(BaseClass), NamingClass(DerivedClass),
-        Diag(0, Context.getDiagAllocator()) {
-    }
-
-    bool isQuiet() const { return Diag.getDiagID() == 0; }
-
-    AccessSpecifier getAccess() const { return AccessSpecifier(Access); }
-
-    // These apply to member decls...
-    NamedDecl *getTargetDecl() const { return Target; }
-    CXXRecordDecl *getNamingClass() const { return NamingClass; }
-
-    // ...and these apply to hierarchy conversions.
-    CXXRecordDecl *getBaseClass() const { return cast<CXXRecordDecl>(Target); }
-    CXXRecordDecl *getDerivedClass() const { return NamingClass; }
-
-    /// Retrieves the base object type, important when accessing
-    /// an instance member.
-    QualType getBaseObjectType() const { return BaseObjectType; }
-
-    /// Sets a diagnostic to be performed.  The diagnostic is given
-    /// four (additional) arguments:
-    ///   %0 - 0 if the entity was private, 1 if protected
-    ///   %1 - the DeclarationName of the entity
-    ///   %2 - the TypeDecl type of the naming class
-    ///   %3 - the TypeDecl type of the declaring class
-    void setDiag(const PartialDiagnostic &PDiag) {
-      assert(isQuiet() && "partial diagnostic already defined");
-      Diag = PDiag;
-    }
-    PartialDiagnostic &setDiag(unsigned DiagID) {
-      assert(isQuiet() && "partial diagnostic already defined");
-      assert(DiagID && "creating null diagnostic");
-      Diag.Reset(DiagID);
-      return Diag;
-    }
-    const PartialDiagnostic &getDiag() const {
-      return Diag;
-    }
-
-  private:
-    unsigned Access : 2;
-    bool IsMember;
-    NamedDecl *Target;
-    CXXRecordDecl *NamingClass;
-    QualType BaseObjectType;
-    PartialDiagnostic Diag;
-  };
-
-  struct DelayedDiagnostic {
-    enum DDKind { Deprecation, Access };
-
-    unsigned char Kind; // actually a DDKind
-    bool Triggered;
-
-    SourceLocation Loc;
-
-    union {
-      /// Deprecation.
-      struct { NamedDecl *Decl; } DeprecationData;
-
-      /// Access control.
-      char AccessData[sizeof(AccessedEntity)];
-    };
-
-    void destroy() {
-      switch (Kind) {
-      case Access: getAccessData().~AccessedEntity(); break;
-      case Deprecation: break;
-      }
-    }
-
-    static DelayedDiagnostic makeDeprecation(SourceLocation Loc,
-                                             NamedDecl *D) {
-      DelayedDiagnostic DD;
-      DD.Kind = Deprecation;
-      DD.Triggered = false;
-      DD.Loc = Loc;
-      DD.DeprecationData.Decl = D;
-      return DD;
-    }
-
-    static DelayedDiagnostic makeAccess(SourceLocation Loc,
-                                        const AccessedEntity &Entity) {
-      DelayedDiagnostic DD;
-      DD.Kind = Access;
-      DD.Triggered = false;
-      DD.Loc = Loc;
-      new (&DD.getAccessData()) AccessedEntity(Entity);
-      return DD;
-    }
-
-    AccessedEntity &getAccessData() {
-      return *reinterpret_cast<AccessedEntity*>(AccessData);
-    }
-    const AccessedEntity &getAccessData() const {
-      return *reinterpret_cast<const AccessedEntity*>(AccessData);
-    }
-  };
-
-  /// \brief The stack of diagnostics that were delayed due to being
-  /// produced during the parsing of a declaration.
-  llvm::SmallVector<DelayedDiagnostic, 8> DelayedDiagnostics;
-
-  /// \brief The depth of the current ParsingDeclaration stack.
-  /// If nonzero, we are currently parsing a declaration (and
-  /// hence should delay deprecation warnings).
-  unsigned ParsingDeclDepth;
-
-  /// WeakUndeclaredIdentifiers - Identifiers contained in
-  /// #pragma weak before declared. rare. may alias another
-  /// identifier, declared or undeclared
-  class WeakInfo {
-    IdentifierInfo *alias;  // alias (optional)
-    SourceLocation loc;     // for diagnostics
-    bool used;              // identifier later declared?
-  public:
-    WeakInfo()
-      : alias(0), loc(SourceLocation()), used(false) {}
-    WeakInfo(IdentifierInfo *Alias, SourceLocation Loc)
-      : alias(Alias), loc(Loc), used(false) {}
-    inline IdentifierInfo * getAlias() const { return alias; }
-    inline SourceLocation getLocation() const { return loc; }
-    void setUsed(bool Used=true) { used = Used; }
-    inline bool getUsed() { return used; }
-    bool operator==(WeakInfo RHS) const {
-      return alias == RHS.getAlias() && loc == RHS.getLocation();
-    }
-    bool operator!=(WeakInfo RHS) const { return !(*this == RHS); }
-  };
-  llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers;
-
-  /// WeakTopLevelDecl - Translation-unit scoped declarations generated by
-  /// #pragma weak during processing of other Decls.
-  /// I couldn't figure out a clean way to generate these in-line, so
-  /// we store them here and handle separately -- which is a hack.
-  /// It would be best to refactor this.
-  llvm::SmallVector<Decl*,2> WeakTopLevelDecl;
-
-  IdentifierResolver IdResolver;
-
-  /// Translation Unit Scope - useful to Objective-C actions that need
-  /// to lookup file scope declarations in the "ordinary" C decl namespace.
-  /// For example, user-defined classes, built-in "id" type, etc.
-  Scope *TUScope;
-
-  /// \brief The C++ "std" namespace, where the standard library resides.
-  NamespaceDecl *StdNamespace;
-
-  /// \brief The C++ "std::bad_alloc" class, which is defined by the C++
-  /// standard library.
-  CXXRecordDecl *StdBadAlloc;
-
-  /// A flag to remember whether the implicit forms of operator new and delete
-  /// have been declared.
-  bool GlobalNewDeleteDeclared;
-
-  /// \brief The set of declarations that have been referenced within
-  /// a potentially evaluated expression.
-  typedef std::vector<std::pair<SourceLocation, Decl *> >
-    PotentiallyReferencedDecls;
-
-  /// \brief A set of diagnostics that may be emitted.
-  typedef std::vector<std::pair<SourceLocation, PartialDiagnostic> >
-    PotentiallyEmittedDiagnostics;
-
-  /// \brief Data structure used to record current or nested
-  /// expression evaluation contexts.
-  struct ExpressionEvaluationContextRecord {
-    /// \brief The expression evaluation context.
-    ExpressionEvaluationContext Context;
-
-    /// \brief The number of temporaries that were active when we
-    /// entered this expression evaluation context.
-    unsigned NumTemporaries;
-
-    /// \brief The set of declarations referenced within a
-    /// potentially potentially-evaluated context.
-    ///
-    /// When leaving a potentially potentially-evaluated context, each
-    /// of these elements will be as referenced if the corresponding
-    /// potentially potentially evaluated expression is potentially
-    /// evaluated.
-    PotentiallyReferencedDecls *PotentiallyReferenced;
-
-    /// \brief The set of diagnostics to emit should this potentially
-    /// potentially-evaluated context become evaluated.
-    PotentiallyEmittedDiagnostics *PotentiallyDiagnosed;
-
-    ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context,
-                                      unsigned NumTemporaries)
-      : Context(Context), NumTemporaries(NumTemporaries),
-        PotentiallyReferenced(0), PotentiallyDiagnosed(0) { }
-
-    void addReferencedDecl(SourceLocation Loc, Decl *Decl) {
-      if (!PotentiallyReferenced)
-        PotentiallyReferenced = new PotentiallyReferencedDecls;
-      PotentiallyReferenced->push_back(std::make_pair(Loc, Decl));
-    }
-
-    void addDiagnostic(SourceLocation Loc, const PartialDiagnostic &PD) {
-      if (!PotentiallyDiagnosed)
-        PotentiallyDiagnosed = new PotentiallyEmittedDiagnostics;
-      PotentiallyDiagnosed->push_back(std::make_pair(Loc, PD));
-    }
-
-    void Destroy() {
-      delete PotentiallyReferenced;
-      delete PotentiallyDiagnosed;
-      PotentiallyReferenced = 0;
-      PotentiallyDiagnosed = 0;
-    }
-  };
-
-  /// A stack of expression evaluation contexts.
-  llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts;
-
-  /// \brief Whether the code handled by Sema should be considered a
-  /// complete translation unit or not.
-  ///
-  /// When true (which is generally the case), Sema will perform
-  /// end-of-translation-unit semantic tasks (such as creating
-  /// initializers for tentative definitions in C) once parsing has
-  /// completed. This flag will be false when building PCH files,
-  /// since a PCH file is by definition not a complete translation
-  /// unit.
-  bool CompleteTranslationUnit;
-
-  llvm::BumpPtrAllocator BumpAlloc;
-
-  /// \brief The number of SFINAE diagnostics that have been trapped.
-  unsigned NumSFINAEErrors;
-
-  typedef llvm::DenseMap<Selector, ObjCMethodList> MethodPool;
-
-  /// Instance/Factory Method Pools - allows efficient lookup when typechecking
-  /// messages to "id". We need to maintain a list, since selectors can have
-  /// differing signatures across classes. In Cocoa, this happens to be
-  /// extremely uncommon (only 1% of selectors are "overloaded").
-  MethodPool InstanceMethodPool;
-  MethodPool FactoryMethodPool;
-
-  MethodPool::iterator ReadMethodPool(Selector Sel, bool isInstance);
-
-  /// Private Helper predicate to check for 'self'.
-  bool isSelfExpr(Expr *RExpr);
-public:
-  Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
-       bool CompleteTranslationUnit = true,
-       CodeCompleteConsumer *CompletionConsumer = 0);
-  ~Sema();
-
-  const LangOptions &getLangOptions() const { return LangOpts; }
-  Diagnostic &getDiagnostics() const { return Diags; }
-  SourceManager &getSourceManager() const { return SourceMgr; }
-  const TargetAttributesSema &getTargetAttributesSema() const;
-
-  /// \brief Helper class that creates diagnostics with optional
-  /// template instantiation stacks.
-  ///
-  /// This class provides a wrapper around the basic DiagnosticBuilder
-  /// class that emits diagnostics. SemaDiagnosticBuilder is
-  /// responsible for emitting the diagnostic (as DiagnosticBuilder
-  /// does) and, if the diagnostic comes from inside a template
-  /// instantiation, printing the template instantiation stack as
-  /// well.
-  class SemaDiagnosticBuilder : public DiagnosticBuilder {
-    Sema &SemaRef;
-    unsigned DiagID;
-
-  public:
-    SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
-      : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { }
-
-    explicit SemaDiagnosticBuilder(Sema &SemaRef)
-      : DiagnosticBuilder(DiagnosticBuilder::Suppress), SemaRef(SemaRef) { }
-
-    ~SemaDiagnosticBuilder();
-  };
-
-  /// \brief Emit a diagnostic.
-  SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
-
-  /// \brief Emit a partial diagnostic.
-  SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic& PD);
-
-  /// \brief Build a partial diagnostic.
-  PartialDiagnostic PDiag(unsigned DiagID = 0) {
-    return PartialDiagnostic(DiagID, Context.getDiagAllocator());
-  }
-
-  virtual void DeleteExpr(ExprTy *E);
-  virtual void DeleteStmt(StmtTy *S);
-
-  OwningExprResult Owned(Expr* E) {
-    assert(!E || E->isRetained());
-    return OwningExprResult(*this, E);
-  }
-  OwningExprResult Owned(ExprResult R) {
-    if (R.isInvalid())
-      return ExprError();
-    assert(!R.get() || ((Expr*) R.get())->isRetained());
-    return OwningExprResult(*this, R.get());
-  }
-  OwningStmtResult Owned(Stmt* S) {
-    assert(!S || S->isRetained());
-    return OwningStmtResult(*this, S);
-  }
-
-  virtual void ActOnEndOfTranslationUnit();
-
-  Scope *getScopeForContext(DeclContext *Ctx);
-
-  void PushFunctionScope();
-  void PushBlockScope(Scope *BlockScope, BlockDecl *Block);
-  void PopFunctionOrBlockScope();
-
-  /// getLabelMap() - Return the current label map.  If we're in a block, we
-  /// return it.
-  llvm::DenseMap<IdentifierInfo*, LabelStmt*> &getLabelMap() {
-    if (FunctionScopes.empty())
-      return TopFunctionScope.LabelMap;
-
-    return FunctionScopes.back()->LabelMap;
-  }
-
-  /// getSwitchStack - This is returns the switch stack for the current block or
-  /// function.
-  llvm::SmallVector<SwitchStmt*,8> &getSwitchStack() {
-    if (FunctionScopes.empty())
-      return TopFunctionScope.SwitchStack;
-
-    return FunctionScopes.back()->SwitchStack;
-  }
-
-  /// \brief Determine whether the current function or block needs scope
-  /// checking.
-  bool &FunctionNeedsScopeChecking() {
-    if (FunctionScopes.empty())
-      return TopFunctionScope.NeedsScopeChecking;
-
-    return FunctionScopes.back()->NeedsScopeChecking;
-  }
-
-  bool hasAnyErrorsInThisFunction() const;
-
-  /// \brief Retrieve the current block, if any.
-  BlockScopeInfo *getCurBlock();
-
-  /// WeakTopLevelDeclDecls - access to #pragma weak-generated Decls
-  llvm::SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; }
-
-  //===--------------------------------------------------------------------===//
-  // Type Analysis / Processing: SemaType.cpp.
-  //
-
-  QualType adjustParameterType(QualType T);
-  QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs);
-  QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVR) {
-    return BuildQualifiedType(T, Loc, Qualifiers::fromCVRMask(CVR));
-  }
-  QualType BuildPointerType(QualType T,
-                            SourceLocation Loc, DeclarationName Entity);
-  QualType BuildReferenceType(QualType T, bool LValueRef,
-                              SourceLocation Loc, DeclarationName Entity);
-  QualType BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
-                          Expr *ArraySize, unsigned Quals,
-                          SourceRange Brackets, DeclarationName Entity);
-  QualType BuildExtVectorType(QualType T, ExprArg ArraySize,
-                              SourceLocation AttrLoc);
-  QualType BuildFunctionType(QualType T,
-                             QualType *ParamTypes, unsigned NumParamTypes,
-                             bool Variadic, unsigned Quals,
-                             SourceLocation Loc, DeclarationName Entity);
-  QualType BuildMemberPointerType(QualType T, QualType Class,
-                                  SourceLocation Loc,
-                                  DeclarationName Entity);
-  QualType BuildBlockPointerType(QualType T,
-                                 SourceLocation Loc, DeclarationName Entity);
-  TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S,
-                                       TagDecl **OwnedDecl = 0);
-  TypeSourceInfo *GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
-                                               TypeSourceInfo *ReturnTypeInfo);
-  /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
-  QualType CreateLocInfoType(QualType T, TypeSourceInfo *TInfo);
-  DeclarationName GetNameForDeclarator(Declarator &D);
-  DeclarationName GetNameFromUnqualifiedId(const UnqualifiedId &Name);
-  static QualType GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo = 0);
-  bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
-  bool CheckDistantExceptionSpec(QualType T);
-  bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New);
-  bool CheckEquivalentExceptionSpec(
-      const FunctionProtoType *Old, SourceLocation OldLoc,
-      const FunctionProtoType *New, SourceLocation NewLoc);
-  bool CheckEquivalentExceptionSpec(
-      const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
-      const FunctionProtoType *Old, SourceLocation OldLoc,
-      const FunctionProtoType *New, SourceLocation NewLoc,
-      bool *MissingExceptionSpecification = 0,
-      bool *MissingEmptyExceptionSpecification = 0);
-  bool CheckExceptionSpecSubset(
-      const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID,
-      const FunctionProtoType *Superset, SourceLocation SuperLoc,
-      const FunctionProtoType *Subset, SourceLocation SubLoc);
-  bool CheckParamExceptionSpec(const PartialDiagnostic & NoteID,
-      const FunctionProtoType *Target, SourceLocation TargetLoc,
-      const FunctionProtoType *Source, SourceLocation SourceLoc);
-
-  virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
-
-  bool RequireCompleteType(SourceLocation Loc, QualType T,
-                           const PartialDiagnostic &PD,
-                           std::pair<SourceLocation, PartialDiagnostic> Note);
-  bool RequireCompleteType(SourceLocation Loc, QualType T,
-                           const PartialDiagnostic &PD);
-  bool RequireCompleteType(SourceLocation Loc, QualType T,
-                           unsigned DiagID);
-
-  QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
-                             const CXXScopeSpec &SS, QualType T);
-
-  QualType BuildTypeofExprType(Expr *E);
-  QualType BuildDecltypeType(Expr *E);
-
-  //===--------------------------------------------------------------------===//
-  // Symbol table / Decl tracking callbacks: SemaDecl.cpp.
-  //
-
-  /// getDeclName - Return a pretty name for the specified decl if possible, or
-  /// an empty string if not.  This is used for pretty crash reporting.
-  virtual std::string getDeclName(DeclPtrTy D);
-
-  DeclGroupPtrTy ConvertDeclToDeclGroup(DeclPtrTy Ptr);
-
-  virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
-                              Scope *S, CXXScopeSpec *SS,
-                              bool isClassName = false,
-                              TypeTy *ObjectType = 0);
-  virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
-  virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
-                                       SourceLocation IILoc,
-                                       Scope *S,
-                                       CXXScopeSpec *SS,
-                                       TypeTy *&SuggestedType);
-
-  virtual DeclPtrTy ActOnDeclarator(Scope *S, Declarator &D) {
-    return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
-  }
-
-  DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
-                             MultiTemplateParamsArg TemplateParameterLists,
-                             bool IsFunctionDefinition);
-  void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
-                                        const LookupResult &Previous,
-                                        Scope *S);
-  void DiagnoseFunctionSpecifiers(Declarator& D);
-  void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R);
-  void CheckShadow(Scope *S, VarDecl *D);
-  NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                    QualType R, TypeSourceInfo *TInfo,
-                                    LookupResult &Previous, bool &Redeclaration);
-  NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                     QualType R, TypeSourceInfo *TInfo,
-                                     LookupResult &Previous,
-                                     MultiTemplateParamsArg TemplateParamLists,
-                                     bool &Redeclaration);
-  void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous,
-                                bool &Redeclaration);
-  NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
-                                     QualType R, TypeSourceInfo *TInfo,
-                                     LookupResult &Previous,
-                                     MultiTemplateParamsArg TemplateParamLists,
-                                     bool IsFunctionDefinition,
-                                     bool &Redeclaration);
-  void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
-  void CheckFunctionDeclaration(Scope *S,
-                                FunctionDecl *NewFD, LookupResult &Previous,
-                                bool IsExplicitSpecialization,
-                                bool &Redeclaration,
-                                bool &OverloadableAttrRequired);
-  void CheckMain(FunctionDecl *FD);
-  virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D);
-  ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
-                                          SourceLocation Loc,
-                                          QualType T);
-  ParmVarDecl *CheckParameter(DeclContext *DC,
-                              TypeSourceInfo *TSInfo, QualType T,
-                              IdentifierInfo *Name,
-                              SourceLocation NameLoc,
-                              VarDecl::StorageClass StorageClass,
-                              VarDecl::StorageClass StorageClassAsWritten);
-  virtual void ActOnParamDefaultArgument(DeclPtrTy param,
-                                         SourceLocation EqualLoc,
-                                         ExprArg defarg);
-  virtual void ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
-                                                 SourceLocation EqualLoc,
-                                                 SourceLocation ArgLoc);
-  virtual void ActOnParamDefaultArgumentError(DeclPtrTy param);
-  bool SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
-                               SourceLocation EqualLoc);
-
-
-  // Contains the locations of the beginning of unparsed default
-  // argument locations.
-  llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
-
-  virtual void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init);
-  void AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit);
-  void ActOnUninitializedDecl(DeclPtrTy dcl, bool TypeContainsUndeducedAuto);
-  virtual void ActOnInitializerError(DeclPtrTy Dcl);
-  virtual void SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc);
-  virtual DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
-                                                 DeclPtrTy *Group,
-                                                 unsigned NumDecls);
-  virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
-                                               SourceLocation LocAfterDecls);
-  virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, Declarator &D);
-  virtual DeclPtrTy ActOnStartOfFunctionDef(Scope *S, DeclPtrTy D);
-  virtual void ActOnStartOfObjCMethodDef(Scope *S, DeclPtrTy D);
-
-  virtual DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body);
-  DeclPtrTy ActOnFinishFunctionBody(DeclPtrTy Decl, StmtArg Body,
-                                    bool IsInstantiation);
-
-  /// \brief Diagnose any unused parameters in the given sequence of
-  /// ParmVarDecl pointers.
-  template<typename InputIterator>
-  void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) {
-    if (Diags.getDiagnosticLevel(diag::warn_unused_parameter) ==
-          Diagnostic::Ignored)
-      return;
-
-    // Don't diagnose unused-parameter errors in template instantiations; we
-    // will already have done so in the template itself.
-    if (!ActiveTemplateInstantiations.empty())
-      return;
-
-    for (; Param != ParamEnd; ++Param) {
-      if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
-          !(*Param)->template hasAttr<UnusedAttr>()) {
-        Diag((*Param)->getLocation(), diag::warn_unused_parameter)
-          << (*Param)->getDeclName();
-      }
-    }
-  }
-
-  void DiagnoseInvalidJumps(Stmt *Body);
-  virtual DeclPtrTy ActOnFileScopeAsmDecl(SourceLocation Loc, ExprArg expr);
-
-  /// Scope actions.
-  virtual void ActOnPopScope(SourceLocation Loc, Scope *S);
-  virtual void ActOnTranslationUnitScope(SourceLocation Loc, Scope *S);
-
-  /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
-  /// no declarator (e.g. "struct foo;") is parsed.
-  virtual DeclPtrTy ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
-                                               DeclSpec &DS);
-
-  virtual DeclPtrTy BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
-                                                AccessSpecifier AS,
-                                                RecordDecl *Record);
-
-  bool isAcceptableTagRedeclaration(const TagDecl *Previous,
-                                    TagDecl::TagKind NewTag,
-                                    SourceLocation NewTagLoc,
-                                    const IdentifierInfo &Name);
-
-  virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
-                             SourceLocation KWLoc, CXXScopeSpec &SS,
-                             IdentifierInfo *Name, SourceLocation NameLoc,
-                             AttributeList *Attr, AccessSpecifier AS,
-                             MultiTemplateParamsArg TemplateParameterLists,
-                             bool &OwnedDecl, bool &IsDependent);
-
-  virtual TypeResult ActOnDependentTag(Scope *S,
-                                       unsigned TagSpec,
-                                       TagUseKind TUK,
-                                       const CXXScopeSpec &SS,
-                                       IdentifierInfo *Name,
-                                       SourceLocation TagLoc,
-                                       SourceLocation NameLoc);
-
-  virtual void ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
-                         IdentifierInfo *ClassName,
-                         llvm::SmallVectorImpl<DeclPtrTy> &Decls);
-  virtual DeclPtrTy ActOnField(Scope *S, DeclPtrTy TagD,
-                               SourceLocation DeclStart,
-                               Declarator &D, ExprTy *BitfieldWidth);
-
-  FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart,
-                         Declarator &D, Expr *BitfieldWidth,
-                         AccessSpecifier AS);
-
-  FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T,
-                            TypeSourceInfo *TInfo,
-                            RecordDecl *Record, SourceLocation Loc,
-                            bool Mutable, Expr *BitfieldWidth,
-                            SourceLocation TSSL,
-                            AccessSpecifier AS, NamedDecl *PrevDecl,
-                            Declarator *D = 0);
-
-  enum CXXSpecialMember {
-    CXXInvalid = -1,
-    CXXConstructor = 0,
-    CXXCopyConstructor = 1,
-    CXXCopyAssignment = 2,
-    CXXDestructor = 3
-  };
-  void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem);
-  CXXSpecialMember getSpecialMember(const CXXMethodDecl *MD);
-
-  virtual DeclPtrTy ActOnIvar(Scope *S, SourceLocation DeclStart,
-                              DeclPtrTy IntfDecl,
-                              Declarator &D, ExprTy *BitfieldWidth,
-                              tok::ObjCKeywordKind visibility);
-
-  // This is used for both record definitions and ObjC interface declarations.
-  virtual void ActOnFields(Scope* S,
-                           SourceLocation RecLoc, DeclPtrTy TagDecl,
-                           DeclPtrTy *Fields, unsigned NumFields,
-                           SourceLocation LBrac, SourceLocation RBrac,
-                           AttributeList *AttrList);
-
-  /// ActOnTagStartDefinition - Invoked when we have entered the
-  /// scope of a tag's definition (e.g., for an enumeration, class,
-  /// struct, or union).
-  virtual void ActOnTagStartDefinition(Scope *S, DeclPtrTy TagDecl);
-
-  /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a
-  /// C++ record definition's base-specifiers clause and are starting its
-  /// member declarations.
-  virtual void ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagDecl,
-                                               SourceLocation LBraceLoc);
-
-  /// ActOnTagFinishDefinition - Invoked once we have finished parsing
-  /// the definition of a tag (enumeration, class, struct, or union).
-  virtual void ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagDecl,
-                                        SourceLocation RBraceLoc);
-
-  /// ActOnTagDefinitionError - Invoked when there was an unrecoverable
-  /// error parsing the definition of a tag.
-  virtual void ActOnTagDefinitionError(Scope *S, DeclPtrTy TagDecl);
-
-  EnumConstantDecl *CheckEnumConstant(EnumDecl *Enum,
-                                      EnumConstantDecl *LastEnumConst,
-                                      SourceLocation IdLoc,
-                                      IdentifierInfo *Id,
-                                      ExprArg val);
-
-  virtual DeclPtrTy ActOnEnumConstant(Scope *S, DeclPtrTy EnumDecl,
-                                      DeclPtrTy LastEnumConstant,
-                                      SourceLocation IdLoc, IdentifierInfo *Id,
-                                      SourceLocation EqualLoc, ExprTy *Val);
-  virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
-                             SourceLocation RBraceLoc, DeclPtrTy EnumDecl,
-                             DeclPtrTy *Elements, unsigned NumElements,
-                             Scope *S, AttributeList *Attr);
-
-  DeclContext *getContainingDC(DeclContext *DC);
-
-  /// Set the current declaration context until it gets popped.
-  void PushDeclContext(Scope *S, DeclContext *DC);
-  void PopDeclContext();
-
-  /// EnterDeclaratorContext - Used when we must lookup names in the context
-  /// of a declarator's nested name specifier.
-  void EnterDeclaratorContext(Scope *S, DeclContext *DC);
-  void ExitDeclaratorContext(Scope *S);
-
-  DeclContext *getFunctionLevelDeclContext();
-
-  /// getCurFunctionDecl - If inside of a function body, this returns a pointer
-  /// to the function decl for the function being parsed.  If we're currently
-  /// in a 'block', this returns the containing context.
-  FunctionDecl *getCurFunctionDecl();
-
-  /// getCurMethodDecl - If inside of a method body, this returns a pointer to
-  /// the method decl for the method being parsed.  If we're currently
-  /// in a 'block', this returns the containing context.
-  ObjCMethodDecl *getCurMethodDecl();
-
-  /// getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method
-  /// or C function we're in, otherwise return null.  If we're currently
-  /// in a 'block', this returns the containing context.
-  NamedDecl *getCurFunctionOrMethodDecl();
-
-  /// Add this decl to the scope shadowed decl chains.
-  void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext = true);
-
-  /// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
-  /// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
-  /// true if 'D' belongs to the given declaration context.
-  bool isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S = 0);
-
-  /// Finds the scope corresponding to the given decl context, if it
-  /// happens to be an enclosing scope.  Otherwise return NULL.
-  Scope *getScopeForDeclContext(Scope *S, DeclContext *DC) {
-    DeclContext *TargetDC = DC->getPrimaryContext();
-    do {
-      if (DeclContext *ScopeDC = (DeclContext*) S->getEntity())
-        if (ScopeDC->getPrimaryContext() == TargetDC)
-          return S;
-    } while ((S = S->getParent()));
-
-    return NULL;
-  }
-
-  /// Subroutines of ActOnDeclarator().
-  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
-                                TypeSourceInfo *TInfo);
-  void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
-  bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
-  bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
-  void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
-  bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
-
-  // AssignmentAction - This is used by all the assignment diagnostic functions
-  // to represent what is actually causing the operation
-  enum AssignmentAction {
-    AA_Assigning,
-    AA_Passing,
-    AA_Returning,
-    AA_Converting,
-    AA_Initializing,
-    AA_Sending,
-    AA_Casting
-  };
-
-  /// C++ Overloading.
-  enum OverloadKind {
-    /// This is a legitimate overload: the existing declarations are
-    /// functions or function templates with different signatures.
-    Ovl_Overload,
-
-    /// This is not an overload because the signature exactly matches
-    /// an existing declaration.
-    Ovl_Match,
-
-    /// This is not an overload because the lookup results contain a
-    /// non-function.
-    Ovl_NonFunction
-  };
-  OverloadKind CheckOverload(Scope *S,
-                             FunctionDecl *New,
-                             const LookupResult &OldDecls,
-                             NamedDecl *&OldDecl,
-                             bool IsForUsingDecl);
-  bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl);
-
-  bool TryImplicitConversion(InitializationSequence &Sequence,
-                             const InitializedEntity &Entity,
-                             Expr *From,
-                             bool SuppressUserConversions,
-                             bool AllowExplicit,
-                             bool InOverloadResolution);
-
-  ImplicitConversionSequence
-  TryImplicitConversion(Expr* From, QualType ToType,
-                        bool SuppressUserConversions,
-                        bool AllowExplicit,
-                        bool InOverloadResolution);
-  bool IsStandardConversion(Expr *From, QualType ToType,
-                            bool InOverloadResolution,
-                            StandardConversionSequence& SCS);
-  bool IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType);
-  bool IsFloatingPointPromotion(QualType FromType, QualType ToType);
-  bool IsComplexPromotion(QualType FromType, QualType ToType);
-  bool IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
-                           bool InOverloadResolution,
-                           QualType& ConvertedType, bool &IncompatibleObjC);
-  bool isObjCPointerConversion(QualType FromType, QualType ToType,
-                               QualType& ConvertedType, bool &IncompatibleObjC);
-  bool FunctionArgTypesAreEqual (FunctionProtoType* OldType, 
-                                 FunctionProtoType* NewType);
-  
-  bool CheckPointerConversion(Expr *From, QualType ToType,
-                              CastExpr::CastKind &Kind,
-                              CXXBaseSpecifierArray& BasePath,
-                              bool IgnoreBaseAccess);
-  bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType,
-                                 bool InOverloadResolution,
-                                 QualType &ConvertedType);
-  bool CheckMemberPointerConversion(Expr *From, QualType ToType,
-                                    CastExpr::CastKind &Kind,
-                                    CXXBaseSpecifierArray &BasePath,
-                                    bool IgnoreBaseAccess);
-  bool IsQualificationConversion(QualType FromType, QualType ToType);
-  OverloadingResult IsUserDefinedConversion(Expr *From, QualType ToType,
-                               UserDefinedConversionSequence& User,
-                               OverloadCandidateSet& Conversions,
-                               bool AllowExplicit);
-  bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
-
-
-  ImplicitConversionSequence::CompareKind
-  CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
-                                     const ImplicitConversionSequence& ICS2);
-
-  ImplicitConversionSequence::CompareKind
-  CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
-                                     const StandardConversionSequence& SCS2);
-
-  ImplicitConversionSequence::CompareKind
-  CompareQualificationConversions(const StandardConversionSequence& SCS1,
-                                  const StandardConversionSequence& SCS2);
-
-  ImplicitConversionSequence::CompareKind
-  CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
-                                  const StandardConversionSequence& SCS2);
-
-  OwningExprResult PerformCopyInitialization(const InitializedEntity &Entity,
-                                             SourceLocation EqualLoc,
-                                             OwningExprResult Init);
-  ImplicitConversionSequence
-  TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method,
-                                  CXXRecordDecl *ActingContext);
-  bool PerformObjectArgumentInitialization(Expr *&From,
-                                           NestedNameSpecifier *Qualifier,
-                                           NamedDecl *FoundDecl,
-                                           CXXMethodDecl *Method);
-
-  ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
-  bool PerformContextuallyConvertToBool(Expr *&From);
-
-  ImplicitConversionSequence TryContextuallyConvertToObjCId(Expr *From);
-  bool PerformContextuallyConvertToObjCId(Expr *&From);
-
-  OwningExprResult 
-  ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
-                                     const PartialDiagnostic &NotIntDiag,
-                                     const PartialDiagnostic &IncompleteDiag,
-                                     const PartialDiagnostic &ExplicitConvDiag,
-                                     const PartialDiagnostic &ExplicitConvNote,
-                                     const PartialDiagnostic &AmbigDiag,
-                                     const PartialDiagnostic &AmbigNote,
-                                     const PartialDiagnostic &ConvDiag);
-  
-  bool PerformObjectMemberConversion(Expr *&From,
-                                     NestedNameSpecifier *Qualifier,
-                                     NamedDecl *FoundDecl,
-                                     NamedDecl *Member);
-
-  // Members have to be NamespaceDecl* or TranslationUnitDecl*.
-  // TODO: make this is a typesafe union.
-  typedef llvm::SmallPtrSet<DeclContext   *, 16> AssociatedNamespaceSet;
-  typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
-
-  void AddOverloadCandidate(NamedDecl *Function,
-                            DeclAccessPair FoundDecl,
-                            Expr **Args, unsigned NumArgs,
-                            OverloadCandidateSet &CandidateSet);
-
-  void AddOverloadCandidate(FunctionDecl *Function,
-                            DeclAccessPair FoundDecl,
-                            Expr **Args, unsigned NumArgs,
-                            OverloadCandidateSet& CandidateSet,
-                            bool SuppressUserConversions = false,
-                            bool PartialOverloading = false);
-  void AddFunctionCandidates(const UnresolvedSetImpl &Functions,
-                             Expr **Args, unsigned NumArgs,
-                             OverloadCandidateSet& CandidateSet,
-                             bool SuppressUserConversions = false);
-  void AddMethodCandidate(DeclAccessPair FoundDecl,
-                          QualType ObjectType,
-                          Expr **Args, unsigned NumArgs,
-                          OverloadCandidateSet& CandidateSet,
-                          bool SuppressUserConversion = false);
-  void AddMethodCandidate(CXXMethodDecl *Method,
-                          DeclAccessPair FoundDecl,
-                          CXXRecordDecl *ActingContext, QualType ObjectType,
-                          Expr **Args, unsigned NumArgs,
-                          OverloadCandidateSet& CandidateSet,
-                          bool SuppressUserConversions = false);
-  void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
-                                  DeclAccessPair FoundDecl,
-                                  CXXRecordDecl *ActingContext,
-                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                                  QualType ObjectType,
-                                  Expr **Args, unsigned NumArgs,
-                                  OverloadCandidateSet& CandidateSet,
-                                  bool SuppressUserConversions = false);
-  void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
-                                    DeclAccessPair FoundDecl,
-                      const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                                    Expr **Args, unsigned NumArgs,
-                                    OverloadCandidateSet& CandidateSet,
-                                    bool SuppressUserConversions = false);
-  void AddConversionCandidate(CXXConversionDecl *Conversion,
-                              DeclAccessPair FoundDecl,
-                              CXXRecordDecl *ActingContext,
-                              Expr *From, QualType ToType,
-                              OverloadCandidateSet& CandidateSet);
-  void AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
-                                      DeclAccessPair FoundDecl,
-                                      CXXRecordDecl *ActingContext,
-                                      Expr *From, QualType ToType,
-                                      OverloadCandidateSet &CandidateSet);
-  void AddSurrogateCandidate(CXXConversionDecl *Conversion,
-                             DeclAccessPair FoundDecl,
-                             CXXRecordDecl *ActingContext,
-                             const FunctionProtoType *Proto,
-                             QualType ObjectTy, Expr **Args, unsigned NumArgs,
-                             OverloadCandidateSet& CandidateSet);
-  void AddMemberOperatorCandidates(OverloadedOperatorKind Op,
-                                   SourceLocation OpLoc,
-                                   Expr **Args, unsigned NumArgs,
-                                   OverloadCandidateSet& CandidateSet,
-                                   SourceRange OpRange = SourceRange());
-  void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
-                           Expr **Args, unsigned NumArgs,
-                           OverloadCandidateSet& CandidateSet,
-                           bool IsAssignmentOperator = false,
-                           unsigned NumContextualBoolArguments = 0);
-  void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
-                                    SourceLocation OpLoc,
-                                    Expr **Args, unsigned NumArgs,
-                                    OverloadCandidateSet& CandidateSet);
-  void AddArgumentDependentLookupCandidates(DeclarationName Name,
-                                            bool Operator,
-                                            Expr **Args, unsigned NumArgs,
-                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                                            OverloadCandidateSet& CandidateSet,
-                                            bool PartialOverloading = false);
-  bool isBetterOverloadCandidate(const OverloadCandidate& Cand1,
-                                 const OverloadCandidate& Cand2,
-                                 SourceLocation Loc);
-  OverloadingResult BestViableFunction(OverloadCandidateSet& CandidateSet,
-                                       SourceLocation Loc,
-                                       OverloadCandidateSet::iterator& Best);
-
-  enum OverloadCandidateDisplayKind {
-    /// Requests that all candidates be shown.  Viable candidates will
-    /// be printed first.
-    OCD_AllCandidates,
-
-    /// Requests that only viable candidates be shown.
-    OCD_ViableCandidates
-  };
-  void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
-                               OverloadCandidateDisplayKind OCD,
-                               Expr **Args, unsigned NumArgs,
-                               const char *Opc = 0,
-                               SourceLocation Loc = SourceLocation());
-
-  void NoteOverloadCandidate(FunctionDecl *Fn);
-  void DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
-                                   SourceLocation CaretLoc,
-                                   const PartialDiagnostic &PDiag);
-
-  FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
-                                                   bool Complain,
-                                                   DeclAccessPair &Found);
-  FunctionDecl *ResolveSingleFunctionTemplateSpecialization(Expr *From);
-
-  Expr *FixOverloadedFunctionReference(Expr *E,
-                                       DeclAccessPair FoundDecl,
-                                       FunctionDecl *Fn);
-  OwningExprResult FixOverloadedFunctionReference(OwningExprResult,
-                                                  DeclAccessPair FoundDecl,
-                                                  FunctionDecl *Fn);
-
-  void AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
-                                   Expr **Args, unsigned NumArgs,
-                                   OverloadCandidateSet &CandidateSet,
-                                   bool PartialOverloading = false);
-
-  OwningExprResult BuildOverloadedCallExpr(Scope *S, Expr *Fn,
-                                           UnresolvedLookupExpr *ULE,
-                                           SourceLocation LParenLoc,
-                                           Expr **Args, unsigned NumArgs,
-                                           SourceLocation *CommaLocs,
-                                           SourceLocation RParenLoc);
-
-  OwningExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc,
-                                           unsigned Opc,
-                                           const UnresolvedSetImpl &Fns,
-                                           ExprArg input);
-
-  OwningExprResult CreateOverloadedBinOp(SourceLocation OpLoc,
-                                         unsigned Opc,
-                                         const UnresolvedSetImpl &Fns,
-                                         Expr *LHS, Expr *RHS);
-
-  OwningExprResult CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
-                                                      SourceLocation RLoc,
-                                                      ExprArg Base,ExprArg Idx);
-
-  OwningExprResult
-  BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
-                            SourceLocation LParenLoc, Expr **Args,
-                            unsigned NumArgs, SourceLocation *CommaLocs,
-                            SourceLocation RParenLoc);
-  ExprResult
-  BuildCallToObjectOfClassType(Scope *S, Expr *Object, SourceLocation LParenLoc,
-                               Expr **Args, unsigned NumArgs,
-                               SourceLocation *CommaLocs,
-                               SourceLocation RParenLoc);
-
-  OwningExprResult BuildOverloadedArrowExpr(Scope *S, ExprArg Base,
-                                            SourceLocation OpLoc);
-
-  /// CheckCallReturnType - Checks that a call expression's return type is
-  /// complete. Returns true on failure. The location passed in is the location
-  /// that best represents the call.
-  bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc,
-                           CallExpr *CE, FunctionDecl *FD);
-
-  /// Helpers for dealing with blocks and functions.
-  bool CheckParmsForFunctionDef(FunctionDecl *FD);
-  void CheckCXXDefaultArguments(FunctionDecl *FD);
-  void CheckExtraCXXDefaultArguments(Declarator &D);
-  Scope *getNonFieldDeclScope(Scope *S);
-
-  /// \name Name lookup
-  ///
-  /// These routines provide name lookup that is used during semantic
-  /// analysis to resolve the various kinds of names (identifiers,
-  /// overloaded operator names, constructor names, etc.) into zero or
-  /// more declarations within a particular scope. The major entry
-  /// points are LookupName, which performs unqualified name lookup,
-  /// and LookupQualifiedName, which performs qualified name lookup.
-  ///
-  /// All name lookup is performed based on some specific criteria,
-  /// which specify what names will be visible to name lookup and how
-  /// far name lookup should work. These criteria are important both
-  /// for capturing language semantics (certain lookups will ignore
-  /// certain names, for example) and for performance, since name
-  /// lookup is often a bottleneck in the compilation of C++. Name
-  /// lookup criteria is specified via the LookupCriteria enumeration.
-  ///
-  /// The results of name lookup can vary based on the kind of name
-  /// lookup performed, the current language, and the translation
-  /// unit. In C, for example, name lookup will either return nothing
-  /// (no entity found) or a single declaration. In C++, name lookup
-  /// can additionally refer to a set of overloaded functions or
-  /// result in an ambiguity. All of the possible results of name
-  /// lookup are captured by the LookupResult class, which provides
-  /// the ability to distinguish among them.
-  //@{
-
-  /// @brief Describes the kind of name lookup to perform.
-  enum LookupNameKind {
-    /// Ordinary name lookup, which finds ordinary names (functions,
-    /// variables, typedefs, etc.) in C and most kinds of names
-    /// (functions, variables, members, types, etc.) in C++.
-    LookupOrdinaryName = 0,
-    /// Tag name lookup, which finds the names of enums, classes,
-    /// structs, and unions.
-    LookupTagName,
-    /// Member name lookup, which finds the names of
-    /// class/struct/union members.
-    LookupMemberName,
-    // Look up of an operator name (e.g., operator+) for use with
-    // operator overloading. This lookup is similar to ordinary name
-    // lookup, but will ignore any declarations that are class
-    // members.
-    LookupOperatorName,
-    /// Look up of a name that precedes the '::' scope resolution
-    /// operator in C++. This lookup completely ignores operator, object,
-    /// function, and enumerator names (C++ [basic.lookup.qual]p1).
-    LookupNestedNameSpecifierName,
-    /// Look up a namespace name within a C++ using directive or
-    /// namespace alias definition, ignoring non-namespace names (C++
-    /// [basic.lookup.udir]p1).
-    LookupNamespaceName,
-    /// Look up all declarations in a scope with the given name,
-    /// including resolved using declarations.  This is appropriate
-    /// for checking redeclarations for a using declaration.
-    LookupUsingDeclName,
-    /// Look up an ordinary name that is going to be redeclared as a
-    /// name with linkage. This lookup ignores any declarations that
-    /// are outside of the current scope unless they have linkage. See
-    /// C99 6.2.2p4-5 and C++ [basic.link]p6.
-    LookupRedeclarationWithLinkage,
-    /// Look up the name of an Objective-C protocol.
-    LookupObjCProtocolName
-  };
-
-  /// \brief Specifies whether (or how) name lookup is being performed for a
-  /// redeclaration (vs. a reference).
-  enum RedeclarationKind {
-    /// \brief The lookup is a reference to this name that is not for the
-    /// purpose of redeclaring the name.
-    NotForRedeclaration = 0,
-    /// \brief The lookup results will be used for redeclaration of a name,
-    /// if an entity by that name already exists.
-    ForRedeclaration
-  };
-
-private:
-  bool CppLookupName(LookupResult &R, Scope *S);
-
-public:
-  /// \brief Look up a name, looking for a single declaration.  Return
-  /// null if the results were absent, ambiguous, or overloaded.
-  ///
-  /// It is preferable to use the elaborated form and explicitly handle
-  /// ambiguity and overloaded.
-  NamedDecl *LookupSingleName(Scope *S, DeclarationName Name,
-                              SourceLocation Loc,
-                              LookupNameKind NameKind,
-                              RedeclarationKind Redecl
-                                = NotForRedeclaration);
-  bool LookupName(LookupResult &R, Scope *S,
-                  bool AllowBuiltinCreation = false);
-  bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
-                           bool InUnqualifiedLookup = false);
-  bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
-                        bool AllowBuiltinCreation = false,
-                        bool EnteringContext = false);
-  ObjCProtocolDecl *LookupProtocol(IdentifierInfo *II, SourceLocation IdLoc);
-
-  void LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
-                                    QualType T1, QualType T2,
-                                    UnresolvedSetImpl &Functions);
-  DeclContext::lookup_result LookupConstructors(CXXRecordDecl *Class);
-  CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
-
-  void ArgumentDependentLookup(DeclarationName Name, bool Operator,
-                               Expr **Args, unsigned NumArgs,
-                               ADLResult &Functions);
-
-  void LookupVisibleDecls(Scope *S, LookupNameKind Kind,
-                          VisibleDeclConsumer &Consumer);
-  void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
-                          VisibleDeclConsumer &Consumer);
-  
-  /// \brief The context in which typo-correction occurs.
-  ///
-  /// The typo-correction context affects which keywords (if any) are
-  /// considered when trying to correct for typos.
-  enum CorrectTypoContext {
-    /// \brief An unknown context, where any keyword might be valid.
-    CTC_Unknown,
-    /// \brief A context where no keywords are used (e.g. we expect an actual
-    /// name).
-    CTC_NoKeywords,
-    /// \brief A context where we're correcting a type name.
-    CTC_Type,
-    /// \brief An expression context.
-    CTC_Expression,
-    /// \brief A type cast, or anything else that can be followed by a '<'.
-    CTC_CXXCasts,
-    /// \brief A member lookup context.
-    CTC_MemberLookup,
-    /// \brief The receiver of an Objective-C message send within an
-    /// Objective-C method where 'super' is a valid keyword.
-    CTC_ObjCMessageReceiver
-  };
-
-  DeclarationName CorrectTypo(LookupResult &R, Scope *S, CXXScopeSpec *SS,
-                              DeclContext *MemberContext = 0,
-                              bool EnteringContext = false,
-                              CorrectTypoContext CTC = CTC_Unknown,
-                              const ObjCObjectPointerType *OPT = 0);
-
-  void FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
-                                   AssociatedNamespaceSet &AssociatedNamespaces,
-                                   AssociatedClassSet &AssociatedClasses);
-
-  bool DiagnoseAmbiguousLookup(LookupResult &Result);
-  //@}
-
-  ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id,
-                                          SourceLocation IdLoc,
-                                          bool TypoCorrection = false);
-  NamedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
-                                 Scope *S, bool ForRedeclaration,
-                                 SourceLocation Loc);
-  NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II,
-                                      Scope *S);
-  void AddKnownFunctionAttributes(FunctionDecl *FD);
-
-  // More parsing and symbol table subroutines.
-
-  // Decl attributes - this routine is the top level dispatcher.
-  void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
-  void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL);
-
-  void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
-                           bool &IncompleteImpl, unsigned DiagID);
-  void WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethod,
-                                   ObjCMethodDecl *IntfMethod);
-
-  bool isPropertyReadonly(ObjCPropertyDecl *PropertyDecl,
-                          ObjCInterfaceDecl *IDecl);
-
-  /// CheckProtocolMethodDefs - This routine checks unimplemented
-  /// methods declared in protocol, and those referenced by it.
-  /// \param IDecl - Used for checking for methods which may have been
-  /// inherited.
-  void CheckProtocolMethodDefs(SourceLocation ImpLoc,
-                               ObjCProtocolDecl *PDecl,
-                               bool& IncompleteImpl,
-                               const llvm::DenseSet<Selector> &InsMap,
-                               const llvm::DenseSet<Selector> &ClsMap,
-                               ObjCContainerDecl *CDecl);
-
-  /// CheckImplementationIvars - This routine checks if the instance variables
-  /// listed in the implelementation match those listed in the interface.
-  void CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
-                                ObjCIvarDecl **Fields, unsigned nIvars,
-                                SourceLocation Loc);
-
-  /// ImplMethodsVsClassMethods - This is main routine to warn if any method
-  /// remains unimplemented in the class or category @implementation.
-  void ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
-                                 ObjCContainerDecl* IDecl,
-                                 bool IncompleteImpl = false);
-
-  /// DiagnoseUnimplementedProperties - This routine warns on those properties
-  /// which must be implemented by this implementation.
-  void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl,
-                                       ObjCContainerDecl *CDecl,
-                                       const llvm::DenseSet<Selector>& InsMap);
-
-  /// DefaultSynthesizeProperties - This routine default synthesizes all 
-  /// properties which must be synthesized in class's @implementation.
-  void DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
-                                    ObjCInterfaceDecl *IDecl);
-  
-  /// CollectImmediateProperties - This routine collects all properties in
-  /// the class and its conforming protocols; but not those it its super class.
-  void CollectImmediateProperties(ObjCContainerDecl *CDecl,
-            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& PropMap,
-            llvm::DenseMap<IdentifierInfo *, ObjCPropertyDecl*>& SuperPropMap);
-  
-
-  /// LookupPropertyDecl - Looks up a property in the current class and all
-  /// its protocols.
-  ObjCPropertyDecl *LookupPropertyDecl(const ObjCContainerDecl *CDecl,
-                                       IdentifierInfo *II);
-
-  /// Called by ActOnProperty to handle @property declarations in
-  ////  class extensions.
-  DeclPtrTy HandlePropertyInClassExtension(Scope *S,
-                                           ObjCCategoryDecl *CDecl,
-                                           SourceLocation AtLoc,
-                                           FieldDeclarator &FD,
-                                           Selector GetterSel,
-                                           Selector SetterSel,
-                                           const bool isAssign,
-                                           const bool isReadWrite,
-                                           const unsigned Attributes,
-                                           bool *isOverridingProperty,
-                                           TypeSourceInfo *T,
-                                           tok::ObjCKeywordKind MethodImplKind);
-
-  /// Called by ActOnProperty and HandlePropertyInClassExtension to
-  ///  handle creating the ObjcPropertyDecl for a category or @interface.
-  ObjCPropertyDecl *CreatePropertyDecl(Scope *S,
-                                       ObjCContainerDecl *CDecl,
-                                       SourceLocation AtLoc,
-                                       FieldDeclarator &FD,
-                                       Selector GetterSel,
-                                       Selector SetterSel,
-                                       const bool isAssign,
-                                       const bool isReadWrite,
-                                       const unsigned Attributes,
-                                       TypeSourceInfo *T,
-                                       tok::ObjCKeywordKind MethodImplKind,
-                                       DeclContext *lexicalDC = 0);
-
-  /// AtomicPropertySetterGetterRules - This routine enforces the rule (via
-  /// warning) when atomic property has one but not the other user-declared
-  /// setter or getter.
-  void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
-                                       ObjCContainerDecl* IDecl);
-
-  void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
-
-  /// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
-  /// true, or false, accordingly.
-  bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
-                                  const ObjCMethodDecl *PrevMethod,
-                                  bool matchBasedOnSizeAndAlignment = false);
-
-  /// MatchAllMethodDeclarations - Check methods declaraed in interface or
-  /// or protocol against those declared in their implementations.
-  void MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
-                                  const llvm::DenseSet<Selector> &ClsMap,
-                                  llvm::DenseSet<Selector> &InsMapSeen,
-                                  llvm::DenseSet<Selector> &ClsMapSeen,
-                                  ObjCImplDecl* IMPDecl,
-                                  ObjCContainerDecl* IDecl,
-                                  bool &IncompleteImpl,
-                                  bool ImmediateClass);
-
-  /// AddInstanceMethodToGlobalPool - All instance methods in a translation
-  /// unit are added to a global pool. This allows us to efficiently associate
-  /// a selector with a method declaraation for purposes of typechecking
-  /// messages sent to "id" (where the class of the object is unknown).
-  void AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method);
-
-  /// LookupInstanceMethodInGlobalPool - Returns the method and warns if
-  /// there are multiple signatures.
-  ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R,
-                                                   bool warn=true);
-
-  /// LookupFactoryMethodInGlobalPool - Returns the method and warns if
-  /// there are multiple signatures.
-  ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R);
-
-  /// AddFactoryMethodToGlobalPool - Same as above, but for factory methods.
-  void AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method);
-
-  /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
-  /// initialization.
-  void CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
-                                  llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
-  //===--------------------------------------------------------------------===//
-  // Statement Parsing Callbacks: SemaStmt.cpp.
-public:
-  virtual OwningStmtResult ActOnExprStmt(FullExprArg Expr);
-
-  virtual OwningStmtResult ActOnNullStmt(SourceLocation SemiLoc);
-  virtual OwningStmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
-                                             MultiStmtArg Elts,
-                                             bool isStmtExpr);
-  virtual OwningStmtResult ActOnDeclStmt(DeclGroupPtrTy Decl,
-                                         SourceLocation StartLoc,
-                                         SourceLocation EndLoc);
-  virtual void ActOnForEachDeclStmt(DeclGroupPtrTy Decl);
-  virtual OwningStmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprArg LHSVal,
-                                    SourceLocation DotDotDotLoc, ExprArg RHSVal,
-                                    SourceLocation ColonLoc);
-  virtual void ActOnCaseStmtBody(StmtTy *CaseStmt, StmtArg SubStmt);
-
-  virtual OwningStmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
-                                            SourceLocation ColonLoc,
-                                            StmtArg SubStmt, Scope *CurScope);
-  virtual OwningStmtResult ActOnLabelStmt(SourceLocation IdentLoc,
-                                          IdentifierInfo *II,
-                                          SourceLocation ColonLoc,
-                                          StmtArg SubStmt);
-  virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc,
-                                       FullExprArg CondVal, DeclPtrTy CondVar,
-                                       StmtArg ThenVal,
-                                       SourceLocation ElseLoc, StmtArg ElseVal);
-  virtual OwningStmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,
-                                                  ExprArg Cond,
-                                                  DeclPtrTy CondVar);
-  virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,
-                                                 StmtArg Switch, StmtArg Body);
-  virtual OwningStmtResult ActOnWhileStmt(SourceLocation WhileLoc,
-                                          FullExprArg Cond,
-                                          DeclPtrTy CondVar, StmtArg Body);
-  virtual OwningStmtResult ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
-                                       SourceLocation WhileLoc,
-                                       SourceLocation CondLParen, ExprArg Cond,
-                                       SourceLocation CondRParen);
-
-  virtual OwningStmtResult ActOnForStmt(SourceLocation ForLoc,
-                                        SourceLocation LParenLoc,
-                                        StmtArg First, FullExprArg Second,
-                                        DeclPtrTy SecondVar,
-                                        FullExprArg Third,
-                                        SourceLocation RParenLoc,
-                                        StmtArg Body);
-  virtual OwningStmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc,
-                                       SourceLocation LParenLoc,
-                                       StmtArg First, ExprArg Second,
-                                       SourceLocation RParenLoc, StmtArg Body);
-
-  virtual OwningStmtResult ActOnGotoStmt(SourceLocation GotoLoc,
-                                         SourceLocation LabelLoc,
-                                         IdentifierInfo *LabelII);
-  virtual OwningStmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
-                                                 SourceLocation StarLoc,
-                                                 ExprArg DestExp);
-  virtual OwningStmtResult ActOnContinueStmt(SourceLocation ContinueLoc,
-                                             Scope *CurScope);
-  virtual OwningStmtResult ActOnBreakStmt(SourceLocation GotoLoc,
-                                          Scope *CurScope);
-
-  virtual OwningStmtResult ActOnReturnStmt(SourceLocation ReturnLoc,
-                                           ExprArg RetValExp);
-  OwningStmtResult ActOnBlockReturnStmt(SourceLocation ReturnLoc,
-                                        Expr *RetValExp);
-
-  virtual OwningStmtResult ActOnAsmStmt(SourceLocation AsmLoc,
-                                        bool IsSimple,
-                                        bool IsVolatile,
-                                        unsigned NumOutputs,
-                                        unsigned NumInputs,
-                                        IdentifierInfo **Names,
-                                        MultiExprArg Constraints,
-                                        MultiExprArg Exprs,
-                                        ExprArg AsmString,
-                                        MultiExprArg Clobbers,
-                                        SourceLocation RParenLoc,
-                                        bool MSAsm = false);
-
-
-  VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
-                                  IdentifierInfo *Name, SourceLocation NameLoc,
-                                  bool Invalid = false);
-
-  virtual DeclPtrTy ActOnObjCExceptionDecl(Scope *S, Declarator &D);
-
-  virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
-                                                SourceLocation RParen,
-                                                DeclPtrTy Parm, StmtArg Body);
-
-  virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
-                                                  StmtArg Body);
-
-  virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
-                                              StmtArg Try,
-                                              MultiStmtArg Catch,
-                                              StmtArg Finally);
-
-  virtual OwningStmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc,
-                                                ExprArg Throw);
-  virtual OwningStmtResult ActOnObjCAtThrowStmt(SourceLocation AtLoc,
-                                                ExprArg Throw,
-                                                Scope *CurScope);
-  virtual OwningStmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc,
-                                                       ExprArg SynchExpr,
-                                                       StmtArg SynchBody);
-
-  VarDecl *BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
-                                     TypeSourceInfo *TInfo,
-                                     IdentifierInfo *Name,
-                                     SourceLocation Loc,
-                                     SourceRange Range);
-  virtual DeclPtrTy ActOnExceptionDeclarator(Scope *S, Declarator &D);
-
-  virtual OwningStmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc,
-                                              DeclPtrTy ExDecl,
-                                              StmtArg HandlerBlock);
-  virtual OwningStmtResult ActOnCXXTryBlock(SourceLocation TryLoc,
-                                            StmtArg TryBlock,
-                                            MultiStmtArg Handlers);
-  void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock);
-
-  /// DiagnoseUnusedExprResult - If the statement passed in is an expression
-  /// whose result is unused, warn.
-  void DiagnoseUnusedExprResult(const Stmt *S);
-  void DiagnoseUnusedDecl(const NamedDecl *ND);
-  
-  ParsingDeclStackState PushParsingDeclaration();
-  void PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy D);
-  void EmitDeprecationWarning(NamedDecl *D, SourceLocation Loc);
-
-  void HandleDelayedDeprecationCheck(DelayedDiagnostic &DD, Decl *Ctx);
-
-  //===--------------------------------------------------------------------===//
-  // Expression Parsing Callbacks: SemaExpr.cpp.
-
-  bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc);
-  bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
-                                        ObjCMethodDecl *Getter,
-                                        SourceLocation Loc);
-  void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
-                             Expr **Args, unsigned NumArgs);
-
-  virtual void
-  PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
-
-  virtual void PopExpressionEvaluationContext();
-
-  void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
-  void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
-  bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
-
-  // Primary Expressions.
-  virtual SourceRange getExprRange(ExprTy *E) const;
-
-  virtual OwningExprResult ActOnIdExpression(Scope *S,
-                                             CXXScopeSpec &SS,
-                                             UnqualifiedId &Name,
-                                             bool HasTrailingLParen,
-                                             bool IsAddressOfOperand);
-
-  bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
-                           CorrectTypoContext CTC = CTC_Unknown);
-
-  OwningExprResult LookupInObjCMethod(LookupResult &R,
-                                      Scope *S,
-                                      IdentifierInfo *II,
-                                      bool AllowBuiltinCreation=false);
-
-  OwningExprResult ActOnDependentIdExpression(const CXXScopeSpec &SS,
-                                              DeclarationName Name,
-                                              SourceLocation NameLoc,
-                                              bool isAddressOfOperand,
-                                const TemplateArgumentListInfo *TemplateArgs);
-
-  OwningExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty,
-                                    SourceLocation Loc,
-                                    const CXXScopeSpec *SS = 0);
-  VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
-                                    llvm::SmallVectorImpl<FieldDecl *> &Path);
-  OwningExprResult
-  BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
-                                           FieldDecl *Field,
-                                           Expr *BaseObjectExpr = 0,
-                                      SourceLocation OpLoc = SourceLocation());
-  OwningExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
-                                                   LookupResult &R,
-                                const TemplateArgumentListInfo *TemplateArgs);
-  OwningExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS,
-                                           LookupResult &R,
-                                const TemplateArgumentListInfo *TemplateArgs,
-                                           bool IsDefiniteInstance);
-  bool UseArgumentDependentLookup(const CXXScopeSpec &SS,
-                                  const LookupResult &R,
-                                  bool HasTrailingLParen);
-
-  OwningExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                                     DeclarationName Name,
-                                                     SourceLocation NameLoc);
-  OwningExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
-                                             DeclarationName Name,
-                                             SourceLocation NameLoc,
-                                const TemplateArgumentListInfo *TemplateArgs);
-
-  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                                            LookupResult &R,
-                                            bool ADL);
-  OwningExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                                            SourceLocation Loc,
-                                            NamedDecl *D);
-
-  virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
-                                               tok::TokenKind Kind);
-  virtual OwningExprResult ActOnNumericConstant(const Token &);
-  virtual OwningExprResult ActOnCharacterConstant(const Token &);
-  virtual OwningExprResult ActOnParenExpr(SourceLocation L, SourceLocation R,
-                                          ExprArg Val);
-  virtual OwningExprResult ActOnParenOrParenListExpr(SourceLocation L,
-                                              SourceLocation R,
-                                              MultiExprArg Val,
-                                              TypeTy *TypeOfCast=0);
-
-  /// ActOnStringLiteral - The specified tokens were lexed as pasted string
-  /// fragments (e.g. "foo" "bar" L"baz").
-  virtual OwningExprResult ActOnStringLiteral(const Token *Toks,
-                                              unsigned NumToks);
-
-  // Binary/Unary Operators.  'Tok' is the token for the operator.
-  OwningExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc,
-                                        unsigned OpcIn,
-                                        ExprArg InputArg);
-  OwningExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
-                                UnaryOperator::Opcode Opc, ExprArg input);
-  virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
-                                        tok::TokenKind Op, ExprArg Input);
-
-  OwningExprResult CreateSizeOfAlignOfExpr(TypeSourceInfo *T,
-                                           SourceLocation OpLoc,
-                                           bool isSizeOf, SourceRange R);
-  OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
-                                           bool isSizeOf, SourceRange R);
-  virtual OwningExprResult
-    ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
-                           void *TyOrEx, const SourceRange &ArgRange);
-
-  bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R);
-  bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc,
-                                 const SourceRange &R, bool isSizeof);
-
-  virtual OwningExprResult ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
-                                               tok::TokenKind Kind,
-                                               ExprArg Input);
-
-  virtual OwningExprResult ActOnArraySubscriptExpr(Scope *S, ExprArg Base,
-                                                   SourceLocation LLoc,
-                                                   ExprArg Idx,
-                                                   SourceLocation RLoc);
-  OwningExprResult CreateBuiltinArraySubscriptExpr(ExprArg Base,
-                                                   SourceLocation LLoc,
-                                                   ExprArg Idx,
-                                                   SourceLocation RLoc);
-
-  OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
-                                            QualType BaseType,
-                                            SourceLocation OpLoc,
-                                            bool IsArrow,
-                                            CXXScopeSpec &SS,
-                                            NamedDecl *FirstQualifierInScope,
-                                            DeclarationName Name,
-                                            SourceLocation NameLoc,
-                                const TemplateArgumentListInfo *TemplateArgs);
-
-  OwningExprResult BuildMemberReferenceExpr(ExprArg Base,
-                                            QualType BaseType,
-                                            SourceLocation OpLoc, bool IsArrow,
-                                            const CXXScopeSpec &SS,
-                                            NamedDecl *FirstQualifierInScope,
-                                            LookupResult &R,
-                                 const TemplateArgumentListInfo *TemplateArgs,
-                                          bool SuppressQualifierCheck = false);
-
-  OwningExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
-                                    bool &IsArrow, SourceLocation OpLoc,
-                                    CXXScopeSpec &SS,
-                                    DeclPtrTy ObjCImpDecl,
-                                    bool HasTemplateArgs);
-
-  bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
-                                     const CXXScopeSpec &SS,
-                                     const LookupResult &R);
-
-  OwningExprResult ActOnDependentMemberExpr(ExprArg Base,
-                                            QualType BaseType,
-                                            bool IsArrow,
-                                            SourceLocation OpLoc,
-                                            const CXXScopeSpec &SS,
-                                            NamedDecl *FirstQualifierInScope,
-                                            DeclarationName Name,
-                                            SourceLocation NameLoc,
-                               const TemplateArgumentListInfo *TemplateArgs);
-
-  virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
-                                                 SourceLocation OpLoc,
-                                                 tok::TokenKind OpKind,
-                                                 CXXScopeSpec &SS,
-                                                 UnqualifiedId &Member,
-                                                 DeclPtrTy ObjCImpDecl,
-                                                 bool HasTrailingLParen);
-
-  virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
-  bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
-                               FunctionDecl *FDecl,
-                               const FunctionProtoType *Proto,
-                               Expr **Args, unsigned NumArgs,
-                               SourceLocation RParenLoc);
-
-  /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
-  /// This provides the location of the left/right parens and a list of comma
-  /// locations.
-  virtual OwningExprResult ActOnCallExpr(Scope *S, ExprArg Fn,
-                                         SourceLocation LParenLoc,
-                                         MultiExprArg Args,
-                                         SourceLocation *CommaLocs,
-                                         SourceLocation RParenLoc);
-  OwningExprResult BuildResolvedCallExpr(Expr *Fn,
-                                         NamedDecl *NDecl,
-                                         SourceLocation LParenLoc,
-                                         Expr **Args, unsigned NumArgs,
-                                         SourceLocation RParenLoc);
-
-  virtual OwningExprResult ActOnCastExpr(Scope *S, SourceLocation LParenLoc,
-                                         TypeTy *Ty, SourceLocation RParenLoc,
-                                         ExprArg Op);
-  OwningExprResult BuildCStyleCastExpr(SourceLocation LParenLoc,
-                                       TypeSourceInfo *Ty,
-                                       SourceLocation RParenLoc,
-                                       ExprArg Op);
-
-  virtual bool TypeIsVectorType(TypeTy *Ty) {
-    return GetTypeFromParser(Ty)->isVectorType();
-  }
-
-  OwningExprResult MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg ME);
-  OwningExprResult ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
-                                            SourceLocation RParenLoc, ExprArg E,
-                                            TypeSourceInfo *TInfo);
-
-  virtual OwningExprResult ActOnCompoundLiteral(SourceLocation LParenLoc,
-                                                TypeTy *Ty,
-                                                SourceLocation RParenLoc,
-                                                ExprArg Op);
-
-  OwningExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc,
-                                            TypeSourceInfo *TInfo,
-                                            SourceLocation RParenLoc,
-                                            ExprArg InitExpr);
-
-  virtual OwningExprResult ActOnInitList(SourceLocation LParenLoc,
-                                         MultiExprArg InitList,
-                                         SourceLocation RParenLoc);
-
-  virtual OwningExprResult ActOnDesignatedInitializer(Designation &Desig,
-                                                      SourceLocation Loc,
-                                                      bool GNUSyntax,
-                                                      OwningExprResult Init);
-
-  virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
-                                      tok::TokenKind Kind,
-                                      ExprArg LHS, ExprArg RHS);
-  OwningExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
-                              BinaryOperator::Opcode Opc,
-                              Expr *lhs, Expr *rhs);
-  OwningExprResult CreateBuiltinBinOp(SourceLocation TokLoc,
-                                      unsigned Opc, Expr *lhs, Expr *rhs);
-
-  /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
-  /// in the case of a the GNU conditional expr extension.
-  virtual OwningExprResult ActOnConditionalOp(SourceLocation QuestionLoc,
-                                              SourceLocation ColonLoc,
-                                              ExprArg Cond, ExprArg LHS,
-                                              ExprArg RHS);
-
-  /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-  virtual OwningExprResult ActOnAddrLabel(SourceLocation OpLoc,
-                                          SourceLocation LabLoc,
-                                          IdentifierInfo *LabelII);
-
-  virtual OwningExprResult ActOnStmtExpr(SourceLocation LPLoc, StmtArg SubStmt,
-                                         SourceLocation RPLoc); // "({..})"
-
-  /// __builtin_offsetof(type, a.b[123][456].c)
-  OwningExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
-                                        TypeSourceInfo *TInfo,
-                                        OffsetOfComponent *CompPtr,
-                                        unsigned NumComponents,
-                                        SourceLocation RParenLoc);
-  virtual OwningExprResult ActOnBuiltinOffsetOf(Scope *S,
-                                                SourceLocation BuiltinLoc,
-                                                SourceLocation TypeLoc,
-                                                TypeTy *Arg1,
-                                                OffsetOfComponent *CompPtr,
-                                                unsigned NumComponents,
-                                                SourceLocation RParenLoc);
-
-  // __builtin_types_compatible_p(type1, type2)
-  virtual OwningExprResult ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
-                                                    TypeTy *arg1, TypeTy *arg2,
-                                                    SourceLocation RPLoc);
-
-  // __builtin_choose_expr(constExpr, expr1, expr2)
-  virtual OwningExprResult ActOnChooseExpr(SourceLocation BuiltinLoc,
-                                           ExprArg cond, ExprArg expr1,
-                                           ExprArg expr2, SourceLocation RPLoc);
-
-  // __builtin_va_arg(expr, type)
-  virtual OwningExprResult ActOnVAArg(SourceLocation BuiltinLoc,
-                                      ExprArg expr, TypeTy *type,
-                                      SourceLocation RPLoc);
-
-  // __null
-  virtual OwningExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
-
-  //===------------------------- "Block" Extension ------------------------===//
-
-  /// ActOnBlockStart - This callback is invoked when a block literal is
-  /// started.
-  virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope);
-
-  /// ActOnBlockArguments - This callback allows processing of block arguments.
-  /// If there are no arguments, this is still invoked.
-  virtual void ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope);
-
-  /// ActOnBlockError - If there is an error parsing a block, this callback
-  /// is invoked to pop the information about the block from the action impl.
-  virtual void ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope);
-
-  /// ActOnBlockStmtExpr - This is called when the body of a block statement
-  /// literal was successfully completed.  ^(int x){...}
-  virtual OwningExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc,
-                                              StmtArg Body, Scope *CurScope);
-
-  //===---------------------------- C++ Features --------------------------===//
-
-  // Act on C++ namespaces
-  virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
-                                           IdentifierInfo *Ident,
-                                           SourceLocation LBrace,
-                                           AttributeList *AttrList);
-  virtual void ActOnFinishNamespaceDef(DeclPtrTy Dcl, SourceLocation RBrace);
-
-  NamespaceDecl *getStdNamespace();
-  virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
-                                        SourceLocation UsingLoc,
-                                        SourceLocation NamespcLoc,
-                                        CXXScopeSpec &SS,
-                                        SourceLocation IdentLoc,
-                                        IdentifierInfo *NamespcName,
-                                        AttributeList *AttrList);
-
-  void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir);
-
-  virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
-                                           SourceLocation NamespaceLoc,
-                                           SourceLocation AliasLoc,
-                                           IdentifierInfo *Alias,
-                                           CXXScopeSpec &SS,
-                                           SourceLocation IdentLoc,
-                                           IdentifierInfo *Ident);
-
-  void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow);
-  bool CheckUsingShadowDecl(UsingDecl *UD, NamedDecl *Target,
-                            const LookupResult &PreviousDecls);
-  UsingShadowDecl *BuildUsingShadowDecl(Scope *S, UsingDecl *UD,
-                                        NamedDecl *Target);
-
-  bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
-                                   bool isTypeName,
-                                   const CXXScopeSpec &SS,
-                                   SourceLocation NameLoc,
-                                   const LookupResult &Previous);
-  bool CheckUsingDeclQualifier(SourceLocation UsingLoc,
-                               const CXXScopeSpec &SS,
-                               SourceLocation NameLoc);
-
-  NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
-                                   SourceLocation UsingLoc,
-                                   CXXScopeSpec &SS,
-                                   SourceLocation IdentLoc,
-                                   DeclarationName Name,
-                                   AttributeList *AttrList,
-                                   bool IsInstantiation,
-                                   bool IsTypeName,
-                                   SourceLocation TypenameLoc);
-
-  virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
-                                          AccessSpecifier AS,
-                                          bool HasUsingKeyword,
-                                          SourceLocation UsingLoc,
-                                          CXXScopeSpec &SS,
-                                          UnqualifiedId &Name,
-                                          AttributeList *AttrList,
-                                          bool IsTypeName,
-                                          SourceLocation TypenameLoc);
-
-  /// AddCXXDirectInitializerToDecl - This action is called immediately after
-  /// ActOnDeclarator, when a C++ direct initializer is present.
-  /// e.g: "int x(1);"
-  virtual void AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
-                                             SourceLocation LParenLoc,
-                                             MultiExprArg Exprs,
-                                             SourceLocation *CommaLocs,
-                                             SourceLocation RParenLoc);
-
-  /// InitializeVarWithConstructor - Creates an CXXConstructExpr
-  /// and sets it as the initializer for the the passed in VarDecl.
-  bool InitializeVarWithConstructor(VarDecl *VD,
-                                    CXXConstructorDecl *Constructor,
-                                    MultiExprArg Exprs);
-
-  /// BuildCXXConstructExpr - Creates a complete call to a constructor,
-  /// including handling of its default argument expressions.
-  OwningExprResult
-  BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
-                        CXXConstructorDecl *Constructor, MultiExprArg Exprs,
-                        bool RequiresZeroInit = false,
-                        CXXConstructExpr::ConstructionKind ConstructKind =
-                        CXXConstructExpr::CK_Complete);
-
-  // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
-  // the constructor can be elidable?
-  OwningExprResult
-  BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
-                        CXXConstructorDecl *Constructor, bool Elidable,
-                        MultiExprArg Exprs, bool RequiresZeroInit = false,
-                        CXXConstructExpr::ConstructionKind ConstructKind =
-                        CXXConstructExpr::CK_Complete);
-
-  /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
-  /// the default expr if needed.
-  OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,
-                                          FunctionDecl *FD,
-                                          ParmVarDecl *Param);
-
-  /// FinalizeVarWithDestructor - Prepare for calling destructor on the
-  /// constructed variable.
-  void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType);
-
-  /// \brief Declare the implicit default constructor for the given class.
-  ///
-  /// \param ClassDecl The class declaration into which the implicit 
-  /// default constructor will be added.
-  ///
-  /// \returns The implicitly-declared default constructor.
-  CXXConstructorDecl *DeclareImplicitDefaultConstructor(
-                                                     CXXRecordDecl *ClassDecl);
-  
-  /// DefineImplicitDefaultConstructor - Checks for feasibility of
-  /// defining this constructor as the default constructor.
-  void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
-                                        CXXConstructorDecl *Constructor);
-
-  /// \brief Declare the implicit destructor for the given class.
-  ///
-  /// \param ClassDecl The class declaration into which the implicit 
-  /// destructor will be added.
-  ///
-  /// \returns The implicitly-declared destructor.
-  CXXDestructorDecl *DeclareImplicitDestructor(CXXRecordDecl *ClassDecl);
-                                               
-  /// DefineImplicitDestructor - Checks for feasibility of
-  /// defining this destructor as the default destructor.
-  void DefineImplicitDestructor(SourceLocation CurrentLocation,
-                                CXXDestructorDecl *Destructor);
-
-  /// \brief Declare the implicit copy constructor for the given class.
-  ///
-  /// \param S The scope of the class, which may be NULL if this is a 
-  /// template instantiation.
-  ///
-  /// \param ClassDecl The class declaration into which the implicit 
-  /// copy constructor will be added.
-  ///
-  /// \returns The implicitly-declared copy constructor.
-  CXXConstructorDecl *DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl);
-                                                     
-  /// DefineImplicitCopyConstructor - Checks for feasibility of
-  /// defining this constructor as the copy constructor.
-  void DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
-                                     CXXConstructorDecl *Constructor,
-                                     unsigned TypeQuals);
-
-  /// \brief Declare the implicit copy assignment operator for the given class.
-  ///
-  /// \param S The scope of the class, which may be NULL if this is a 
-  /// template instantiation.
-  ///
-  /// \param ClassDecl The class declaration into which the implicit 
-  /// copy-assignment operator will be added.
-  ///
-  /// \returns The implicitly-declared copy assignment operator.
-  CXXMethodDecl *DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl);
-  
-  /// \brief Defined an implicitly-declared copy assignment operator.
-  void DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
-                                    CXXMethodDecl *MethodDecl);
-
-  /// \brief Force the declaration of any implicitly-declared members of this
-  /// class.
-  void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class);
-  
-  /// MaybeBindToTemporary - If the passed in expression has a record type with
-  /// a non-trivial destructor, this will return CXXBindTemporaryExpr. Otherwise
-  /// it simply returns the passed in expression.
-  OwningExprResult MaybeBindToTemporary(Expr *E);
-
-  bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
-                               MultiExprArg ArgsPtr,
-                               SourceLocation Loc,
-                      ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
-
-  virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
-                                    IdentifierInfo &II, SourceLocation NameLoc,
-                                    Scope *S, CXXScopeSpec &SS,
-                                    TypeTy *ObjectType,
-                                    bool EnteringContext);
-
-  /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
-  virtual OwningExprResult ActOnCXXNamedCast(SourceLocation OpLoc,
-                                             tok::TokenKind Kind,
-                                             SourceLocation LAngleBracketLoc,
-                                             TypeTy *Ty,
-                                             SourceLocation RAngleBracketLoc,
-                                             SourceLocation LParenLoc,
-                                             ExprArg E,
-                                             SourceLocation RParenLoc);
-
-  OwningExprResult BuildCXXNamedCast(SourceLocation OpLoc,
-                                     tok::TokenKind Kind,
-                                     TypeSourceInfo *Ty,
-                                     ExprArg E,
-                                     SourceRange AngleBrackets,
-                                     SourceRange Parens);
-
-  OwningExprResult BuildCXXTypeId(QualType TypeInfoType,
-                                  SourceLocation TypeidLoc,
-                                  TypeSourceInfo *Operand,
-                                  SourceLocation RParenLoc);
-  OwningExprResult BuildCXXTypeId(QualType TypeInfoType,
-                                  SourceLocation TypeidLoc,
-                                  ExprArg Operand,
-                                  SourceLocation RParenLoc);
-
-  /// ActOnCXXTypeid - Parse typeid( something ).
-  virtual OwningExprResult ActOnCXXTypeid(SourceLocation OpLoc,
-                                          SourceLocation LParenLoc, bool isType,
-                                          void *TyOrExpr,
-                                          SourceLocation RParenLoc);
-
-  //// ActOnCXXThis -  Parse 'this' pointer.
-  virtual OwningExprResult ActOnCXXThis(SourceLocation ThisLoc);
-
-  /// ActOnCXXBoolLiteral - Parse {true,false} literals.
-  virtual OwningExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc,
-                                               tok::TokenKind Kind);
-
-  /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
-  virtual OwningExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc);
-
-  //// ActOnCXXThrow -  Parse throw expressions.
-  virtual OwningExprResult ActOnCXXThrow(SourceLocation OpLoc,
-                                         ExprArg expr);
-  bool CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E);
-
-  /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.
-  /// Can be interpreted either as function-style casting ("int(x)")
-  /// or class type construction ("ClassType(x,y,z)")
-  /// or creation of a value-initialized type ("int()").
-  virtual OwningExprResult ActOnCXXTypeConstructExpr(SourceRange TypeRange,
-                                                     TypeTy *TypeRep,
-                                                     SourceLocation LParenLoc,
-                                                     MultiExprArg Exprs,
-                                                     SourceLocation *CommaLocs,
-                                                     SourceLocation RParenLoc);
-
-  /// ActOnCXXNew - Parsed a C++ 'new' expression.
-  virtual OwningExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
-                                       SourceLocation PlacementLParen,
-                                       MultiExprArg PlacementArgs,
-                                       SourceLocation PlacementRParen,
-                                       SourceRange TypeIdParens, Declarator &D,
-                                       SourceLocation ConstructorLParen,
-                                       MultiExprArg ConstructorArgs,
-                                       SourceLocation ConstructorRParen);
-  OwningExprResult BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
-                               SourceLocation PlacementLParen,
-                               MultiExprArg PlacementArgs,
-                               SourceLocation PlacementRParen,
-                               SourceRange TypeIdParens,
-                               QualType AllocType,
-                               SourceLocation TypeLoc,
-                               SourceRange TypeRange,
-                               ExprArg ArraySize,
-                               SourceLocation ConstructorLParen,
-                               MultiExprArg ConstructorArgs,
-                               SourceLocation ConstructorRParen);
-
-  bool CheckAllocatedType(QualType AllocType, SourceLocation Loc,
-                          SourceRange R);
-  bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
-                               bool UseGlobal, QualType AllocType, bool IsArray,
-                               Expr **PlaceArgs, unsigned NumPlaceArgs,
-                               FunctionDecl *&OperatorNew,
-                               FunctionDecl *&OperatorDelete);
-  bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
-                              DeclarationName Name, Expr** Args,
-                              unsigned NumArgs, DeclContext *Ctx,
-                              bool AllowMissing, FunctionDecl *&Operator);
-  void DeclareGlobalNewDelete();
-  void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return,
-                                       QualType Argument,
-                                       bool addMallocAttr = false);
-
-  bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
-                                DeclarationName Name, FunctionDecl* &Operator);
-
-  /// ActOnCXXDelete - Parsed a C++ 'delete' expression
-  virtual OwningExprResult ActOnCXXDelete(SourceLocation StartLoc,
-                                          bool UseGlobal, bool ArrayForm,
-                                          ExprArg Operand);
-
-  virtual DeclResult ActOnCXXConditionDeclaration(Scope *S,
-                                                  Declarator &D);
-  OwningExprResult CheckConditionVariable(VarDecl *ConditionVar,
-                                          SourceLocation StmtLoc,
-                                          bool ConvertToBoolean);
-
-  /// ActOnUnaryTypeTrait - Parsed one of the unary type trait support
-  /// pseudo-functions.
-  virtual OwningExprResult ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
-                                               SourceLocation KWLoc,
-                                               SourceLocation LParen,
-                                               TypeTy *Ty,
-                                               SourceLocation RParen);
-
-  virtual OwningExprResult ActOnStartCXXMemberReference(Scope *S,
-                                                        ExprArg Base,
-                                                        SourceLocation OpLoc,
-                                                        tok::TokenKind OpKind,
-                                                        TypeTy *&ObjectType,
-                                                   bool &MayBePseudoDestructor);
-
-  OwningExprResult DiagnoseDtorReference(SourceLocation NameLoc,
-                                         ExprArg MemExpr);
-
-  OwningExprResult BuildPseudoDestructorExpr(ExprArg Base,
-                                             SourceLocation OpLoc,
-                                             tok::TokenKind OpKind,
-                                             const CXXScopeSpec &SS,
-                                             TypeSourceInfo *ScopeType,
-                                             SourceLocation CCLoc,
-                                             SourceLocation TildeLoc,
-                                     PseudoDestructorTypeStorage DestroyedType,
-                                             bool HasTrailingLParen);
-
-  virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
-                                                     SourceLocation OpLoc,
-                                                     tok::TokenKind OpKind,
-                                                     CXXScopeSpec &SS,
-                                                   UnqualifiedId &FirstTypeName,
-                                                     SourceLocation CCLoc,
-                                                     SourceLocation TildeLoc,
-                                                  UnqualifiedId &SecondTypeName,
-                                                     bool HasTrailingLParen);
-
-  /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
-  /// non-empty, will create a new CXXExprWithTemporaries expression.
-  /// Otherwise, just returs the passed in expression.
-  Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr);
-  OwningExprResult MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr);
-  FullExpr CreateFullExpr(Expr *SubExpr);
-
-  virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr);
-
-  // Marks SS invalid if it represents an incomplete type.
-  bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC);
-
-  DeclContext *computeDeclContext(QualType T);
-  DeclContext *computeDeclContext(const CXXScopeSpec &SS,
-                                  bool EnteringContext = false);
-  bool isDependentScopeSpecifier(const CXXScopeSpec &SS);
-  CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
-  bool isUnknownSpecialization(const CXXScopeSpec &SS);
-
-  /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
-  /// global scope ('::').
-  virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S,
-                                                   SourceLocation CCLoc);
-
-  bool isAcceptableNestedNameSpecifier(NamedDecl *SD);
-  NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
-
-  virtual bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
-                                            SourceLocation IdLoc,
-                                            IdentifierInfo &II,
-                                            TypeTy *ObjectType);
-
-  CXXScopeTy *BuildCXXNestedNameSpecifier(Scope *S,
-                                          CXXScopeSpec &SS,
-                                          SourceLocation IdLoc,
-                                          SourceLocation CCLoc,
-                                          IdentifierInfo &II,
-                                          QualType ObjectType,
-                                          NamedDecl *ScopeLookupResult,
-                                          bool EnteringContext,
-                                          bool ErrorRecoveryLookup);
-
-  virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
-                                                  CXXScopeSpec &SS,
-                                                  SourceLocation IdLoc,
-                                                  SourceLocation CCLoc,
-                                                  IdentifierInfo &II,
-                                                  TypeTy *ObjectType,
-                                                  bool EnteringContext);
-
-  virtual bool IsInvalidUnlessNestedName(Scope *S,
-                                         CXXScopeSpec &SS,
-                                         IdentifierInfo &II,
-                                         TypeTy *ObjectType,
-                                         bool EnteringContext);
-
-  /// ActOnCXXNestedNameSpecifier - Called during parsing of a
-  /// nested-name-specifier that involves a template-id, e.g.,
-  /// "foo::bar<int, float>::", and now we need to build a scope
-  /// specifier. \p SS is empty or the previously parsed nested-name
-  /// part ("foo::"), \p Type is the already-parsed class template
-  /// specialization (or other template-id that names a type), \p
-  /// TypeRange is the source range where the type is located, and \p
-  /// CCLoc is the location of the trailing '::'.
-  virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
-                                                  const CXXScopeSpec &SS,
-                                                  TypeTy *Type,
-                                                  SourceRange TypeRange,
-                                                  SourceLocation CCLoc);
-
-  virtual bool ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
-
-  /// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global
-  /// scope or nested-name-specifier) is parsed, part of a declarator-id.
-  /// After this method is called, according to [C++ 3.4.3p3], names should be
-  /// looked up in the declarator-id's scope, until the declarator is parsed and
-  /// ActOnCXXExitDeclaratorScope is called.
-  /// The 'SS' should be a non-empty valid CXXScopeSpec.
-  virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS);
-
-  /// ActOnCXXExitDeclaratorScope - Called when a declarator that previously
-  /// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same
-  /// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well.
-  /// Used to indicate that names should revert to being looked up in the
-  /// defining scope.
-  virtual void ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS);
-
-  /// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an
-  /// initializer for the declaration 'Dcl'.
-  /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
-  /// static data member of class X, names should be looked up in the scope of
-  /// class X.
-  virtual void ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl);
-
-  /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
-  /// initializer for the declaration 'Dcl'.
-  virtual void ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl);
-
-  // ParseObjCStringLiteral - Parse Objective-C string literals.
-  virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
-                                            ExprTy **Strings,
-                                            unsigned NumStrings);
-
-  Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
-                                  TypeSourceInfo *EncodedTypeInfo,
-                                  SourceLocation RParenLoc);
-  CXXMemberCallExpr *BuildCXXMemberCallExpr(Expr *Exp,
-                                            NamedDecl *FoundDecl,
-                                            CXXMethodDecl *Method);
-
-  virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
-                                               SourceLocation EncodeLoc,
-                                               SourceLocation LParenLoc,
-                                               TypeTy *Ty,
-                                               SourceLocation RParenLoc);
-
-  // ParseObjCSelectorExpression - Build selector expression for @selector
-  virtual ExprResult ParseObjCSelectorExpression(Selector Sel,
-                                                 SourceLocation AtLoc,
-                                                 SourceLocation SelLoc,
-                                                 SourceLocation LParenLoc,
-                                                 SourceLocation RParenLoc);
-
-  // ParseObjCProtocolExpression - Build protocol expression for @protocol
-  virtual ExprResult ParseObjCProtocolExpression(IdentifierInfo * ProtocolName,
-                                                 SourceLocation AtLoc,
-                                                 SourceLocation ProtoLoc,
-                                                 SourceLocation LParenLoc,
-                                                 SourceLocation RParenLoc);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Declarations
-  //
-  virtual DeclPtrTy ActOnStartLinkageSpecification(Scope *S,
-                                                   SourceLocation ExternLoc,
-                                                   SourceLocation LangLoc,
-                                                   llvm::StringRef Lang,
-                                                   SourceLocation LBraceLoc);
-  virtual DeclPtrTy ActOnFinishLinkageSpecification(Scope *S,
-                                                    DeclPtrTy LinkageSpec,
-                                                    SourceLocation RBraceLoc);
-
-
-  //===--------------------------------------------------------------------===//
-  // C++ Classes
-  //
-  virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S,
-                                  const CXXScopeSpec *SS);
-
-  virtual DeclPtrTy ActOnAccessSpecifier(AccessSpecifier Access,
-                                         SourceLocation ASLoc,
-                                         SourceLocation ColonLoc);
-
-  virtual DeclPtrTy ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS,
-                                             Declarator &D,
-                                 MultiTemplateParamsArg TemplateParameterLists,
-                                             ExprTy *BitfieldWidth,
-                                             ExprTy *Init, bool IsDefinition,
-                                             bool Deleted = false);
-
-  virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
-                                            Scope *S,
-                                            CXXScopeSpec &SS,
-                                            IdentifierInfo *MemberOrBase,
-                                            TypeTy *TemplateTypeTy,
-                                            SourceLocation IdLoc,
-                                            SourceLocation LParenLoc,
-                                            ExprTy **Args, unsigned NumArgs,
-                                            SourceLocation *CommaLocs,
-                                            SourceLocation RParenLoc);
-
-  MemInitResult BuildMemberInitializer(FieldDecl *Member, Expr **Args,
-                                       unsigned NumArgs, SourceLocation IdLoc,
-                                       SourceLocation LParenLoc,
-                                       SourceLocation RParenLoc);
-
-  MemInitResult BuildBaseInitializer(QualType BaseType,
-                                     TypeSourceInfo *BaseTInfo,
-                                     Expr **Args, unsigned NumArgs,
-                                     SourceLocation LParenLoc,
-                                     SourceLocation RParenLoc,
-                                     CXXRecordDecl *ClassDecl);
-
-  bool SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
-                                   CXXBaseOrMemberInitializer **Initializers,
-                                   unsigned NumInitializers, bool AnyErrors);
-  
-  void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation);
-                           
-
-  /// MarkBaseAndMemberDestructorsReferenced - Given a record decl,
-  /// mark all the non-trivial destructors of its members and bases as
-  /// referenced.
-  void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc,
-                                              CXXRecordDecl *Record);
-
-  /// \brief The list of classes whose vtables have been used within
-  /// this translation unit, and the source locations at which the
-  /// first use occurred.
-  llvm::SmallVector<std::pair<CXXRecordDecl *, SourceLocation>, 16> 
-    VTableUses;
-
-  /// \brief The set of classes whose vtables have been used within
-  /// this translation unit, and a bit that will be true if the vtable is
-  /// required to be emitted (otherwise, it should be emitted only if needed
-  /// by code generation).
-  llvm::DenseMap<CXXRecordDecl *, bool> VTablesUsed;
-
-  /// \brief A list of all of the dynamic classes in this translation
-  /// unit.
-  llvm::SmallVector<CXXRecordDecl *, 16> DynamicClasses;
-
-  /// \brief Note that the vtable for the given class was used at the
-  /// given location.
-  void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
-                      bool DefinitionRequired = false);
-
-  /// MarkVirtualMembersReferenced - Will mark all virtual members of the given
-  /// CXXRecordDecl referenced.
-  void MarkVirtualMembersReferenced(SourceLocation Loc,
-                                    const CXXRecordDecl *RD);
-
-  /// \brief Define all of the vtables that have been used in this
-  /// translation unit and reference any virtual members used by those
-  /// vtables.
-  ///
-  /// \returns true if any work was done, false otherwise.
-  bool DefineUsedVTables();
-
-  void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl);
-
-  virtual void ActOnMemInitializers(DeclPtrTy ConstructorDecl,
-                                    SourceLocation ColonLoc,
-                                    MemInitTy **MemInits, unsigned NumMemInits,
-                                    bool AnyErrors);
-
-  void CheckCompletedCXXClass(CXXRecordDecl *Record);
-  virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
-                                                 DeclPtrTy TagDecl,
-                                                 SourceLocation LBrac,
-                                                 SourceLocation RBrac,
-                                                 AttributeList *AttrList);
-
-  virtual void ActOnReenterTemplateScope(Scope *S, DeclPtrTy Template);
-  virtual void ActOnStartDelayedMemberDeclarations(Scope *S,
-                                                   DeclPtrTy Record);
-  virtual void ActOnStartDelayedCXXMethodDeclaration(Scope *S,
-                                                     DeclPtrTy Method);
-  virtual void ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy Param);
-  virtual void ActOnFinishDelayedCXXMethodDeclaration(Scope *S,
-                                                      DeclPtrTy Method);
-  virtual void ActOnFinishDelayedMemberDeclarations(Scope *S,
-                                                    DeclPtrTy Record);
-
-  virtual DeclPtrTy ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
-                                                 ExprArg AssertExpr,
-                                                 ExprArg AssertMessageExpr);
-
-  FriendDecl *CheckFriendTypeDecl(SourceLocation FriendLoc,
-                                  TypeSourceInfo *TSInfo);
-  DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
-                                MultiTemplateParamsArg TemplateParams);
-  DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
-                                    MultiTemplateParamsArg TemplateParams);
-
-  QualType CheckConstructorDeclarator(Declarator &D, QualType R,
-                                      FunctionDecl::StorageClass& SC);
-  void CheckConstructor(CXXConstructorDecl *Constructor);
-  QualType CheckDestructorDeclarator(Declarator &D, QualType R,
-                                     FunctionDecl::StorageClass& SC);
-  bool CheckDestructor(CXXDestructorDecl *Destructor);
-  void CheckConversionDeclarator(Declarator &D, QualType &R,
-                                 FunctionDecl::StorageClass& SC);
-  DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Derived Classes
-  //
-
-  /// ActOnBaseSpecifier - Parsed a base specifier
-  CXXBaseSpecifier *CheckBaseSpecifier(CXXRecordDecl *Class,
-                                       SourceRange SpecifierRange,
-                                       bool Virtual, AccessSpecifier Access,
-                                       QualType BaseType,
-                                       SourceLocation BaseLoc);
-
-  /// SetClassDeclAttributesFromBase - Copies class decl traits
-  /// (such as whether the class has a trivial constructor,
-  /// trivial destructor etc) from the given base class.
-  void SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
-                                      const CXXRecordDecl *BaseClass,
-                                      bool BaseIsVirtual);
-
-  virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl,
-                                        SourceRange SpecifierRange,
-                                        bool Virtual, AccessSpecifier Access,
-                                        TypeTy *basetype, SourceLocation
-                                        BaseLoc);
-
-  bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
-                            unsigned NumBases);
-  virtual void ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
-                                   unsigned NumBases);
-
-  bool IsDerivedFrom(QualType Derived, QualType Base);
-  bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths);
-
-  // FIXME: I don't like this name.
-  void BuildBasePathArray(const CXXBasePaths &Paths,
-                          CXXBaseSpecifierArray &BasePath);
-
-  bool BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath);
-
-  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
-                                    SourceLocation Loc, SourceRange Range,
-                                    CXXBaseSpecifierArray *BasePath = 0,
-                                    bool IgnoreAccess = false);
-  bool CheckDerivedToBaseConversion(QualType Derived, QualType Base,
-                                    unsigned InaccessibleBaseID,
-                                    unsigned AmbigiousBaseConvID,
-                                    SourceLocation Loc, SourceRange Range,
-                                    DeclarationName Name,
-                                    CXXBaseSpecifierArray *BasePath);
-
-  std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths);
-
-  /// CheckOverridingFunctionReturnType - Checks whether the return types are
-  /// covariant, according to C++ [class.virtual]p5.
-  bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
-                                         const CXXMethodDecl *Old);
-
-  /// CheckOverridingFunctionExceptionSpec - Checks whether the exception
-  /// spec is a subset of base spec.
-  bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
-                                            const CXXMethodDecl *Old);
-
-  /// CheckOverridingFunctionAttributes - Checks whether attributes are
-  /// incompatible or prevent overriding.
-  bool CheckOverridingFunctionAttributes(const CXXMethodDecl *New,
-                                         const CXXMethodDecl *Old);
-
-  bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Access Control
-  //
-
-  enum AccessResult {
-    AR_accessible,
-    AR_inaccessible,
-    AR_dependent,
-    AR_delayed
-  };
-
-  bool SetMemberAccessSpecifier(NamedDecl *MemberDecl,
-                                NamedDecl *PrevMemberDecl,
-                                AccessSpecifier LexicalAS);
-
-  AccessResult CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
-                                           DeclAccessPair FoundDecl);
-  AccessResult CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
-                                           DeclAccessPair FoundDecl);
-  AccessResult CheckAllocationAccess(SourceLocation OperatorLoc,
-                                     SourceRange PlacementRange,
-                                     CXXRecordDecl *NamingClass,
-                                     DeclAccessPair FoundDecl);
-  AccessResult CheckConstructorAccess(SourceLocation Loc,
-                                      CXXConstructorDecl *D,
-                                      const InitializedEntity &Entity,
-                                      AccessSpecifier Access,
-                                      bool IsCopyBindingRefToTemp = false);
-  AccessResult CheckDestructorAccess(SourceLocation Loc,
-                                     CXXDestructorDecl *Dtor,
-                                     const PartialDiagnostic &PDiag);
-  AccessResult CheckDirectMemberAccess(SourceLocation Loc,
-                                       NamedDecl *D,
-                                       const PartialDiagnostic &PDiag);
-  AccessResult CheckMemberOperatorAccess(SourceLocation Loc,
-                                         Expr *ObjectExpr,
-                                         Expr *ArgExpr,
-                                         DeclAccessPair FoundDecl);
-  AccessResult CheckAddressOfMemberAccess(Expr *OvlExpr,
-                                          DeclAccessPair FoundDecl);
-  AccessResult CheckBaseClassAccess(SourceLocation AccessLoc,
-                                    QualType Base, QualType Derived,
-                                    const CXXBasePath &Path,
-                                    unsigned DiagID,
-                                    bool ForceCheck = false,
-                                    bool ForceUnprivileged = false);
-  void CheckLookupAccess(const LookupResult &R);
-
-  void HandleDependentAccessCheck(const DependentDiagnostic &DD,
-                         const MultiLevelTemplateArgumentList &TemplateArgs);
-  void PerformDependentDiagnostics(const DeclContext *Pattern,
-                        const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  void HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *Ctx);
-
-  /// A flag to suppress access checking.
-  bool SuppressAccessChecking;
-
-  void ActOnStartSuppressingAccessChecks();
-  void ActOnStopSuppressingAccessChecks();
-
-  enum AbstractDiagSelID {
-    AbstractNone = -1,
-    AbstractReturnType,
-    AbstractParamType,
-    AbstractVariableType,
-    AbstractFieldType
-  };
-
-  bool RequireNonAbstractType(SourceLocation Loc, QualType T,
-                              const PartialDiagnostic &PD,
-                              const CXXRecordDecl *CurrentRD = 0);
-
-  bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID,
-                              AbstractDiagSelID SelID = AbstractNone,
-                              const CXXRecordDecl *CurrentRD = 0);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Overloaded Operators [C++ 13.5]
-  //
-
-  bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl);
-
-  bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Templates [C++ 14]
-  //
-  void LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS,
-                          QualType ObjectType, bool EnteringContext,
-                          bool &MemberOfUnknownSpecialization);
-
-  virtual TemplateNameKind isTemplateName(Scope *S,
-                                          CXXScopeSpec &SS,
-                                          UnqualifiedId &Name,
-                                          TypeTy *ObjectType,
-                                          bool EnteringContext,
-                                          TemplateTy &Template,
-                                          bool &MemberOfUnknownSpecialization);
-
-  virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II,
-                                           SourceLocation IILoc,
-                                           Scope *S,
-                                           const CXXScopeSpec *SS,
-                                           TemplateTy &SuggestedTemplate,
-                                           TemplateNameKind &SuggestedKind);
-
-  bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
-  TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl);
-
-  virtual DeclPtrTy ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
-                                       SourceLocation EllipsisLoc,
-                                       SourceLocation KeyLoc,
-                                       IdentifierInfo *ParamName,
-                                       SourceLocation ParamNameLoc,
-                                       unsigned Depth, unsigned Position,
-                                       SourceLocation EqualLoc,
-                                       TypeTy *DefaultArg);
-
-  QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc);
-  virtual DeclPtrTy ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
-                                                  unsigned Depth,
-                                                  unsigned Position,
-                                                  SourceLocation EqualLoc,
-                                                  ExprArg DefaultArg);
-  virtual DeclPtrTy ActOnTemplateTemplateParameter(Scope *S,
-                                                   SourceLocation TmpLoc,
-                                                   TemplateParamsTy *Params,
-                                                   IdentifierInfo *ParamName,
-                                                   SourceLocation ParamNameLoc,
-                                                   unsigned Depth,
-                                                   unsigned Position,
-                                                   SourceLocation EqualLoc,
-                                     const ParsedTemplateArgument &DefaultArg);
-
-  virtual TemplateParamsTy *
-  ActOnTemplateParameterList(unsigned Depth,
-                             SourceLocation ExportLoc,
-                             SourceLocation TemplateLoc,
-                             SourceLocation LAngleLoc,
-                             DeclPtrTy *Params, unsigned NumParams,
-                             SourceLocation RAngleLoc);
-
-  /// \brief The context in which we are checking a template parameter
-  /// list.
-  enum TemplateParamListContext {
-    TPC_ClassTemplate,
-    TPC_FunctionTemplate,
-    TPC_ClassTemplateMember,
-    TPC_FriendFunctionTemplate
-  };
-
-  bool CheckTemplateParameterList(TemplateParameterList *NewParams,
-                                  TemplateParameterList *OldParams,
-                                  TemplateParamListContext TPC);
-  TemplateParameterList *
-  MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
-                                          const CXXScopeSpec &SS,
-                                          TemplateParameterList **ParamLists,
-                                          unsigned NumParamLists,
-                                          bool IsFriend,
-                                          bool &IsExplicitSpecialization,
-                                          bool &Invalid);
-
-  DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
-                                SourceLocation KWLoc, CXXScopeSpec &SS,
-                                IdentifierInfo *Name, SourceLocation NameLoc,
-                                AttributeList *Attr,
-                                TemplateParameterList *TemplateParams,
-                                AccessSpecifier AS);
-
-  void translateTemplateArguments(const ASTTemplateArgsPtr &In,
-                                  TemplateArgumentListInfo &Out);
-
-  QualType CheckTemplateIdType(TemplateName Template,
-                               SourceLocation TemplateLoc,
-                               const TemplateArgumentListInfo &TemplateArgs);
-
-  virtual TypeResult
-  ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
-                      SourceLocation LAngleLoc,
-                      ASTTemplateArgsPtr TemplateArgs,
-                      SourceLocation RAngleLoc);
-
-  virtual TypeResult ActOnTagTemplateIdType(TypeResult Type,
-                                            TagUseKind TUK,
-                                            DeclSpec::TST TagSpec,
-                                            SourceLocation TagLoc);
-
-  OwningExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
-                                       LookupResult &R,
-                                       bool RequiresADL,
-                               const TemplateArgumentListInfo &TemplateArgs);
-  OwningExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
-                                                DeclarationName Name,
-                                                SourceLocation NameLoc,
-                               const TemplateArgumentListInfo &TemplateArgs);
-
-  virtual TemplateNameKind ActOnDependentTemplateName(Scope *S,
-                                                  SourceLocation TemplateKWLoc,
-                                                      CXXScopeSpec &SS,
-                                                      UnqualifiedId &Name,
-                                                      TypeTy *ObjectType,
-                                                      bool EnteringContext,
-                                                      TemplateTy &Template);
-
-  bool CheckClassTemplatePartialSpecializationArgs(
-                                        TemplateParameterList *TemplateParams,
-                              const TemplateArgumentListBuilder &TemplateArgs,
-                                        bool &MirrorsPrimaryTemplate);
-
-  virtual DeclResult
-  ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
-                                   SourceLocation KWLoc,
-                                   CXXScopeSpec &SS,
-                                   TemplateTy Template,
-                                   SourceLocation TemplateNameLoc,
-                                   SourceLocation LAngleLoc,
-                                   ASTTemplateArgsPtr TemplateArgs,
-                                   SourceLocation RAngleLoc,
-                                   AttributeList *Attr,
-                                 MultiTemplateParamsArg TemplateParameterLists);
-
-  virtual DeclPtrTy ActOnTemplateDeclarator(Scope *S,
-                                  MultiTemplateParamsArg TemplateParameterLists,
-                                            Declarator &D);
-
-  virtual DeclPtrTy ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
-                                  MultiTemplateParamsArg TemplateParameterLists,
-                                                    Declarator &D);
-
-  bool
-  CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
-                                         TemplateSpecializationKind NewTSK,
-                                         NamedDecl *PrevDecl,
-                                         TemplateSpecializationKind PrevTSK,
-                                         SourceLocation PrevPtOfInstantiation,
-                                         bool &SuppressNew);
-
-  bool CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
-                    const TemplateArgumentListInfo &ExplicitTemplateArgs,
-                                                    LookupResult &Previous);
-
-  bool CheckFunctionTemplateSpecialization(FunctionDecl *FD,
-                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                                           LookupResult &Previous);
-  bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
-
-  virtual DeclResult
-  ActOnExplicitInstantiation(Scope *S,
-                             SourceLocation ExternLoc,
-                             SourceLocation TemplateLoc,
-                             unsigned TagSpec,
-                             SourceLocation KWLoc,
-                             const CXXScopeSpec &SS,
-                             TemplateTy Template,
-                             SourceLocation TemplateNameLoc,
-                             SourceLocation LAngleLoc,
-                             ASTTemplateArgsPtr TemplateArgs,
-                             SourceLocation RAngleLoc,
-                             AttributeList *Attr);
-
-  virtual DeclResult
-  ActOnExplicitInstantiation(Scope *S,
-                             SourceLocation ExternLoc,
-                             SourceLocation TemplateLoc,
-                             unsigned TagSpec,
-                             SourceLocation KWLoc,
-                             CXXScopeSpec &SS,
-                             IdentifierInfo *Name,
-                             SourceLocation NameLoc,
-                             AttributeList *Attr);
-
-  virtual DeclResult ActOnExplicitInstantiation(Scope *S,
-                                                SourceLocation ExternLoc,
-                                                SourceLocation TemplateLoc,
-                                                Declarator &D);
-
-  TemplateArgumentLoc
-  SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
-                                          SourceLocation TemplateLoc,
-                                          SourceLocation RAngleLoc,
-                                          Decl *Param,
-                                      TemplateArgumentListBuilder &Converted);
-
-  /// \brief Specifies the context in which a particular template
-  /// argument is being checked.
-  enum CheckTemplateArgumentKind {
-    /// \brief The template argument was specified in the code or was
-    /// instantiated with some deduced template arguments.
-    CTAK_Specified,
-
-    /// \brief The template argument was deduced via template argument
-    /// deduction.
-    CTAK_Deduced,
-
-    /// \brief The template argument was deduced from an array bound
-    /// via template argument deduction.
-    CTAK_DeducedFromArrayBound
-  };
-
-  bool CheckTemplateArgument(NamedDecl *Param,
-                             const TemplateArgumentLoc &Arg,
-                             TemplateDecl *Template,
-                             SourceLocation TemplateLoc,
-                             SourceLocation RAngleLoc,
-                             TemplateArgumentListBuilder &Converted,
-                             CheckTemplateArgumentKind CTAK = CTAK_Specified);
-
-  bool CheckTemplateArgumentList(TemplateDecl *Template,
-                                 SourceLocation TemplateLoc,
-                                 const TemplateArgumentListInfo &TemplateArgs,
-                                 bool PartialTemplateArgs,
-                                 TemplateArgumentListBuilder &Converted);
-
-  bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
-                                 const TemplateArgumentLoc &Arg,
-                                 TemplateArgumentListBuilder &Converted);
-
-  bool CheckTemplateArgument(TemplateTypeParmDecl *Param,
-                             TypeSourceInfo *Arg);
-  bool CheckTemplateArgumentPointerToMember(Expr *Arg,
-                                            TemplateArgument &Converted);
-  bool CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
-                             QualType InstantiatedParamType, Expr *&Arg,
-                             TemplateArgument &Converted,
-                             CheckTemplateArgumentKind CTAK = CTAK_Specified);
-  bool CheckTemplateArgument(TemplateTemplateParmDecl *Param,
-                             const TemplateArgumentLoc &Arg);
-
-  OwningExprResult
-  BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
-                                          QualType ParamType,
-                                          SourceLocation Loc);
-  OwningExprResult
-  BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
-                                              SourceLocation Loc);
-
-  /// \brief Enumeration describing how template parameter lists are compared
-  /// for equality.
-  enum TemplateParameterListEqualKind {
-    /// \brief We are matching the template parameter lists of two templates
-    /// that might be redeclarations.
-    ///
-    /// \code
-    /// template<typename T> struct X;
-    /// template<typename T> struct X;
-    /// \endcode
-    TPL_TemplateMatch,
-
-    /// \brief We are matching the template parameter lists of two template
-    /// template parameters as part of matching the template parameter lists
-    /// of two templates that might be redeclarations.
-    ///
-    /// \code
-    /// template<template<int I> class TT> struct X;
-    /// template<template<int Value> class Other> struct X;
-    /// \endcode
-    TPL_TemplateTemplateParmMatch,
-
-    /// \brief We are matching the template parameter lists of a template
-    /// template argument against the template parameter lists of a template
-    /// template parameter.
-    ///
-    /// \code
-    /// template<template<int Value> class Metafun> struct X;
-    /// template<int Value> struct integer_c;
-    /// X<integer_c> xic;
-    /// \endcode
-    TPL_TemplateTemplateArgumentMatch
-  };
-
-  bool TemplateParameterListsAreEqual(TemplateParameterList *New,
-                                      TemplateParameterList *Old,
-                                      bool Complain,
-                                      TemplateParameterListEqualKind Kind,
-                                      SourceLocation TemplateArgLoc
-                                        = SourceLocation());
-
-  bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams);
-
-  /// \brief Called when the parser has parsed a C++ typename
-  /// specifier, e.g., "typename T::type".
-  ///
-  /// \param S The scope in which this typename type occurs.
-  /// \param TypenameLoc the location of the 'typename' keyword
-  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
-  /// \param II the identifier we're retrieving (e.g., 'type' in the example).
-  /// \param IdLoc the location of the identifier.
-  virtual TypeResult
-  ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
-                    const CXXScopeSpec &SS, const IdentifierInfo &II, 
-                    SourceLocation IdLoc);
-
-  /// \brief Called when the parser has parsed a C++ typename
-  /// specifier that ends in a template-id, e.g.,
-  /// "typename MetaFun::template apply<T1, T2>".
-  ///
-  /// \param S The scope in which this typename type occurs.
-  /// \param TypenameLoc the location of the 'typename' keyword
-  /// \param SS the nested-name-specifier following the typename (e.g., 'T::').
-  /// \param TemplateLoc the location of the 'template' keyword, if any.
-  /// \param Ty the type that the typename specifier refers to.
-  virtual TypeResult
-  ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
-                    const CXXScopeSpec &SS, SourceLocation TemplateLoc, 
-                    TypeTy *Ty);
-
-  QualType CheckTypenameType(ElaboratedTypeKeyword Keyword,
-                             NestedNameSpecifier *NNS,
-                             const IdentifierInfo &II,
-                             SourceLocation KeywordLoc,
-                             SourceRange NNSRange,
-                             SourceLocation IILoc);
-
-  TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
-                                                    SourceLocation Loc,
-                                                    DeclarationName Name);
-  bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
-
-  std::string
-  getTemplateArgumentBindingsText(const TemplateParameterList *Params,
-                                  const TemplateArgumentList &Args);
-
-  std::string
-  getTemplateArgumentBindingsText(const TemplateParameterList *Params,
-                                  const TemplateArgument *Args,
-                                  unsigned NumArgs);
-
-  /// \brief Describes the result of template argument deduction.
-  ///
-  /// The TemplateDeductionResult enumeration describes the result of
-  /// template argument deduction, as returned from
-  /// DeduceTemplateArguments(). The separate TemplateDeductionInfo
-  /// structure provides additional information about the results of
-  /// template argument deduction, e.g., the deduced template argument
-  /// list (if successful) or the specific template parameters or
-  /// deduced arguments that were involved in the failure.
-  enum TemplateDeductionResult {
-    /// \brief Template argument deduction was successful.
-    TDK_Success = 0,
-    /// \brief Template argument deduction exceeded the maximum template
-    /// instantiation depth (which has already been diagnosed).
-    TDK_InstantiationDepth,
-    /// \brief Template argument deduction did not deduce a value
-    /// for every template parameter.
-    TDK_Incomplete,
-    /// \brief Template argument deduction produced inconsistent
-    /// deduced values for the given template parameter.
-    TDK_Inconsistent,
-    /// \brief Template argument deduction failed due to inconsistent
-    /// cv-qualifiers on a template parameter type that would
-    /// otherwise be deduced, e.g., we tried to deduce T in "const T"
-    /// but were given a non-const "X".
-    TDK_InconsistentQuals,
-    /// \brief Substitution of the deduced template argument values
-    /// resulted in an error.
-    TDK_SubstitutionFailure,
-    /// \brief Substitution of the deduced template argument values
-    /// into a non-deduced context produced a type or value that
-    /// produces a type that does not match the original template
-    /// arguments provided.
-    TDK_NonDeducedMismatch,
-    /// \brief When performing template argument deduction for a function
-    /// template, there were too many call arguments.
-    TDK_TooManyArguments,
-    /// \brief When performing template argument deduction for a function
-    /// template, there were too few call arguments.
-    TDK_TooFewArguments,
-    /// \brief The explicitly-specified template arguments were not valid
-    /// template arguments for the given template.
-    TDK_InvalidExplicitArguments,
-    /// \brief The arguments included an overloaded function name that could
-    /// not be resolved to a suitable function.
-    TDK_FailedOverloadResolution
-  };
-
-  /// \brief Provides information about an attempted template argument
-  /// deduction, whose success or failure was described by a
-  /// TemplateDeductionResult value.
-  class TemplateDeductionInfo {
-    /// \brief The context in which the template arguments are stored.
-    ASTContext &Context;
-
-    /// \brief The deduced template argument list.
-    ///
-    TemplateArgumentList *Deduced;
-
-    /// \brief The source location at which template argument
-    /// deduction is occurring.
-    SourceLocation Loc;
-
-    // do not implement these
-    TemplateDeductionInfo(const TemplateDeductionInfo&);
-    TemplateDeductionInfo &operator=(const TemplateDeductionInfo&);
-
-  public:
-    TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc)
-      : Context(Context), Deduced(0), Loc(Loc) { }
-
-    ~TemplateDeductionInfo() {
-      // FIXME: if (Deduced) Deduced->Destroy(Context);
-    }
-
-    /// \brief Returns the location at which template argument is
-    /// occuring.
-    SourceLocation getLocation() const {
-      return Loc;
-    }
-
-    /// \brief Take ownership of the deduced template argument list.
-    TemplateArgumentList *take() {
-      TemplateArgumentList *Result = Deduced;
-      Deduced = 0;
-      return Result;
-    }
-
-    /// \brief Provide a new template argument list that contains the
-    /// results of template argument deduction.
-    void reset(TemplateArgumentList *NewDeduced) {
-      // FIXME: if (Deduced) Deduced->Destroy(Context);
-      Deduced = NewDeduced;
-    }
-
-    /// \brief The template parameter to which a template argument
-    /// deduction failure refers.
-    ///
-    /// Depending on the result of template argument deduction, this
-    /// template parameter may have different meanings:
-    ///
-    ///   TDK_Incomplete: this is the first template parameter whose
-    ///   corresponding template argument was not deduced.
-    ///
-    ///   TDK_Inconsistent: this is the template parameter for which
-    ///   two different template argument values were deduced.
-    TemplateParameter Param;
-
-    /// \brief The first template argument to which the template
-    /// argument deduction failure refers.
-    ///
-    /// Depending on the result of the template argument deduction,
-    /// this template argument may have different meanings:
-    ///
-    ///   TDK_Inconsistent: this argument is the first value deduced
-    ///   for the corresponding template parameter.
-    ///
-    ///   TDK_SubstitutionFailure: this argument is the template
-    ///   argument we were instantiating when we encountered an error.
-    ///
-    ///   TDK_NonDeducedMismatch: this is the template argument
-    ///   provided in the source code.
-    TemplateArgument FirstArg;
-
-    /// \brief The second template argument to which the template
-    /// argument deduction failure refers.
-    ///
-    /// FIXME: Finish documenting this.
-    TemplateArgument SecondArg;
-  };
-
-  TemplateDeductionResult
-  DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
-                          const TemplateArgumentList &TemplateArgs,
-                          TemplateDeductionInfo &Info);
-
-  TemplateDeductionResult
-  SubstituteExplicitTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                        const TemplateArgumentListInfo &ExplicitTemplateArgs,
-                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                 llvm::SmallVectorImpl<QualType> &ParamTypes,
-                                      QualType *FunctionType,
-                                      TemplateDeductionInfo &Info);
-
-  TemplateDeductionResult
-  FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
-                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                  unsigned NumExplicitlySpecified,
-                                  FunctionDecl *&Specialization,
-                                  TemplateDeductionInfo &Info);
-
-  TemplateDeductionResult
-  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                          Expr **Args, unsigned NumArgs,
-                          FunctionDecl *&Specialization,
-                          TemplateDeductionInfo &Info);
-
-  TemplateDeductionResult
-  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                          QualType ArgFunctionType,
-                          FunctionDecl *&Specialization,
-                          TemplateDeductionInfo &Info);
-
-  TemplateDeductionResult
-  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                          QualType ToType,
-                          CXXConversionDecl *&Specialization,
-                          TemplateDeductionInfo &Info);
-
-  TemplateDeductionResult
-  DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
-                          const TemplateArgumentListInfo *ExplicitTemplateArgs,
-                          FunctionDecl *&Specialization,
-                          TemplateDeductionInfo &Info);
-
-  FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
-                                                   FunctionTemplateDecl *FT2,
-                                                   SourceLocation Loc,
-                                           TemplatePartialOrderingContext TPOC);
-  UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin,
-                                           UnresolvedSetIterator SEnd,
-                                           TemplatePartialOrderingContext TPOC,
-                                           SourceLocation Loc,
-                                           const PartialDiagnostic &NoneDiag,
-                                           const PartialDiagnostic &AmbigDiag,
-                                        const PartialDiagnostic &CandidateDiag);
-
-  ClassTemplatePartialSpecializationDecl *
-  getMoreSpecializedPartialSpecialization(
-                                  ClassTemplatePartialSpecializationDecl *PS1,
-                                  ClassTemplatePartialSpecializationDecl *PS2,
-                                  SourceLocation Loc);
-
-  void MarkUsedTemplateParameters(const TemplateArgumentList &TemplateArgs,
-                                  bool OnlyDeduced,
-                                  unsigned Depth,
-                                  llvm::SmallVectorImpl<bool> &Used);
-  void MarkDeducedTemplateParameters(FunctionTemplateDecl *FunctionTemplate,
-                                     llvm::SmallVectorImpl<bool> &Deduced);
-
-  //===--------------------------------------------------------------------===//
-  // C++ Template Instantiation
-  //
-
-  MultiLevelTemplateArgumentList getTemplateInstantiationArgs(NamedDecl *D,
-                                     const TemplateArgumentList *Innermost = 0,
-                                                bool RelativeToPrimary = false,
-                                               const FunctionDecl *Pattern = 0);
-
-  /// \brief A template instantiation that is currently in progress.
-  struct ActiveTemplateInstantiation {
-    /// \brief The kind of template instantiation we are performing
-    enum InstantiationKind {
-      /// We are instantiating a template declaration. The entity is
-      /// the declaration we're instantiating (e.g., a CXXRecordDecl).
-      TemplateInstantiation,
-
-      /// We are instantiating a default argument for a template
-      /// parameter. The Entity is the template, and
-      /// TemplateArgs/NumTemplateArguments provides the template
-      /// arguments as specified.
-      /// FIXME: Use a TemplateArgumentList
-      DefaultTemplateArgumentInstantiation,
-
-      /// We are instantiating a default argument for a function.
-      /// The Entity is the ParmVarDecl, and TemplateArgs/NumTemplateArgs
-      /// provides the template arguments as specified.
-      DefaultFunctionArgumentInstantiation,
-
-      /// We are substituting explicit template arguments provided for
-      /// a function template. The entity is a FunctionTemplateDecl.
-      ExplicitTemplateArgumentSubstitution,
-
-      /// We are substituting template argument determined as part of
-      /// template argument deduction for either a class template
-      /// partial specialization or a function template. The
-      /// Entity is either a ClassTemplatePartialSpecializationDecl or
-      /// a FunctionTemplateDecl.
-      DeducedTemplateArgumentSubstitution,
-
-      /// We are substituting prior template arguments into a new
-      /// template parameter. The template parameter itself is either a
-      /// NonTypeTemplateParmDecl or a TemplateTemplateParmDecl.
-      PriorTemplateArgumentSubstitution,
-
-      /// We are checking the validity of a default template argument that
-      /// has been used when naming a template-id.
-      DefaultTemplateArgumentChecking
-    } Kind;
-
-    /// \brief The point of instantiation within the source code.
-    SourceLocation PointOfInstantiation;
-
-    /// \brief The template in which we are performing the instantiation,
-    /// for substitutions of prior template arguments.
-    TemplateDecl *Template;
-
-    /// \brief The entity that is being instantiated.
-    uintptr_t Entity;
-
-    /// \brief The list of template arguments we are substituting, if they
-    /// are not part of the entity.
-    const TemplateArgument *TemplateArgs;
-
-    /// \brief The number of template arguments in TemplateArgs.
-    unsigned NumTemplateArgs;
-
-    /// \brief The source range that covers the construct that cause
-    /// the instantiation, e.g., the template-id that causes a class
-    /// template instantiation.
-    SourceRange InstantiationRange;
-
-    ActiveTemplateInstantiation()
-      : Kind(TemplateInstantiation), Template(0), Entity(0), TemplateArgs(0),
-        NumTemplateArgs(0) {}
-
-    /// \brief Determines whether this template is an actual instantiation
-    /// that should be counted toward the maximum instantiation depth.
-    bool isInstantiationRecord() const;
-
-    friend bool operator==(const ActiveTemplateInstantiation &X,
-                           const ActiveTemplateInstantiation &Y) {
-      if (X.Kind != Y.Kind)
-        return false;
-
-      if (X.Entity != Y.Entity)
-        return false;
-
-      switch (X.Kind) {
-      case TemplateInstantiation:
-        return true;
-
-      case PriorTemplateArgumentSubstitution:
-      case DefaultTemplateArgumentChecking:
-        if (X.Template != Y.Template)
-          return false;
-
-        // Fall through
-
-      case DefaultTemplateArgumentInstantiation:
-      case ExplicitTemplateArgumentSubstitution:
-      case DeducedTemplateArgumentSubstitution:
-      case DefaultFunctionArgumentInstantiation:
-        return X.TemplateArgs == Y.TemplateArgs;
-
-      }
-
-      return true;
-    }
-
-    friend bool operator!=(const ActiveTemplateInstantiation &X,
-                           const ActiveTemplateInstantiation &Y) {
-      return !(X == Y);
-    }
-  };
-
-  /// \brief List of active template instantiations.
-  ///
-  /// This vector is treated as a stack. As one template instantiation
-  /// requires another template instantiation, additional
-  /// instantiations are pushed onto the stack up to a
-  /// user-configurable limit LangOptions::InstantiationDepth.
-  llvm::SmallVector<ActiveTemplateInstantiation, 16>
-    ActiveTemplateInstantiations;
-
-  /// \brief The number of ActiveTemplateInstantiation entries in
-  /// \c ActiveTemplateInstantiations that are not actual instantiations and,
-  /// therefore, should not be counted as part of the instantiation depth.
-  unsigned NonInstantiationEntries;
-
-  /// \brief The last template from which a template instantiation
-  /// error or warning was produced.
-  ///
-  /// This value is used to suppress printing of redundant template
-  /// instantiation backtraces when there are multiple errors in the
-  /// same instantiation. FIXME: Does this belong in Sema? It's tough
-  /// to implement it anywhere else.
-  ActiveTemplateInstantiation LastTemplateInstantiationErrorContext;
-
-  /// \brief The stack of calls expression undergoing template instantiation.
-  ///
-  /// The top of this stack is used by a fixit instantiating unresolved
-  /// function calls to fix the AST to match the textual change it prints.
-  llvm::SmallVector<CallExpr *, 8> CallsUndergoingInstantiation;
-
-  /// \brief A stack object to be created when performing template
-  /// instantiation.
-  ///
-  /// Construction of an object of type \c InstantiatingTemplate
-  /// pushes the current instantiation onto the stack of active
-  /// instantiations. If the size of this stack exceeds the maximum
-  /// number of recursive template instantiations, construction
-  /// produces an error and evaluates true.
-  ///
-  /// Destruction of this object will pop the named instantiation off
-  /// the stack.
-  struct InstantiatingTemplate {
-    /// \brief Note that we are instantiating a class template,
-    /// function template, or a member thereof.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          Decl *Entity,
-                          SourceRange InstantiationRange = SourceRange());
-
-    /// \brief Note that we are instantiating a default argument in a
-    /// template-id.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          TemplateDecl *Template,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          SourceRange InstantiationRange = SourceRange());
-
-    /// \brief Note that we are instantiating a default argument in a
-    /// template-id.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          FunctionTemplateDecl *FunctionTemplate,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          ActiveTemplateInstantiation::InstantiationKind Kind,
-                          SourceRange InstantiationRange = SourceRange());
-
-    /// \brief Note that we are instantiating as part of template
-    /// argument deduction for a class template partial
-    /// specialization.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          ClassTemplatePartialSpecializationDecl *PartialSpec,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          SourceRange InstantiationRange = SourceRange());
-
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          ParmVarDecl *Param,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          SourceRange InstantiationRange = SourceRange());
-
-    /// \brief Note that we are substituting prior template arguments into a
-    /// non-type or template template parameter.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          TemplateDecl *Template,
-                          NonTypeTemplateParmDecl *Param,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          SourceRange InstantiationRange);
-
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          TemplateDecl *Template,
-                          TemplateTemplateParmDecl *Param,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          SourceRange InstantiationRange);
-
-    /// \brief Note that we are checking the default template argument
-    /// against the template parameter for a given template-id.
-    InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
-                          TemplateDecl *Template,
-                          NamedDecl *Param,
-                          const TemplateArgument *TemplateArgs,
-                          unsigned NumTemplateArgs,
-                          SourceRange InstantiationRange);
-
-
-    /// \brief Note that we have finished instantiating this template.
-    void Clear();
-
-    ~InstantiatingTemplate() { Clear(); }
-
-    /// \brief Determines whether we have exceeded the maximum
-    /// recursive template instantiations.
-    operator bool() const { return Invalid; }
-
-  private:
-    Sema &SemaRef;
-    bool Invalid;
-
-    bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
-                                 SourceRange InstantiationRange);
-
-    InstantiatingTemplate(const InstantiatingTemplate&); // not implemented
-
-    InstantiatingTemplate&
-    operator=(const InstantiatingTemplate&); // not implemented
-  };
-
-  void PrintInstantiationStack();
-
-  /// \brief Determines whether we are currently in a context where
-  /// template argument substitution failures are not considered
-  /// errors.
-  ///
-  /// When this routine returns true, the emission of most diagnostics
-  /// will be suppressed and there will be no local error recovery.
-  bool isSFINAEContext() const;
-
-  /// \brief RAII class used to determine whether SFINAE has
-  /// trapped any errors that occur during template argument
-  /// deduction.
-  class SFINAETrap {
-    Sema &SemaRef;
-    unsigned PrevSFINAEErrors;
-  public:
-    explicit SFINAETrap(Sema &SemaRef)
-      : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors) { }
-
-    ~SFINAETrap() { SemaRef.NumSFINAEErrors = PrevSFINAEErrors; }
-
-    /// \brief Determine whether any SFINAE errors have been trapped.
-    bool hasErrorOccurred() const {
-      return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
-    }
-  };
-
-  /// \brief RAII class that determines when any errors have occurred
-  /// between the time the instance was created and the time it was
-  /// queried.
-  class ErrorTrap {
-    Sema &SemaRef;
-    unsigned PrevErrors;
-
-  public:
-    explicit ErrorTrap(Sema &SemaRef)
-      : SemaRef(SemaRef), PrevErrors(SemaRef.getDiagnostics().getNumErrors()) {}
-
-    /// \brief Determine whether any errors have occurred since this
-    /// object instance was created.
-    bool hasErrorOccurred() const {
-      return SemaRef.getDiagnostics().getNumErrors() > PrevErrors;
-    }
-  };
-
-  /// \brief A stack-allocated class that identifies which local
-  /// variable declaration instantiations are present in this scope.
-  ///
-  /// A new instance of this class type will be created whenever we
-  /// instantiate a new function declaration, which will have its own
-  /// set of parameter declarations.
-  class LocalInstantiationScope {
-    /// \brief Reference to the semantic analysis that is performing
-    /// this template instantiation.
-    Sema &SemaRef;
-
-    /// \brief A mapping from local declarations that occur
-    /// within a template to their instantiations.
-    ///
-    /// This mapping is used during instantiation to keep track of,
-    /// e.g., function parameter and variable declarations. For example,
-    /// given:
-    ///
-    /// \code
-    ///   template<typename T> T add(T x, T y) { return x + y; }
-    /// \endcode
-    ///
-    /// when we instantiate add<int>, we will introduce a mapping from
-    /// the ParmVarDecl for 'x' that occurs in the template to the
-    /// instantiated ParmVarDecl for 'x'.
-    llvm::DenseMap<const Decl *, Decl *> LocalDecls;
-
-    /// \brief The outer scope, which contains local variable
-    /// definitions from some other instantiation (that may not be
-    /// relevant to this particular scope).
-    LocalInstantiationScope *Outer;
-
-    /// \brief Whether we have already exited this scope.
-    bool Exited;
-
-    /// \brief Whether to combine this scope with the outer scope, such that
-    /// lookup will search our outer scope.
-    bool CombineWithOuterScope;
-    
-    // This class is non-copyable
-    LocalInstantiationScope(const LocalInstantiationScope &);
-    LocalInstantiationScope &operator=(const LocalInstantiationScope &);
-
-  public:
-    LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false)
-      : SemaRef(SemaRef), Outer(SemaRef.CurrentInstantiationScope),
-        Exited(false), CombineWithOuterScope(CombineWithOuterScope)
-    {
-      SemaRef.CurrentInstantiationScope = this;
-    }
-
-    ~LocalInstantiationScope() {
-      Exit();
-    }
-
-    /// \brief Exit this local instantiation scope early.
-    void Exit() {
-      if (Exited)
-        return;
-      
-      SemaRef.CurrentInstantiationScope = Outer;
-      Exited = true;
-    }
-
-    Decl *getInstantiationOf(const Decl *D);
-
-    VarDecl *getInstantiationOf(const VarDecl *Var) {
-      return cast<VarDecl>(getInstantiationOf(cast<Decl>(Var)));
-    }
-
-    ParmVarDecl *getInstantiationOf(const ParmVarDecl *Var) {
-      return cast<ParmVarDecl>(getInstantiationOf(cast<Decl>(Var)));
-    }
-
-    NonTypeTemplateParmDecl *getInstantiationOf(
-                                          const NonTypeTemplateParmDecl *Var) {
-      return cast<NonTypeTemplateParmDecl>(getInstantiationOf(cast<Decl>(Var)));
-    }
-
-    void InstantiatedLocal(const Decl *D, Decl *Inst);
-  };
-
-  /// \brief The current instantiation scope used to store local
-  /// variables.
-  LocalInstantiationScope *CurrentInstantiationScope;
-
-  /// \brief The number of typos corrected by CorrectTypo.
-  unsigned TyposCorrected;
-
-  /// \brief Worker object for performing CFG-based warnings.
-  sema::AnalysisBasedWarnings AnalysisWarnings;
-
-  /// \brief An entity for which implicit template instantiation is required.
-  ///
-  /// The source location associated with the declaration is the first place in
-  /// the source code where the declaration was "used". It is not necessarily
-  /// the point of instantiation (which will be either before or after the
-  /// namespace-scope declaration that triggered this implicit instantiation),
-  /// However, it is the location that diagnostics should generally refer to,
-  /// because users will need to know what code triggered the instantiation.
-  typedef std::pair<ValueDecl *, SourceLocation> PendingImplicitInstantiation;
-
-  /// \brief The queue of implicit template instantiations that are required
-  /// but have not yet been performed.
-  std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
-
-  /// \brief The queue of implicit template instantiations that are required
-  /// and must be performed within the current local scope.
-  ///
-  /// This queue is only used for member functions of local classes in
-  /// templates, which must be instantiated in the same scope as their
-  /// enclosing function, so that they can reference function-local
-  /// types, static variables, enumerators, etc.
-  std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations;
-
-  void PerformPendingImplicitInstantiations(bool LocalOnly = false);
-
-  TypeSourceInfo *SubstType(TypeSourceInfo *T,
-                            const MultiLevelTemplateArgumentList &TemplateArgs,
-                            SourceLocation Loc, DeclarationName Entity);
-
-  QualType SubstType(QualType T,
-                     const MultiLevelTemplateArgumentList &TemplateArgs,
-                     SourceLocation Loc, DeclarationName Entity);
-
-  TypeSourceInfo *SubstFunctionDeclType(TypeSourceInfo *T,
-                            const MultiLevelTemplateArgumentList &TemplateArgs,
-                                        SourceLocation Loc,
-                                        DeclarationName Entity);
-  ParmVarDecl *SubstParmVarDecl(ParmVarDecl *D,
-                            const MultiLevelTemplateArgumentList &TemplateArgs);
-  OwningExprResult SubstExpr(Expr *E,
-                            const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  OwningStmtResult SubstStmt(Stmt *S,
-                            const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  Decl *SubstDecl(Decl *D, DeclContext *Owner,
-                  const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  bool
-  SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
-                      CXXRecordDecl *Pattern,
-                      const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  bool
-  InstantiateClass(SourceLocation PointOfInstantiation,
-                   CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
-                   const MultiLevelTemplateArgumentList &TemplateArgs,
-                   TemplateSpecializationKind TSK,
-                   bool Complain = true);
-
-  bool
-  InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
-                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
-                           TemplateSpecializationKind TSK,
-                           bool Complain = true);
-
-  void InstantiateClassMembers(SourceLocation PointOfInstantiation,
-                               CXXRecordDecl *Instantiation,
-                            const MultiLevelTemplateArgumentList &TemplateArgs,
-                               TemplateSpecializationKind TSK);
-
-  void InstantiateClassTemplateSpecializationMembers(
-                                          SourceLocation PointOfInstantiation,
-                           ClassTemplateSpecializationDecl *ClassTemplateSpec,
-                                                TemplateSpecializationKind TSK);
-
-  NestedNameSpecifier *
-  SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
-                           SourceRange Range,
-                           const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  TemplateName
-  SubstTemplateName(TemplateName Name, SourceLocation Loc,
-                    const MultiLevelTemplateArgumentList &TemplateArgs);
-  bool Subst(const TemplateArgumentLoc &Arg, TemplateArgumentLoc &Result,
-             const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
-                                     FunctionDecl *Function,
-                                     bool Recursive = false,
-                                     bool DefinitionRequired = false);
-  void InstantiateStaticDataMemberDefinition(
-                                     SourceLocation PointOfInstantiation,
-                                     VarDecl *Var,
-                                     bool Recursive = false,
-                                     bool DefinitionRequired = false);
-
-  void InstantiateMemInitializers(CXXConstructorDecl *New,
-                                  const CXXConstructorDecl *Tmpl,
-                            const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
-                          const MultiLevelTemplateArgumentList &TemplateArgs);
-  DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
-                          const MultiLevelTemplateArgumentList &TemplateArgs);
-
-  // Objective-C declarations.
-  virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
-                                             IdentifierInfo *ClassName,
-                                             SourceLocation ClassLoc,
-                                             IdentifierInfo *SuperName,
-                                             SourceLocation SuperLoc,
-                                             const DeclPtrTy *ProtoRefs,
-                                             unsigned NumProtoRefs,
-                                             const SourceLocation *ProtoLocs,
-                                             SourceLocation EndProtoLoc,
-                                             AttributeList *AttrList);
-
-  virtual DeclPtrTy ActOnCompatiblityAlias(
-                    SourceLocation AtCompatibilityAliasLoc,
-                    IdentifierInfo *AliasName,  SourceLocation AliasLocation,
-                    IdentifierInfo *ClassName, SourceLocation ClassLocation);
-
-  void CheckForwardProtocolDeclarationForCircularDependency(
-    IdentifierInfo *PName,
-    SourceLocation &PLoc, SourceLocation PrevLoc,
-    const ObjCList<ObjCProtocolDecl> &PList);
-
-  virtual DeclPtrTy ActOnStartProtocolInterface(
-                    SourceLocation AtProtoInterfaceLoc,
-                    IdentifierInfo *ProtocolName, SourceLocation ProtocolLoc,
-                    const DeclPtrTy *ProtoRefNames, unsigned NumProtoRefs,
-                    const SourceLocation *ProtoLocs,
-                    SourceLocation EndProtoLoc,
-                    AttributeList *AttrList);
-
-  virtual DeclPtrTy ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
-                                                IdentifierInfo *ClassName,
-                                                SourceLocation ClassLoc,
-                                                IdentifierInfo *CategoryName,
-                                                SourceLocation CategoryLoc,
-                                                const DeclPtrTy *ProtoRefs,
-                                                unsigned NumProtoRefs,
-                                                const SourceLocation *ProtoLocs,
-                                                SourceLocation EndProtoLoc);
-
-  virtual DeclPtrTy ActOnStartClassImplementation(
-                    SourceLocation AtClassImplLoc,
-                    IdentifierInfo *ClassName, SourceLocation ClassLoc,
-                    IdentifierInfo *SuperClassname,
-                    SourceLocation SuperClassLoc);
-
-  virtual DeclPtrTy ActOnStartCategoryImplementation(
-                                                  SourceLocation AtCatImplLoc,
-                                                  IdentifierInfo *ClassName,
-                                                  SourceLocation ClassLoc,
-                                                  IdentifierInfo *CatName,
-                                                  SourceLocation CatLoc);
-
-  virtual DeclPtrTy ActOnForwardClassDeclaration(SourceLocation Loc,
-                                                 IdentifierInfo **IdentList,
-                                                 SourceLocation *IdentLocs,
-                                                 unsigned NumElts);
-
-  virtual DeclPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc,
-                                            const IdentifierLocPair *IdentList,
-                                                  unsigned NumElts,
-                                                  AttributeList *attrList);
-
-  virtual void FindProtocolDeclaration(bool WarnOnDeclarations,
-                                       const IdentifierLocPair *ProtocolId,
-                                       unsigned NumProtocols,
-                                   llvm::SmallVectorImpl<DeclPtrTy> &Protocols);
-
-  /// Ensure attributes are consistent with type.
-  /// \param [in, out] Attributes The attributes to check; they will
-  /// be modified to be consistent with \arg PropertyTy.
-  void CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
-                                   SourceLocation Loc,
-                                   unsigned &Attributes);
-  void ProcessPropertyDecl(ObjCPropertyDecl *property, ObjCContainerDecl *DC);
-  void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
-                                ObjCPropertyDecl *SuperProperty,
-                                const IdentifierInfo *Name);
-  void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl);
-
-  void CompareMethodParamsInBaseAndSuper(Decl *IDecl,
-                                         ObjCMethodDecl *MethodDecl,
-                                         bool IsInstance);
-
-  void CompareProperties(Decl *CDecl, DeclPtrTy MergeProtocols);
-
-  void DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
-                                        ObjCInterfaceDecl *ID);
-
-  void MatchOneProtocolPropertiesInClass(Decl *CDecl,
-                                         ObjCProtocolDecl *PDecl);
-
-  virtual void ActOnAtEnd(Scope *S, SourceRange AtEnd,
-                          DeclPtrTy classDecl,
-                          DeclPtrTy *allMethods = 0, unsigned allNum = 0,
-                          DeclPtrTy *allProperties = 0, unsigned pNum = 0,
-                          DeclGroupPtrTy *allTUVars = 0, unsigned tuvNum = 0);
-
-  virtual DeclPtrTy ActOnProperty(Scope *S, SourceLocation AtLoc,
-                                  FieldDeclarator &FD, ObjCDeclSpec &ODS,
-                                  Selector GetterSel, Selector SetterSel,
-                                  DeclPtrTy ClassCategory,
-                                  bool *OverridingProperty,
-                                  tok::ObjCKeywordKind MethodImplKind);
-
-  virtual DeclPtrTy ActOnPropertyImplDecl(Scope *S,
-                                          SourceLocation AtLoc,
-                                          SourceLocation PropertyLoc,
-                                          bool ImplKind,DeclPtrTy ClassImplDecl,
-                                          IdentifierInfo *PropertyId,
-                                          IdentifierInfo *PropertyIvar);
-
-  virtual DeclPtrTy ActOnMethodDeclaration(
-    SourceLocation BeginLoc, // location of the + or -.
-    SourceLocation EndLoc,   // location of the ; or {.
-    tok::TokenKind MethodType,
-    DeclPtrTy ClassDecl, ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
-    Selector Sel,
-    // optional arguments. The number of types/arguments is obtained
-    // from the Sel.getNumArgs().
-    ObjCArgInfo *ArgInfo,
-    DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
-    AttributeList *AttrList, tok::ObjCKeywordKind MethodImplKind,
-    bool isVariadic = false);
-
-  // Helper method for ActOnClassMethod/ActOnInstanceMethod.
-  // Will search "local" class/category implementations for a method decl.
-  // Will also search in class's root looking for instance method.
-  // Returns 0 if no method is found.
-  ObjCMethodDecl *LookupPrivateClassMethod(Selector Sel,
-                                           ObjCInterfaceDecl *CDecl);
-  ObjCMethodDecl *LookupPrivateInstanceMethod(Selector Sel,
-                                              ObjCInterfaceDecl *ClassDecl);
-
-  OwningExprResult
-  HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
-                            Expr *BaseExpr,
-                            DeclarationName MemberName,
-                            SourceLocation MemberLoc);
-
-  virtual OwningExprResult
-  ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
-                            IdentifierInfo &propertyName,
-                            SourceLocation receiverNameLoc,
-                            SourceLocation propertyNameLoc);
-
-  virtual ObjCMessageKind getObjCMessageKind(Scope *S,
-                                             IdentifierInfo *Name,
-                                             SourceLocation NameLoc,
-                                             bool IsSuper,
-                                             bool HasTrailingDot,
-                                             TypeTy *&ReceiverType);
-
-  virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
-                                             Selector Sel,
-                                             SourceLocation LBracLoc,
-                                             SourceLocation SelectorLoc,
-                                             SourceLocation RBracLoc,
-                                             MultiExprArg Args);
-
-  OwningExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
-                                     QualType ReceiverType,
-                                     SourceLocation SuperLoc,
-                                     Selector Sel,
-                                     ObjCMethodDecl *Method,
-                                     SourceLocation LBracLoc,
-                                     SourceLocation RBracLoc,
-                                     MultiExprArg Args);
-
-  virtual OwningExprResult ActOnClassMessage(Scope *S,
-                                             TypeTy *Receiver,
-                                             Selector Sel,
-                                             SourceLocation LBracLoc,
-                                             SourceLocation SelectorLoc,
-                                             SourceLocation RBracLoc,
-                                             MultiExprArg Args);
-
-  OwningExprResult BuildInstanceMessage(ExprArg Receiver,
-                                        QualType ReceiverType,
-                                        SourceLocation SuperLoc,
-                                        Selector Sel,
-                                        ObjCMethodDecl *Method,
-                                        SourceLocation LBracLoc,
-                                        SourceLocation RBracLoc,
-                                        MultiExprArg Args);
-
-  virtual OwningExprResult ActOnInstanceMessage(Scope *S,
-                                                ExprArg Receiver,
-                                                Selector Sel,
-                                                SourceLocation LBracLoc,
-                                                SourceLocation SelectorLoc,
-                                                SourceLocation RBracLoc,
-                                                MultiExprArg Args);
-
-
-  /// ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
-  virtual void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
-                                       SourceLocation PragmaLoc,
-                                       SourceLocation KindLoc);
-
-  /// ActOnPragmaPack - Called on well formed #pragma pack(...).
-  virtual void ActOnPragmaPack(PragmaPackKind Kind,
-                               IdentifierInfo *Name,
-                               ExprTy *Alignment,
-                               SourceLocation PragmaLoc,
-                               SourceLocation LParenLoc,
-                               SourceLocation RParenLoc);
-
-  /// ActOnPragmaUnused - Called on well-formed '#pragma unused'.
-  virtual void ActOnPragmaUnused(const Token *Identifiers,
-                                 unsigned NumIdentifiers, Scope *curScope,
-                                 SourceLocation PragmaLoc,
-                                 SourceLocation LParenLoc,
-                                 SourceLocation RParenLoc);
-
-  NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
-  void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
-
-  /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
-  virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
-                                 SourceLocation PragmaLoc,
-                                 SourceLocation WeakNameLoc);
-
-  /// ActOnPragmaWeakAlias - Called on well formed #pragma weak ident = ident.
-  virtual void ActOnPragmaWeakAlias(IdentifierInfo* WeakName,
-                                    IdentifierInfo* AliasName,
-                                    SourceLocation PragmaLoc,
-                                    SourceLocation WeakNameLoc,
-                                    SourceLocation AliasNameLoc);
-
-  /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
-  /// a the record decl, to handle '#pragma pack' and '#pragma options align'.
-  void AddAlignmentAttributesForRecord(RecordDecl *RD);
-
-  /// FreePackedContext - Deallocate and null out PackContext.
-  void FreePackedContext();
-
-  /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
-  void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
-
-  /// ImpCastExprToType - If Expr is not of type 'Type', insert an implicit
-  /// cast.  If there is already an implicit cast, merge into the existing one.
-  /// If isLvalue, the result of the cast is an lvalue.
-  void ImpCastExprToType(Expr *&Expr, QualType Type, CastExpr::CastKind Kind,
-                         bool isLvalue = false,
-                         CXXBaseSpecifierArray BasePath =
-                          CXXBaseSpecifierArray());
-
-  // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
-  // functions and arrays to their respective pointers (C99 6.3.2.1).
-  Expr *UsualUnaryConversions(Expr *&expr);
-
-  // DefaultFunctionArrayConversion - converts functions and arrays
-  // to their respective pointers (C99 6.3.2.1).
-  void DefaultFunctionArrayConversion(Expr *&expr);
-
-  // DefaultFunctionArrayLvalueConversion - converts functions and
-  // arrays to their respective pointers and performs the
-  // lvalue-to-rvalue conversion.
-  void DefaultFunctionArrayLvalueConversion(Expr *&expr);
-
-  // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
-  // do not have a prototype. Integer promotions are performed on each
-  // argument, and arguments that have type float are promoted to double.
-  void DefaultArgumentPromotion(Expr *&Expr);
-
-  // Used for emitting the right warning by DefaultVariadicArgumentPromotion
-  enum VariadicCallType {
-    VariadicFunction,
-    VariadicBlock,
-    VariadicMethod,
-    VariadicConstructor,
-    VariadicDoesNotApply
-  };
-
-  /// GatherArgumentsForCall - Collector argument expressions for various
-  /// form of call prototypes.
-  bool GatherArgumentsForCall(SourceLocation CallLoc,
-                              FunctionDecl *FDecl,
-                              const FunctionProtoType *Proto,
-                              unsigned FirstProtoArg,
-                              Expr **Args, unsigned NumArgs,
-                              llvm::SmallVector<Expr *, 8> &AllArgs,
-                              VariadicCallType CallType = VariadicDoesNotApply);
-
-  // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
-  // will warn if the resulting type is not a POD type.
-  bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT,
-                                        FunctionDecl *FDecl);
-
-  // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
-  // operands and then handles various conversions that are common to binary
-  // operators (C99 6.3.1.8). If both operands aren't arithmetic, this
-  // routine returns the first non-arithmetic type found. The client is
-  // responsible for emitting appropriate error diagnostics.
-  QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
-                                      bool isCompAssign = false);
-
-  /// AssignConvertType - All of the 'assignment' semantic checks return this
-  /// enum to indicate whether the assignment was allowed.  These checks are
-  /// done for simple assignments, as well as initialization, return from
-  /// function, argument passing, etc.  The query is phrased in terms of a
-  /// source and destination type.
-  enum AssignConvertType {
-    /// Compatible - the types are compatible according to the standard.
-    Compatible,
-
-    /// PointerToInt - The assignment converts a pointer to an int, which we
-    /// accept as an extension.
-    PointerToInt,
-
-    /// IntToPointer - The assignment converts an int to a pointer, which we
-    /// accept as an extension.
-    IntToPointer,
-
-    /// FunctionVoidPointer - The assignment is between a function pointer and
-    /// void*, which the standard doesn't allow, but we accept as an extension.
-    FunctionVoidPointer,
-
-    /// IncompatiblePointer - The assignment is between two pointers types that
-    /// are not compatible, but we accept them as an extension.
-    IncompatiblePointer,
-
-    /// IncompatiblePointer - The assignment is between two pointers types which
-    /// point to integers which have a different sign, but are otherwise identical.
-    /// This is a subset of the above, but broken out because it's by far the most
-    /// common case of incompatible pointers.
-    IncompatiblePointerSign,
-
-    /// CompatiblePointerDiscardsQualifiers - The assignment discards
-    /// c/v/r qualifiers, which we accept as an extension.
-    CompatiblePointerDiscardsQualifiers,
-
-    /// IncompatibleNestedPointerQualifiers - The assignment is between two
-    /// nested pointer types, and the qualifiers other than the first two
-    /// levels differ e.g. char ** -> const char **, but we accept them as an
-    /// extension.
-    IncompatibleNestedPointerQualifiers,
-
-    /// IncompatibleVectors - The assignment is between two vector types that
-    /// have the same size, which we accept as an extension.
-    IncompatibleVectors,
-
-    /// IntToBlockPointer - The assignment converts an int to a block
-    /// pointer. We disallow this.
-    IntToBlockPointer,
-
-    /// IncompatibleBlockPointer - The assignment is between two block
-    /// pointers types that are not compatible.
-    IncompatibleBlockPointer,
-
-    /// IncompatibleObjCQualifiedId - The assignment is between a qualified
-    /// id type and something else (that is incompatible with it). For example,
-    /// "id <XXX>" = "Foo *", where "Foo *" doesn't implement the XXX protocol.
-    IncompatibleObjCQualifiedId,
-
-    /// Incompatible - We reject this conversion outright, it is invalid to
-    /// represent it in the AST.
-    Incompatible
-  };
-
-  /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
-  /// assignment conversion type specified by ConvTy.  This returns true if the
-  /// conversion was invalid or false if the conversion was accepted.
-  bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
-                                SourceLocation Loc,
-                                QualType DstType, QualType SrcType,
-                                Expr *SrcExpr, AssignmentAction Action,
-                                bool *Complained = 0);
-
-  /// CheckAssignmentConstraints - Perform type checking for assignment,
-  /// argument passing, variable initialization, and function return values.
-  /// This routine is only used by the following two methods. C99 6.5.16.
-  AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs);
-
-  // CheckSingleAssignmentConstraints - Currently used by
-  // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking,
-  // this routine performs the default function/array converions.
-  AssignConvertType CheckSingleAssignmentConstraints(QualType lhs,
-                                                     Expr *&rExpr);
-
-  // \brief If the lhs type is a transparent union, check whether we
-  // can initialize the transparent union with the given expression.
-  AssignConvertType CheckTransparentUnionArgumentConstraints(QualType lhs,
-                                                             Expr *&rExpr);
-
-  // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
-  AssignConvertType CheckPointerTypesForAssignment(QualType lhsType,
-                                                   QualType rhsType);
-
-  AssignConvertType CheckObjCPointerTypesForAssignment(QualType lhsType,
-                                                       QualType rhsType);
-
-  // Helper function for CheckAssignmentConstraints involving two
-  // block pointer types.
-  AssignConvertType CheckBlockPointerTypesForAssignment(QualType lhsType,
-                                                        QualType rhsType);
-
-  bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType);
-
-  bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType);
-
-  bool PerformImplicitConversion(Expr *&From, QualType ToType,
-                                 AssignmentAction Action,
-                                 bool AllowExplicit = false);
-  bool PerformImplicitConversion(Expr *&From, QualType ToType,
-                                 AssignmentAction Action,
-                                 bool AllowExplicit,
-                                 ImplicitConversionSequence& ICS);
-  bool PerformImplicitConversion(Expr *&From, QualType ToType,
-                                 const ImplicitConversionSequence& ICS,
-                                 AssignmentAction Action,
-                                 bool IgnoreBaseAccess = false);
-  bool PerformImplicitConversion(Expr *&From, QualType ToType,
-                                 const StandardConversionSequence& SCS,
-                                 AssignmentAction Action,bool IgnoreBaseAccess);
-
-  /// the following "Check" methods will return a valid/converted QualType
-  /// or a null QualType (indicating an error diagnostic was issued).
-
-  /// type checking binary operators (subroutines of CreateBuiltinBinOp).
-  QualType InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
-  QualType CheckPointerToMemberOperands( // C++ 5.5
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isIndirect);
-  QualType CheckMultiplyDivideOperands( // C99 6.5.5
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign,
-                                       bool isDivide);
-  QualType CheckRemainderOperands( // C99 6.5.5
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  QualType CheckAdditionOperands( // C99 6.5.6
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
-  QualType CheckSubtractionOperands( // C99 6.5.6
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, QualType* CompLHSTy = 0);
-  QualType CheckShiftOperands( // C99 6.5.7
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  QualType CheckCompareOperands( // C99 6.5.8/9
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc,
-                                bool isRelational);
-  QualType CheckBitwiseOperands( // C99 6.5.[10...12]
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, bool isCompAssign = false);
-  QualType CheckLogicalOperands( // C99 6.5.[13,14]
-    Expr *&lex, Expr *&rex, SourceLocation OpLoc, unsigned Opc);
-  // CheckAssignmentOperands is used for both simple and compound assignment.
-  // For simple assignment, pass both expressions and a null converted type.
-  // For compound assignment, pass both expressions and the converted type.
-  QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
-    Expr *lex, Expr *&rex, SourceLocation OpLoc, QualType convertedType);
-  QualType CheckCommaOperands( // C99 6.5.17
-    Expr *lex, Expr *&rex, SourceLocation OpLoc);
-  QualType CheckConditionalOperands( // C99 6.5.15
-    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
-  QualType CXXCheckConditionalOperands( // C++ 5.16
-    Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
-  QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
-                                    bool *NonStandardCompositeType = 0);
-
-  QualType FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
-                                        SourceLocation questionLoc);
-
-  /// type checking for vector binary operators.
-  QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
-  QualType CheckVectorCompareOperands(Expr *&lex, Expr *&rx,
-                                      SourceLocation l, bool isRel);
-
-  /// type checking unary operators (subroutines of ActOnUnaryOp).
-  /// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
-  QualType CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc,
-                                          bool isInc, bool isPrefix);
-  QualType CheckAddressOfOperand(Expr *op, SourceLocation OpLoc);
-  QualType CheckIndirectionOperand(Expr *op, SourceLocation OpLoc);
-  QualType CheckRealImagOperand(Expr *&Op, SourceLocation OpLoc, bool isReal);
-
-  /// type checking primary expressions.
-  QualType CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
-                                   const IdentifierInfo *Comp,
-                                   SourceLocation CmpLoc);
-
-  /// type checking declaration initializers (C99 6.7.8)
-  bool CheckInitList(const InitializedEntity &Entity,
-                     InitListExpr *&InitList, QualType &DeclType);
-  bool CheckForConstantInitializer(Expr *e, QualType t);
-
-  // type checking C++ declaration initializers (C++ [dcl.init]).
-
-  /// ReferenceCompareResult - Expresses the result of comparing two
-  /// types (cv1 T1 and cv2 T2) to determine their compatibility for the
-  /// purposes of initialization by reference (C++ [dcl.init.ref]p4).
-  enum ReferenceCompareResult {
-    /// Ref_Incompatible - The two types are incompatible, so direct
-    /// reference binding is not possible.
-    Ref_Incompatible = 0,
-    /// Ref_Related - The two types are reference-related, which means
-    /// that their unqualified forms (T1 and T2) are either the same
-    /// or T1 is a base class of T2.
-    Ref_Related,
-    /// Ref_Compatible_With_Added_Qualification - The two types are
-    /// reference-compatible with added qualification, meaning that
-    /// they are reference-compatible and the qualifiers on T1 (cv1)
-    /// are greater than the qualifiers on T2 (cv2).
-    Ref_Compatible_With_Added_Qualification,
-    /// Ref_Compatible - The two types are reference-compatible and
-    /// have equivalent qualifiers (cv1 == cv2).
-    Ref_Compatible
-  };
-
-  ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc,
-                                                      QualType T1, QualType T2,
-                                                      bool& DerivedToBase);
-
-  /// CheckCastTypes - Check type constraints for casting between types under
-  /// C semantics, or forward to CXXCheckCStyleCast in C++.
-  bool CheckCastTypes(SourceRange TyRange, QualType CastTy, Expr *&CastExpr,
-                      CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath,
-                      bool FunctionalStyle = false);
-
-  // CheckVectorCast - check type constraints for vectors.
-  // Since vectors are an extension, there are no C standard reference for this.
-  // We allow casting between vectors and integer datatypes of the same size.
-  // returns true if the cast is invalid
-  bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
-                       CastExpr::CastKind &Kind);
-
-  // CheckExtVectorCast - check type constraints for extended vectors.
-  // Since vectors are an extension, there are no C standard reference for this.
-  // We allow casting between vectors and integer datatypes of the same size,
-  // or vectors and the element type of that vector.
-  // returns true if the cast is invalid
-  bool CheckExtVectorCast(SourceRange R, QualType VectorTy, Expr *&CastExpr,
-                          CastExpr::CastKind &Kind);
-
-  /// CXXCheckCStyleCast - Check constraints of a C-style or function-style
-  /// cast under C++ semantics.
-  bool CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
-                          CastExpr::CastKind &Kind,
-                          CXXBaseSpecifierArray &BasePath,
-                          bool FunctionalStyle);
-
-  /// CheckMessageArgumentTypes - Check types in an Obj-C message send.
-  /// \param Method - May be null.
-  /// \param [out] ReturnType - The return type of the send.
-  /// \return true iff there were any incompatible types.
-  bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel,
-                                 ObjCMethodDecl *Method, bool isClassMessage,
-                                 SourceLocation lbrac, SourceLocation rbrac,
-                                 QualType &ReturnType);
-
-  /// CheckBooleanCondition - Diagnose problems involving the use of
-  /// the given expression as a boolean condition (e.g. in an if
-  /// statement).  Also performs the standard function and array
-  /// decays, possibly changing the input variable.
-  ///
-  /// \param Loc - A location associated with the condition, e.g. the
-  /// 'if' keyword.
-  /// \return true iff there were any errors
-  bool CheckBooleanCondition(Expr *&CondExpr, SourceLocation Loc);
-
-  virtual OwningExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,
-                                                 ExprArg SubExpr);
-  
-  /// DiagnoseAssignmentAsCondition - Given that an expression is
-  /// being used as a boolean condition, warn if it's an assignment.
-  void DiagnoseAssignmentAsCondition(Expr *E);
-
-  /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
-  bool CheckCXXBooleanCondition(Expr *&CondExpr);
-
-  /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have
-  /// the specified width and sign.  If an overflow occurs, detect it and emit
-  /// the specified diagnostic.
-  void ConvertIntegerToTypeWarnOnOverflow(llvm::APSInt &OldVal,
-                                          unsigned NewWidth, bool NewSign,
-                                          SourceLocation Loc, unsigned DiagID);
-
-  /// Checks that the Objective-C declaration is declared in the global scope.
-  /// Emits an error and marks the declaration as invalid if it's not declared
-  /// in the global scope.
-  bool CheckObjCDeclScope(Decl *D);
-
-  void InitBuiltinVaListType();
-
-  /// VerifyIntegerConstantExpression - verifies that an expression is an ICE,
-  /// and reports the appropriate diagnostics. Returns false on success.
-  /// Can optionally return the value of the expression.
-  bool VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result = 0);
-
-  /// VerifyBitField - verifies that a bit field expression is an ICE and has
-  /// the correct width, and that the field type is valid.
-  /// Returns false on success.
-  /// Can optionally return whether the bit-field is of width 0
-  bool VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
-                      QualType FieldTy, const Expr *BitWidth,
-                      bool *ZeroWidth = 0);
-
-  /// \name Code completion
-  //@{
-  virtual void CodeCompleteOrdinaryName(Scope *S,
-                                     CodeCompletionContext CompletionContext);
-  virtual void CodeCompleteExpression(Scope *S, QualType T);
-  virtual void CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *Base,
-                                               SourceLocation OpLoc,
-                                               bool IsArrow);
-  virtual void CodeCompleteTag(Scope *S, unsigned TagSpec);
-  virtual void CodeCompleteCase(Scope *S);
-  virtual void CodeCompleteCall(Scope *S, ExprTy *Fn,
-                                ExprTy **Args, unsigned NumArgs);
-  virtual void CodeCompleteInitializer(Scope *S, DeclPtrTy D);
-  virtual void CodeCompleteReturn(Scope *S);
-  virtual void CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS);
-  
-  virtual void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
-                                       bool EnteringContext);
-  virtual void CodeCompleteUsing(Scope *S);
-  virtual void CodeCompleteUsingDirective(Scope *S);
-  virtual void CodeCompleteNamespaceDecl(Scope *S);
-  virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
-  virtual void CodeCompleteOperatorName(Scope *S);
-
-  virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
-                                           bool InInterface);
-  virtual void CodeCompleteObjCAtVisibility(Scope *S);
-  virtual void CodeCompleteObjCAtStatement(Scope *S);
-  virtual void CodeCompleteObjCAtExpression(Scope *S);
-  virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
-  virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
-                                              DeclPtrTy *Methods,
-                                              unsigned NumMethods);
-  virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
-                                              DeclPtrTy *Methods,
-                                              unsigned NumMethods);
-  virtual void CodeCompleteObjCMessageReceiver(Scope *S);
-  virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
-                                            IdentifierInfo **SelIdents,
-                                            unsigned NumSelIdents);
-  virtual void CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
-                                            IdentifierInfo **SelIdents,
-                                            unsigned NumSelIdents);
-  virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
-                                               IdentifierInfo **SelIdents,
-                                               unsigned NumSelIdents);
-  virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
-                                                  unsigned NumProtocols);
-  virtual void CodeCompleteObjCProtocolDecl(Scope *S);
-  virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
-  virtual void CodeCompleteObjCSuperclass(Scope *S,
-                                          IdentifierInfo *ClassName,
-                                          SourceLocation ClassNameLoc);
-  virtual void CodeCompleteObjCImplementationDecl(Scope *S);
-  virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
-                                                 IdentifierInfo *ClassName,
-                                                 SourceLocation ClassNameLoc);
-  virtual void CodeCompleteObjCImplementationCategory(Scope *S,
-                                                  IdentifierInfo *ClassName,
-                                                  SourceLocation ClassNameLoc);
-  virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
-                                                  DeclPtrTy ObjCImpDecl);
-  virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
-                                                  IdentifierInfo *PropertyName,
-                                                      DeclPtrTy ObjCImpDecl);
-  virtual void CodeCompleteObjCMethodDecl(Scope *S,
-                                          bool IsInstanceMethod,
-                                          TypeTy *ReturnType,
-                                          DeclPtrTy IDecl);
-  virtual void CodeCompleteObjCMethodDeclSelector(Scope *S, 
-                                                  bool IsInstanceMethod,
-                                                  bool AtParameterName,
-                                                  TypeTy *ReturnType,
-                                                  IdentifierInfo **SelIdents,
-                                                  unsigned NumSelIdents);
-  
-  //@}
-
-  //===--------------------------------------------------------------------===//
-  // Extra semantic analysis beyond the C type system
-
-public:
-  SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
-                                                unsigned ByteNo) const;
-
-private:
-  bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
-  bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);
-
-  bool CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall);
-  bool CheckObjCString(Expr *Arg);
-
-  Action::OwningExprResult CheckBuiltinFunctionCall(unsigned BuiltinID,
-                                                    CallExpr *TheCall);
-  bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-  bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall);
-
-  bool SemaBuiltinVAStart(CallExpr *TheCall);
-  bool SemaBuiltinUnorderedCompare(CallExpr *TheCall);
-  bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs);
-
-public:
-  // Used by C++ template instantiation.
-  Action::OwningExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
-
-private:
-  bool SemaBuiltinPrefetch(CallExpr *TheCall);
-  bool SemaBuiltinObjectSize(CallExpr *TheCall);
-  bool SemaBuiltinLongjmp(CallExpr *TheCall);
-  OwningExprResult SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult);
-  bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
-                              llvm::APSInt &Result);
-  bool SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
-                              bool HasVAListArg, unsigned format_idx,
-                              unsigned firstDataArg);
-  void CheckPrintfString(const StringLiteral *FExpr, const Expr *OrigFormatExpr,
-                         const CallExpr *TheCall, bool HasVAListArg,
-                         unsigned format_idx, unsigned firstDataArg);
-  void CheckNonNullArguments(const NonNullAttr *NonNull,
-                             const CallExpr *TheCall);
-  void CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
-                            unsigned format_idx, unsigned firstDataArg);
-  void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
-                            SourceLocation ReturnLoc);
-  void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
-  void CheckImplicitConversions(Expr *E);
-};
-
-//===--------------------------------------------------------------------===//
-// Typed version of Parser::ExprArg (smart pointer for wrapping Expr pointers).
-template <typename T>
-class ExprOwningPtr : public Action::ExprArg {
-public:
-  ExprOwningPtr(Sema *S, T *expr) : Action::ExprArg(*S, expr) {}
-
-  void reset(T* p) { Action::ExprArg::operator=(p); }
-  T* get() const { return static_cast<T*>(Action::ExprArg::get()); }
-  T* take() { return static_cast<T*>(Action::ExprArg::take()); }
-  T* release() { return take(); }
-
-  T& operator*() const { return *get(); }
-  T* operator->() const { return get(); }
-};
-
-}  // end namespace clang
-
-#endif
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index e110e3d..e629f0f 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -11,9 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DelayedDiagnostic.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclCXX.h"
@@ -22,6 +23,7 @@
 #include "clang/AST/ExprCXX.h"
 
 using namespace clang;
+using namespace sema;
 
 /// A copy of Sema's enum without AR_delayed.
 enum AccessResult {
@@ -132,10 +134,10 @@ struct EffectiveContext {
   bool Dependent;
 };
 
-/// Like Sema's AccessedEntity, but kindly lets us scribble all over
+/// Like sema:;AccessedEntity, but kindly lets us scribble all over
 /// it.
-struct AccessTarget : public Sema::AccessedEntity {
-  AccessTarget(const Sema::AccessedEntity &Entity)
+struct AccessTarget : public AccessedEntity {
+  AccessTarget(const AccessedEntity &Entity)
     : AccessedEntity(Entity) {
     initialize();
   }
@@ -562,6 +564,130 @@ static AccessResult GetFriendKind(Sema &S,
   return OnFailure;
 }
 
+namespace {
+
+/// A helper class for checking for a friend which will grant access
+/// to a protected instance member.
+struct ProtectedFriendContext {
+  Sema &S;
+  const EffectiveContext &EC;
+  const CXXRecordDecl *NamingClass;
+  bool CheckDependent;
+  bool EverDependent;
+
+  /// The path down to the current base class.
+  llvm::SmallVector<const CXXRecordDecl*, 20> CurPath;
+
+  ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
+                         const CXXRecordDecl *InstanceContext,
+                         const CXXRecordDecl *NamingClass)
+    : S(S), EC(EC), NamingClass(NamingClass),
+      CheckDependent(InstanceContext->isDependentContext() ||
+                     NamingClass->isDependentContext()),
+      EverDependent(false) {}
+
+  /// Check classes in the current path for friendship, starting at
+  /// the given index.
+  bool checkFriendshipAlongPath(unsigned I) {
+    assert(I < CurPath.size());
+    for (unsigned E = CurPath.size(); I != E; ++I) {
+      switch (GetFriendKind(S, EC, CurPath[I])) {
+      case AR_accessible:   return true;
+      case AR_inaccessible: continue;
+      case AR_dependent:    EverDependent = true; continue;
+      }
+    }
+    return false;
+  }
+
+  /// Perform a search starting at the given class.
+  ///
+  /// PrivateDepth is the index of the last (least derived) class
+  /// along the current path such that a notional public member of
+  /// the final class in the path would have access in that class.
+  bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
+    // If we ever reach the naming class, check the current path for
+    // friendship.  We can also stop recursing because we obviously
+    // won't find the naming class there again.
+    if (Cur == NamingClass)
+      return checkFriendshipAlongPath(PrivateDepth);
+
+    if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
+      EverDependent = true;
+
+    // Recurse into the base classes.
+    for (CXXRecordDecl::base_class_const_iterator
+           I = Cur->bases_begin(), E = Cur->bases_end(); I != E; ++I) {
+
+      // If this is private inheritance, then a public member of the
+      // base will not have any access in classes derived from Cur.
+      unsigned BasePrivateDepth = PrivateDepth;
+      if (I->getAccessSpecifier() == AS_private)
+        BasePrivateDepth = CurPath.size() - 1;
+
+      const CXXRecordDecl *RD;
+
+      QualType T = I->getType();
+      if (const RecordType *RT = T->getAs<RecordType>()) {
+        RD = cast<CXXRecordDecl>(RT->getDecl());
+      } else if (const InjectedClassNameType *IT
+                   = T->getAs<InjectedClassNameType>()) {
+        RD = IT->getDecl();
+      } else {
+        assert(T->isDependentType() && "non-dependent base wasn't a record?");
+        EverDependent = true;
+        continue;
+      }
+
+      // Recurse.  We don't need to clean up if this returns true.
+      CurPath.push_back(RD);
+      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
+        return true;
+      CurPath.pop_back();
+    }
+
+    return false;
+  }
+
+  bool findFriendship(const CXXRecordDecl *Cur) {
+    assert(CurPath.empty());
+    CurPath.push_back(Cur);
+    return findFriendship(Cur, 0);
+  }
+};
+}
+
+/// Search for a class P that EC is a friend of, under the constraint
+///   InstanceContext <= P <= NamingClass
+/// and with the additional restriction that a protected member of
+/// NamingClass would have some natural access in P.
+///
+/// That second condition isn't actually quite right: the condition in
+/// the standard is whether the target would have some natural access
+/// in P.  The difference is that the target might be more accessible
+/// along some path not passing through NamingClass.  Allowing that
+/// introduces two problems:
+///   - It breaks encapsulation because you can suddenly access a
+///     forbidden base class's members by subclassing it elsewhere.
+///   - It makes access substantially harder to compute because it
+///     breaks the hill-climbing algorithm: knowing that the target is
+///     accessible in some base class would no longer let you change
+///     the question solely to whether the base class is accessible,
+///     because the original target might have been more accessible
+///     because of crazy subclassing.
+/// So we don't implement that.
+static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
+                                           const CXXRecordDecl *InstanceContext,
+                                           const CXXRecordDecl *NamingClass) {
+  assert(InstanceContext->getCanonicalDecl() == InstanceContext);
+  assert(NamingClass->getCanonicalDecl() == NamingClass);
+
+  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
+  if (PRC.findFriendship(InstanceContext)) return AR_accessible;
+  if (PRC.EverDependent) return AR_dependent;
+  return AR_inaccessible;
+}
+
 static AccessResult HasAccess(Sema &S,
                               const EffectiveContext &EC,
                               const CXXRecordDecl *NamingClass,
@@ -629,20 +755,25 @@ static AccessResult HasAccess(Sema &S,
     }
   }
 
-  if (!NamingClass->hasFriends())
-    return OnFailure;
-
-  // Don't consider friends if we're under the [class.protected]
-  // restriction, above.
+  // [M3] and [B3] say that, if the target is protected in N, we grant
+  // access if the access occurs in a friend or member of some class P
+  // that's a subclass of N and where the target has some natural
+  // access in P.  The 'member' aspect is easy to handle because P
+  // would necessarily be one of the effective-context records, and we
+  // address that above.  The 'friend' aspect is completely ridiculous
+  // to implement because there are no restrictions at all on P
+  // *unless* the [class.protected] restriction applies.  If it does,
+  // however, we should ignore whether the naming class is a friend,
+  // and instead rely on whether any potential P is a friend.
   if (Access == AS_protected && Target.hasInstanceContext()) {
     const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
     if (!InstanceContext) return AR_dependent;
-
-    switch (IsDerivedFromInclusive(InstanceContext, NamingClass)) {
-    case AR_accessible: break;
+    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
+    case AR_accessible: return AR_accessible;
     case AR_inaccessible: return OnFailure;
     case AR_dependent: return AR_dependent;
     }
+    llvm_unreachable("impossible friendship kind");
   }
 
   switch (GetFriendKind(S, EC, NamingClass)) {
@@ -799,6 +930,57 @@ static CXXBasePath *FindBestPath(Sema &S,
   return BestPath;
 }
 
+/// Given that an entity has protected natural access, check whether
+/// access might be denied because of the protected member access
+/// restriction.
+///
+/// \return true if a note was emitted
+static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
+                                       AccessTarget &Target) {
+  // Only applies to instance accesses.
+  if (!Target.hasInstanceContext())
+    return false;
+  assert(Target.isMemberAccess());
+  NamedDecl *D = Target.getTargetDecl();
+
+  const CXXRecordDecl *DeclaringClass = Target.getDeclaringClass();
+  DeclaringClass = DeclaringClass->getCanonicalDecl();
+
+  for (EffectiveContext::record_iterator
+         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
+    const CXXRecordDecl *ECRecord = *I;
+    switch (IsDerivedFromInclusive(ECRecord, DeclaringClass)) {
+    case AR_accessible: break;
+    case AR_inaccessible: continue;
+    case AR_dependent: continue;
+    }
+
+    // The effective context is a subclass of the declaring class.
+    // If that class isn't a superclass of the instance context,
+    // then the [class.protected] restriction applies.
+
+    // To get this exactly right, this might need to be checked more
+    // holistically;  it's not necessarily the case that gaining
+    // access here would grant us access overall.
+
+    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
+    assert(InstanceContext && "diagnosing dependent access");
+
+    switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
+    case AR_accessible: continue;
+    case AR_dependent: continue;
+    case AR_inaccessible:
+      S.Diag(D->getLocation(), diag::note_access_protected_restricted)
+        << (InstanceContext != Target.getNamingClass()->getCanonicalDecl())
+        << S.Context.getTypeDeclType(InstanceContext)
+        << S.Context.getTypeDeclType(ECRecord);
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /// Diagnose the path which caused the given declaration or base class
 /// to become inaccessible.
 static void DiagnoseAccessPath(Sema &S,
@@ -817,6 +999,10 @@ static void DiagnoseAccessPath(Sema &S,
   if (D && (Access == D->getAccess() || D->getAccess() == AS_private)) {
     switch (HasAccess(S, EC, DeclaringClass, D->getAccess(), Entity)) {
     case AR_inaccessible: {
+      if (Access == AS_protected &&
+          TryDiagnoseProtectedAccess(S, EC, Entity))
+        return;
+
       S.Diag(D->getLocation(), diag::note_access_natural)
         << (unsigned) (Access == AS_protected)
         << /*FIXME: not implicitly*/ 0;
@@ -1033,7 +1219,7 @@ static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
   // access control.
   if (S.CurContext->isFileContext() && S.ParsingDeclDepth) {
     S.DelayedDiagnostics.push_back(
-        Sema::DelayedDiagnostic::makeAccess(Loc, Entity));
+        DelayedDiagnostic::makeAccess(Loc, Entity));
     return Sema::AR_delayed;
   }
 
@@ -1266,7 +1452,7 @@ Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
       Found.getAccess() == AS_public)
     return AR_accessible;
 
-  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).getPointer();
+  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
   CXXRecordDecl *NamingClass = Ovl->getNamingClass();
 
   AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index 69f27b0..0921156 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -12,8 +12,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/AST/Attr.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
@@ -62,18 +63,30 @@ namespace {
     /// alignment to the previous value. If \arg Name is non-zero then
     /// the first such named record is popped, otherwise the top record
     /// is popped. Returns true if the pop succeeded.
-    bool pop(IdentifierInfo *Name);
+    bool pop(IdentifierInfo *Name, bool IsReset);
   };
 }  // end anonymous namespace.
 
-bool PragmaPackStack::pop(IdentifierInfo *Name) {
-  if (Stack.empty())
-    return false;
-
+bool PragmaPackStack::pop(IdentifierInfo *Name, bool IsReset) {
   // If name is empty just pop top.
   if (!Name) {
-    Alignment = Stack.back().Alignment;
-    Stack.pop_back();
+    // An empty stack is a special case...
+    if (Stack.empty()) {
+      // If this isn't a reset, it is always an error.
+      if (!IsReset)
+        return false;
+
+      // Otherwise, it is an error only if some alignment has been set.
+      if (!Alignment)
+        return false;
+
+      // Otherwise, reset to the default alignment.
+      Alignment = 0;
+    } else {
+      Alignment = Stack.back().Alignment;
+      Stack.pop_back();
+    }
+
     return true;
   }
 
@@ -108,9 +121,11 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
   // Otherwise, check to see if we need a max field alignment attribute.
   if (unsigned Alignment = Stack->getAlignment()) {
     if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
-      RD->addAttr(::new (Context) AlignMac68kAttr());
+      RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
     else
-      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
+      RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
+                                                        Context,
+                                                        Alignment * 8));
   }
 }
 
@@ -122,13 +137,10 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
 
   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
 
-  // Reset just pops the top of the stack.
-  if (Kind == Action::POAK_Reset) {
-    // Do the pop.
-    if (!Context->pop(0)) {
-      // If a name was specified then failure indicates the name
-      // wasn't found. Otherwise failure indicates the stack was
-      // empty.
+  // Reset just pops the top of the stack, or resets the current alignment to
+  // default.
+  if (Kind == Sema::POAK_Reset) {
+    if (!Context->pop(0, /*IsReset=*/true)) {
       Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
         << "stack empty";
     }
@@ -188,7 +200,6 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
         !(Val == 0 || Val.isPowerOf2()) ||
         Val.getZExtValue() > 16) {
       Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
-      Alignment->Destroy(Context);
       return; // Ignore
     }
 
@@ -201,11 +212,11 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
   PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
 
   switch (Kind) {
-  case Action::PPK_Default: // pack([n])
+  case Sema::PPK_Default: // pack([n])
     Context->setAlignment(AlignmentVal);
     break;
 
-  case Action::PPK_Show: // pack(show)
+  case Sema::PPK_Show: // pack(show)
     // Show the current alignment, making sure to show the right value
     // for the default.
     AlignmentVal = Context->getAlignment();
@@ -218,21 +229,21 @@ void Sema::ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name,
       Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
     break;
 
-  case Action::PPK_Push: // pack(push [, id] [, [n])
+  case Sema::PPK_Push: // pack(push [, id] [, [n])
     Context->push(Name);
     // Set the new alignment if specified.
     if (Alignment)
       Context->setAlignment(AlignmentVal);
     break;
 
-  case Action::PPK_Pop: // pack(pop [, id] [,  n])
+  case Sema::PPK_Pop: // pack(pop [, id] [,  n])
     // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
     // "#pragma pack(pop, identifier, n) is undefined"
     if (Alignment && Name)
       Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment);
 
     // Do the pop.
-    if (!Context->pop(Name)) {
+    if (!Context->pop(Name, /*IsReset=*/false)) {
       // If a name was specified then failure indicates the name
       // wasn't found. Otherwise failure indicates the stack was
       // empty.
@@ -277,6 +288,80 @@ void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
       continue;
     }
 
-    VD->addAttr(::new (Context) UnusedAttr());
+    VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
+  }
+}
+
+typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
+                              SourceLocation> > VisStack;
+
+void Sema::AddPushedVisibilityAttribute(Decl *D) {
+  if (!VisContext)
+    return;
+
+  if (D->hasAttr<VisibilityAttr>())
+    return;
+
+  VisStack *Stack = static_cast<VisStack*>(VisContext);
+  VisibilityAttr::VisibilityType type = Stack->back().first;
+  SourceLocation loc = Stack->back().second;
+
+  D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
+}
+
+/// FreeVisContext - Deallocate and null out VisContext.
+void Sema::FreeVisContext() {
+  delete static_cast<VisStack*>(VisContext);
+  VisContext = 0;
+}
+
+static void PushPragmaVisibility(Sema &S, VisibilityAttr::VisibilityType type,
+                                 SourceLocation loc) {
+  // Put visibility on stack.
+  if (!S.VisContext)
+    S.VisContext = new VisStack;
+
+  VisStack *Stack = static_cast<VisStack*>(S.VisContext);
+  Stack->push_back(std::make_pair(type, loc));
+}
+
+void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+                                 SourceLocation PragmaLoc) {
+  if (IsPush) {
+    // Compute visibility to use.
+    VisibilityAttr::VisibilityType type;
+    if (VisType->isStr("default"))
+      type = VisibilityAttr::Default;
+    else if (VisType->isStr("hidden"))
+      type = VisibilityAttr::Hidden;
+    else if (VisType->isStr("internal"))
+      type = VisibilityAttr::Hidden; // FIXME
+    else if (VisType->isStr("protected"))
+      type = VisibilityAttr::Protected;
+    else {
+      Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
+        VisType->getName();
+      return;
+    }
+    PushPragmaVisibility(*this, type, PragmaLoc);
+  } else {
+    PopPragmaVisibility();
+  }
+}
+
+void Sema::PushVisibilityAttr(const VisibilityAttr *Attr) {
+  PushPragmaVisibility(*this, Attr->getVisibility(), Attr->getLocation());
+}
+
+void Sema::PopPragmaVisibility() {
+  // Pop visibility from stack, if there is one on the stack.
+  if (VisContext) {
+    VisStack *Stack = static_cast<VisStack*>(VisContext);
+
+    Stack->pop_back();
+    // To simplify the implementation, never keep around an empty stack.
+    if (Stack->empty())
+      FreeVisContext();
   }
+  // FIXME: Add diag for pop without push.
 }
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index b8e27e7..21b1a73 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -11,8 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -43,16 +43,16 @@ static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                                  const SourceRange &OpRange,
                                  const SourceRange &DestRange,
-                                 CastExpr::CastKind &Kind);
+                                 CastKind &Kind);
 static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                             const SourceRange &OpRange,
-                            CastExpr::CastKind &Kind,
-                            CXXBaseSpecifierArray &BasePath);
+                            CastKind &Kind,
+                            CXXCastPath &BasePath);
 static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                              const SourceRange &OpRange,
                              const SourceRange &DestRange,
-                             CastExpr::CastKind &Kind,
-                             CXXBaseSpecifierArray &BasePath);
+                             CastKind &Kind,
+                             CXXCastPath &BasePath);
 
 static bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType);
 
@@ -73,54 +73,54 @@ static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr,
                                                QualType DestType, bool CStyle,
                                                const SourceRange &OpRange,
                                                unsigned &msg,
-                                               CastExpr::CastKind &Kind,
-                                               CXXBaseSpecifierArray &BasePath);
+                                               CastKind &Kind,
+                                               CXXCastPath &BasePath);
 static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType,
                                               QualType DestType, bool CStyle,
                                               const SourceRange &OpRange,
                                               unsigned &msg,
-                                              CastExpr::CastKind &Kind,
-                                              CXXBaseSpecifierArray &BasePath);
+                                              CastKind &Kind,
+                                              CXXCastPath &BasePath);
 static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType,
                                        CanQualType DestType, bool CStyle,
                                        const SourceRange &OpRange,
                                        QualType OrigSrcType,
                                        QualType OrigDestType, unsigned &msg,
-                                       CastExpr::CastKind &Kind,
-                                       CXXBaseSpecifierArray &BasePath);
+                                       CastKind &Kind,
+                                       CXXCastPath &BasePath);
 static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr,
                                                QualType SrcType,
                                                QualType DestType,bool CStyle,
                                                const SourceRange &OpRange,
                                                unsigned &msg,
-                                               CastExpr::CastKind &Kind,
-                                               CXXBaseSpecifierArray &BasePath);
+                                               CastKind &Kind,
+                                               CXXCastPath &BasePath);
 
 static TryCastResult TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr,
                                            QualType DestType, bool CStyle,
                                            const SourceRange &OpRange,
                                            unsigned &msg,
-                                           CastExpr::CastKind &Kind);
+                                           CastKind &Kind);
 static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
                                    QualType DestType, bool CStyle,
                                    const SourceRange &OpRange,
                                    unsigned &msg,
-                                   CastExpr::CastKind &Kind,
-                                   CXXBaseSpecifierArray &BasePath);
+                                   CastKind &Kind,
+                                   CXXCastPath &BasePath);
 static TryCastResult TryConstCast(Sema &Self, Expr *SrcExpr, QualType DestType,
                                   bool CStyle, unsigned &msg);
 static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
                                         QualType DestType, bool CStyle,
                                         const SourceRange &OpRange,
                                         unsigned &msg,
-                                        CastExpr::CastKind &Kind);
+                                        CastKind &Kind);
 
 /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
-                        SourceLocation LAngleBracketLoc, TypeTy *Ty,
+                        SourceLocation LAngleBracketLoc, ParsedType Ty,
                         SourceLocation RAngleBracketLoc,
-                        SourceLocation LParenLoc, ExprArg E,
+                        SourceLocation LParenLoc, Expr *E,
                         SourceLocation RParenLoc) {
   
   TypeSourceInfo *DestTInfo;
@@ -133,11 +133,10 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
                            SourceRange(LParenLoc, RParenLoc));
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
-                        TypeSourceInfo *DestTInfo, ExprArg E,
+                        TypeSourceInfo *DestTInfo, Expr *Ex,
                         SourceRange AngleBrackets, SourceRange Parens) {
-  Expr *Ex = E.takeAs<Expr>();
   QualType DestType = DestTInfo->getType();
 
   SourceRange OpRange(OpLoc, Parens.getEnd());
@@ -153,39 +152,39 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
   case tok::kw_const_cast:
     if (!TypeDependent)
       CheckConstCast(*this, Ex, DestType, OpRange, DestRange);
-    return Owned(new (Context) CXXConstCastExpr(
+    return Owned(CXXConstCastExpr::Create(Context,
                                         DestType.getNonLValueExprType(Context),
-                                                Ex, DestTInfo, OpLoc));
+                                          Ex, DestTInfo, OpLoc));
 
   case tok::kw_dynamic_cast: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (!TypeDependent)
       CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath);
-    return Owned(new (Context)CXXDynamicCastExpr(
+    return Owned(CXXDynamicCastExpr::Create(Context,
                                           DestType.getNonLValueExprType(Context),
-                                                 Kind, Ex, BasePath, DestTInfo,
-                                                 OpLoc));
+                                            Kind, Ex, &BasePath, DestTInfo,
+                                            OpLoc));
   }
   case tok::kw_reinterpret_cast: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CastKind Kind = CK_Unknown;
     if (!TypeDependent)
       CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind);
-    return Owned(new (Context) CXXReinterpretCastExpr(
+    return Owned(CXXReinterpretCastExpr::Create(Context,
                                   DestType.getNonLValueExprType(Context),
-                                  Kind, Ex, CXXBaseSpecifierArray(), 
+                                  Kind, Ex, 0,
                                   DestTInfo, OpLoc));
   }
   case tok::kw_static_cast: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (!TypeDependent)
       CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath);
     
-    return Owned(new (Context) CXXStaticCastExpr(
+    return Owned(CXXStaticCastExpr::Create(Context,
                                          DestType.getNonLValueExprType(Context),
-                                                 Kind, Ex, BasePath,
-                                                 DestTInfo, OpLoc));
+                                           Kind, Ex, &BasePath,
+                                           DestTInfo, OpLoc));
   }
   }
 
@@ -197,7 +196,7 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
 /// the same kind of pointer (plain or to-member). Unlike the Sema function,
 /// this one doesn't care if the two pointers-to-member don't point into the
 /// same class. This is because CastsAwayConstness doesn't care.
-bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
+static bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
   const PointerType *T1PtrType = T1->getAs<PointerType>(),
                     *T2PtrType = T2->getAs<PointerType>();
   if (T1PtrType && T2PtrType) {
@@ -307,8 +306,8 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
 static void
 CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                  const SourceRange &OpRange,
-                 const SourceRange &DestRange, CastExpr::CastKind &Kind,
-                 CXXBaseSpecifierArray &BasePath) {
+                 const SourceRange &DestRange, CastKind &Kind,
+                 CXXCastPath &BasePath) {
   QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
   DestType = Self.Context.getCanonicalType(DestType);
 
@@ -396,6 +395,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
   // C++ 5.2.7p3: If the type of v is the same as the required result type,
   //   [except for cv].
   if (DestRecord == SrcRecord) {
+    Kind = CK_NoOp;
     return;
   }
 
@@ -407,7 +407,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                                            &BasePath))
         return;
         
-    Kind = CastExpr::CK_DerivedToBase;
+    Kind = CK_DerivedToBase;
 
     // If we are casting to or through a virtual base class, we need a
     // vtable.
@@ -428,7 +428,7 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                       cast<CXXRecordDecl>(SrcRecord->getDecl()));
 
   // Done. Everything else is run-time checks.
-  Kind = CastExpr::CK_Dynamic;
+  Kind = CK_Dynamic;
 }
 
 /// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
@@ -457,7 +457,7 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 void
 CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                      const SourceRange &OpRange, const SourceRange &DestRange,
-                     CastExpr::CastKind &Kind) {
+                     CastKind &Kind) {
   if (!DestType->isLValueReferenceType())
     Self.DefaultFunctionArrayLvalueConversion(SrcExpr);
 
@@ -475,13 +475,13 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 /// implicit conversions explicit and getting rid of data loss warnings.
 void
 CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
-                const SourceRange &OpRange, CastExpr::CastKind &Kind,
-                CXXBaseSpecifierArray &BasePath) {
+                const SourceRange &OpRange, CastKind &Kind,
+                CXXCastPath &BasePath) {
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
   if (DestType->isVoidType()) {
-    Kind = CastExpr::CK_ToVoid;
+    Kind = CK_ToVoid;
     return;
   }
 
@@ -493,6 +493,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                     Kind, BasePath) != TC_Success && msg != 0)
     Self.Diag(OpRange.getBegin(), msg) << CT_Static
       << SrcExpr->getType() << DestType << OpRange;
+  else if (Kind == CK_Unknown || Kind == CK_BitCast)
+    Self.CheckCastAlign(SrcExpr, DestType, OpRange);
 }
 
 /// TryStaticCast - Check if a static cast can be performed, and do so if
@@ -501,8 +503,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
 static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
                                    QualType DestType, bool CStyle,
                                    const SourceRange &OpRange, unsigned &msg,
-                                   CastExpr::CastKind &Kind,
-                                   CXXBaseSpecifierArray &BasePath) {
+                                   CastKind &Kind,
+                                   CXXCastPath &BasePath) {
   // The order the tests is not entirely arbitrary. There is one conversion
   // that can be handled in two different ways. Given:
   // struct A {};
@@ -532,7 +534,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
   //   reference to cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1".
   tcr = TryLValueToRValueCast(Self, SrcExpr, DestType, msg);
   if (tcr != TC_NotApplicable) {
-    Kind = CastExpr::CK_NoOp;
+    Kind = CK_NoOp;
     return tcr;
   }
 
@@ -567,7 +569,7 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
     if (SrcType->isComplexType() || SrcType->isVectorType()) {
       // Fall through - these cannot be converted.
     } else if (SrcType->isArithmeticType() || SrcType->isEnumeralType()) {
-      Kind = CastExpr::CK_IntegralCast;
+      Kind = CK_IntegralCast;
       return TC_Success;
     }
   }
@@ -602,19 +604,19 @@ static TryCastResult TryStaticCast(Sema &Self, Expr *&SrcExpr,
             msg = diag::err_bad_cxx_cast_const_away;
             return TC_Failed;
           }
-          Kind = CastExpr::CK_BitCast;
+          Kind = CK_BitCast;
           return TC_Success;
         }
       }
       else if (DestType->isObjCObjectPointerType()) {
         // allow both c-style cast and static_cast of objective-c pointers as 
         // they are pervasive.
-        Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+        Kind = CK_AnyPointerToObjCPointerCast;
         return TC_Success;
       }
       else if (CStyle && DestType->isBlockPointerType()) {
         // allow c-style cast of void * to block pointers.
-        Kind = CastExpr::CK_AnyPointerToBlockPointerCast;
+        Kind = CK_AnyPointerToBlockPointerCast;
         return TC_Success;
       }
     }
@@ -645,9 +647,10 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
   // this is the only cast possibility, so we issue an error if we fail now.
   // FIXME: Should allow casting away constness if CStyle.
   bool DerivedToBase;
+  bool ObjCConversion;
   if (Self.CompareReferenceRelationship(SrcExpr->getLocStart(),
                                         SrcExpr->getType(), R->getPointeeType(),
-                                        DerivedToBase) <
+                                        DerivedToBase, ObjCConversion) <
         Sema::Ref_Compatible_With_Added_Qualification) {
     msg = diag::err_bad_lvalue_to_rvalue_cast;
     return TC_Failed;
@@ -662,8 +665,8 @@ TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType,
 TryCastResult
 TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
                            bool CStyle, const SourceRange &OpRange,
-                           unsigned &msg, CastExpr::CastKind &Kind,
-                           CXXBaseSpecifierArray &BasePath) {
+                           unsigned &msg, CastKind &Kind,
+                           CXXCastPath &BasePath) {
   // C++ 5.2.9p5: An lvalue of type "cv1 B", where B is a class type, can be
   //   cast to type "reference to cv2 D", where D is a class derived from B,
   //   if a valid standard conversion from "pointer to D" to "pointer to B"
@@ -697,8 +700,8 @@ TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType,
 TryCastResult
 TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType,
                          bool CStyle, const SourceRange &OpRange,
-                         unsigned &msg, CastExpr::CastKind &Kind,
-                         CXXBaseSpecifierArray &BasePath) {
+                         unsigned &msg, CastKind &Kind,
+                         CXXCastPath &BasePath) {
   // C++ 5.2.9p8: An rvalue of type "pointer to cv1 B", where B is a class
   //   type, can be converted to an rvalue of type "pointer to cv2 D", where D
   //   is a class derived from B, if a valid standard conversion from "pointer
@@ -732,7 +735,7 @@ TryCastResult
 TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
                   bool CStyle, const SourceRange &OpRange, QualType OrigSrcType,
                   QualType OrigDestType, unsigned &msg, 
-                  CastExpr::CastKind &Kind, CXXBaseSpecifierArray &BasePath) {
+                  CastKind &Kind, CXXCastPath &BasePath) {
   // We can only work with complete types. But don't complain if it doesn't work
   if (Self.RequireCompleteType(OpRange.getBegin(), SrcType, Self.PDiag(0)) ||
       Self.RequireCompleteType(OpRange.getBegin(), DestType, Self.PDiag(0)))
@@ -824,7 +827,7 @@ TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType,
   }
 
   Self.BuildBasePathArray(Paths, BasePath);
-  Kind = CastExpr::CK_BaseToDerived;
+  Kind = CK_BaseToDerived;
   return TC_Success;
 }
 
@@ -839,8 +842,8 @@ TryCastResult
 TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType, 
                              QualType DestType, bool CStyle, 
                              const SourceRange &OpRange,
-                             unsigned &msg, CastExpr::CastKind &Kind,
-                             CXXBaseSpecifierArray &BasePath) {
+                             unsigned &msg, CastKind &Kind,
+                             CXXCastPath &BasePath) {
   const MemberPointerType *DestMemPtr = DestType->getAs<MemberPointerType>();
   if (!DestMemPtr)
     return TC_NotApplicable;
@@ -900,7 +903,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
   }
 
   if (!CStyle && Self.CheckBaseClassAccess(OpRange.getBegin(),
-                                           DestType, SrcType,
+                                           DestClass, SrcClass,
                                            Paths.front(),
                                      diag::err_upcast_to_inaccessible_base)) {
     msg = 0;
@@ -927,7 +930,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
   }
 
   Self.BuildBasePathArray(Paths, BasePath);
-  Kind = CastExpr::CK_DerivedToBaseMemberPointer;
+  Kind = CK_DerivedToBaseMemberPointer;
   return TC_Success;
 }
 
@@ -939,7 +942,7 @@ TryStaticMemberPointerUpcast(Sema &Self, Expr *&SrcExpr, QualType SrcType,
 TryCastResult
 TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
                       bool CStyle, const SourceRange &OpRange, unsigned &msg,
-                      CastExpr::CastKind &Kind) {
+                      CastKind &Kind) {
   if (DestType->isRecordType()) {
     if (Self.RequireCompleteType(OpRange.getBegin(), DestType,
                                  diag::err_bad_dynamic_cast_incomplete)) {
@@ -961,18 +964,17 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
       (CStyle || !DestType->isReferenceType()))
     return TC_NotApplicable;
     
-  Sema::OwningExprResult Result
-    = InitSeq.Perform(Self, Entity, InitKind,
-                      Action::MultiExprArg(Self, (void**)&SrcExpr, 1));
+  ExprResult Result
+    = InitSeq.Perform(Self, Entity, InitKind, MultiExprArg(Self, &SrcExpr, 1));
   if (Result.isInvalid()) {
     msg = 0;
     return TC_Failed;
   }
   
   if (InitSeq.isConstructorInitialization())
-    Kind = CastExpr::CK_ConstructorConversion;
+    Kind = CK_ConstructorConversion;
   else
-    Kind = CastExpr::CK_NoOp;
+    Kind = CK_NoOp;
   
   SrcExpr = Result.takeAs<Expr>();
   return TC_Success;
@@ -1051,7 +1053,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
                                         QualType DestType, bool CStyle,
                                         const SourceRange &OpRange,
                                         unsigned &msg,
-                                        CastExpr::CastKind &Kind) {
+                                        CastKind &Kind) {
   bool IsLValueCast = false;
   
   DestType = Self.Context.getCanonicalType(DestType);
@@ -1097,8 +1099,15 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
       return TC_Failed;
     }
 
+    // Don't allow casting between member pointers of different sizes.
+    if (Self.Context.getTypeSize(DestMemPtr) !=
+        Self.Context.getTypeSize(SrcMemPtr)) {
+      msg = diag::err_bad_cxx_cast_member_pointer_size;
+      return TC_Failed;
+    }
+
     // A valid member pointer cast.
-    Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast;
+    Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
     return TC_Success;
   }
 
@@ -1113,7 +1122,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
-    Kind = CastExpr::CK_PointerToIntegral;
+    Kind = CK_PointerToIntegral;
     return TC_Success;
   }
 
@@ -1132,7 +1141,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
     // If both types have the same size, we can successfully cast.
     if (Self.Context.getTypeSize(SrcType)
           == Self.Context.getTypeSize(DestType)) {
-      Kind = CastExpr::CK_BitCast;
+      Kind = CK_BitCast;
       return TC_Success;
     }
     
@@ -1163,7 +1172,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
     // to the same type. However, the behavior of compilers is pretty consistent
     // on this point: allow same-type conversion if the involved types are
     // pointers, disallow otherwise.
-    Kind = CastExpr::CK_NoOp;
+    Kind = CK_NoOp;
     return TC_Success;
   }
 
@@ -1176,7 +1185,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
       msg = diag::err_bad_reinterpret_cast_small_int;
       return TC_Failed;
     }
-    Kind = CastExpr::CK_PointerToIntegral;
+    Kind = CK_PointerToIntegral;
     return TC_Success;
   }
 
@@ -1184,7 +1193,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
     assert(destIsPtr && "One type must be a pointer");
     // C++ 5.2.10p5: A value of integral or enumeration type can be explicitly
     //   converted to a pointer.
-    Kind = CastExpr::CK_IntegralToPointer;
+    Kind = CK_IntegralToPointer;
     return TC_Success;
   }
 
@@ -1209,13 +1218,13 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
   // Any pointer can be cast to an Objective-C pointer type with a C-style
   // cast.
   if (CStyle && DestType->isObjCObjectPointerType()) {
-    Kind = CastExpr::CK_AnyPointerToObjCPointerCast;
+    Kind = CK_AnyPointerToObjCPointerCast;
     return TC_Success;
   }
     
   // Not casting away constness, so the only remaining check is for compatible
   // pointer categories.
-  Kind = IsLValueCast? CastExpr::CK_LValueBitCast : CastExpr::CK_BitCast;
+  Kind = IsLValueCast? CK_LValueBitCast : CK_BitCast;
 
   if (SrcType->isFunctionPointerType()) {
     if (DestType->isFunctionPointerType()) {
@@ -1252,14 +1261,14 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr,
 
 bool 
 Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
-                         CastExpr::CastKind &Kind, 
-                         CXXBaseSpecifierArray &BasePath,
+                         CastKind &Kind, 
+                         CXXCastPath &BasePath,
                          bool FunctionalStyle) {
   // This test is outside everything else because it's the only case where
   // a non-lvalue-reference target type does not lead to decay.
   // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void".
   if (CastTy->isVoidType()) {
-    Kind = CastExpr::CK_ToVoid;
+    Kind = CK_ToVoid;
     return false;
   }
 
@@ -1285,7 +1294,7 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
   TryCastResult tcr = TryConstCast(*this, CastExpr, CastTy, /*CStyle*/true,
                                    msg);
   if (tcr == TC_Success)
-    Kind = CastExpr::CK_NoOp;
+    Kind = CK_NoOp;
 
   if (tcr == TC_NotApplicable) {
     // ... or if that is not possible, a static_cast, ignoring const, ...
@@ -1301,6 +1310,8 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr,
   if (tcr != TC_Success && msg != 0)
     Diag(R.getBegin(), msg) << (FunctionalStyle ? CT_Functional : CT_CStyle)
       << CastExpr->getType() << CastTy << R;
+  else if (Kind == CK_Unknown || Kind == CK_BitCast)
+    CheckCastAlign(CastExpr, CastTy, R);
 
   return tcr != TC_Success;
 }
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index f56573a..631308e 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -11,14 +11,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
@@ -283,7 +283,7 @@ NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
 bool Sema::isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
                                         SourceLocation IdLoc,
                                         IdentifierInfo &II,
-                                        TypeTy *ObjectTypePtr) {
+                                        ParsedType ObjectTypePtr) {
   QualType ObjectType = GetTypeFromParser(ObjectTypePtr);
   LookupResult Found(*this, &II, IdLoc, LookupNestedNameSpecifierName);
   
@@ -416,7 +416,17 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
 
       ObjectTypeSearchedInScope = true;
     }
-  } else if (isDependent) {
+  } else if (!isDependent) {
+    // Perform unqualified name lookup in the current scope.
+    LookupName(Found, S);
+  }
+
+  // If we performed lookup into a dependent context and did not find anything,
+  // that's fine: just build a dependent nested-name-specifier.
+  if (Found.empty() && isDependent &&
+      !(LookupCtx && LookupCtx->isRecord() &&
+        (!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() ||
+         !cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()))) {
     // Don't speculate if we're just trying to improve error recovery.
     if (ErrorRecoveryLookup)
       return 0;
@@ -429,11 +439,8 @@ Sema::CXXScopeTy *Sema::BuildCXXNestedNameSpecifier(Scope *S,
       return NestedNameSpecifier::Create(Context, &II);
 
     return NestedNameSpecifier::Create(Context, Prefix, &II);
-  } else {
-    // Perform unqualified name lookup in the current scope.
-    LookupName(Found, S);
-  }
-
+  } 
+  
   // FIXME: Deal with ambiguities cleanly.
 
   if (Found.empty() && !ErrorRecoveryLookup) {
@@ -560,10 +567,10 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
                                                     SourceLocation IdLoc,
                                                     SourceLocation CCLoc,
                                                     IdentifierInfo &II,
-                                                    TypeTy *ObjectTypePtr,
+                                                    ParsedType ObjectTypePtr,
                                                     bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, IdLoc, CCLoc, II,
-                                     QualType::getFromOpaquePtr(ObjectTypePtr),
+                                     GetTypeFromParser(ObjectTypePtr),
                                      /*ScopeLookupResult=*/0, EnteringContext,
                                      false);
 }
@@ -575,21 +582,20 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
 ///
 /// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
 bool Sema::IsInvalidUnlessNestedName(Scope *S, CXXScopeSpec &SS,
-                                     IdentifierInfo &II, TypeTy *ObjectType,
+                                     IdentifierInfo &II, ParsedType ObjectType,
                                      bool EnteringContext) {
   return BuildCXXNestedNameSpecifier(S, SS, SourceLocation(), SourceLocation(),
-                                     II, QualType::getFromOpaquePtr(ObjectType),
+                                     II, GetTypeFromParser(ObjectType),
                                      /*ScopeLookupResult=*/0, EnteringContext,
                                      true);
 }
 
 Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
                                                     const CXXScopeSpec &SS,
-                                                    TypeTy *Ty,
+                                                    ParsedType Ty,
                                                     SourceRange TypeRange,
                                                     SourceLocation CCLoc) {
-  NestedNameSpecifier *Prefix
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
+  NestedNameSpecifier *Prefix = SS.getScopeRep();
   QualType T = GetTypeFromParser(Ty);
   return NestedNameSpecifier::Create(Context, Prefix, /*FIXME:*/false,
                                      T.getTypePtr());
@@ -620,7 +626,7 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
   case NestedNameSpecifier::Namespace:
     // These are always namespace scopes.  We never want to enter a
     // namespace scope from anything but a file context.
-    return CurContext->getLookupContext()->isFileContext();
+    return CurContext->getRedeclContext()->isFileContext();
 
   case NestedNameSpecifier::Identifier:
   case NestedNameSpecifier::TypeSpec:
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 7a39f05..a0b4b98 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -12,10 +12,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "clang/Analysis/Analyses/PrintfFormatString.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Analysis/Analyses/FormatString.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -26,12 +29,12 @@
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 #include "clang/Basic/TargetBuiltins.h"
 #include "clang/Basic/TargetInfo.h"
 #include <limits>
 using namespace clang;
+using namespace sema;
 
 /// getLocationOfStringLiteralByte - Return a source location that points to the
 /// specified byte of the specified string literal.
@@ -122,9 +125,9 @@ bool Sema::CheckablePrintfAttr(const FormatAttr *Format, CallExpr *TheCall) {
   return false;
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
-  OwningExprResult TheCallResult(Owned(TheCall));
+  ExprResult TheCallResult(Owned(TheCall));
 
   switch (BuiltinID) {
   case Builtin::BI__builtin___CFStringMakeConstantString:
@@ -298,6 +301,10 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   unsigned i = 0, l = 0, u = 0;
   switch (BuiltinID) {
   default: return false;
+  case ARM::BI__builtin_arm_ssat: i = 1; l = 1; u = 31; break;
+  case ARM::BI__builtin_arm_usat: i = 1; u = 31; break;
+  case ARM::BI__builtin_arm_vcvtr_f:
+  case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break;
 #define GET_NEON_IMMEDIATE_CHECK
 #include "clang/Basic/arm_neon.inc"
 #undef GET_NEON_IMMEDIATE_CHECK
@@ -311,9 +318,9 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
   unsigned Val = Result.getZExtValue();
   if (Val < l || Val > (u + l))
     return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range)
-      << llvm::utostr(l) << llvm::utostr(u+l)  
-      << TheCall->getArg(i)->getSourceRange();
+      << l << u+l << TheCall->getArg(i)->getSourceRange();
 
+  // FIXME: VFP Intrinsics should error if VFP not present.
   return false;
 }
 
@@ -334,16 +341,22 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
 
   // Printf checking.
   if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
-    if (CheckablePrintfAttr(Format, TheCall)) {
+    const bool b = Format->getType() == "scanf";
+    if (b || CheckablePrintfAttr(Format, TheCall)) {
       bool HasVAListArg = Format->getFirstArg() == 0;
-      CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
-                           HasVAListArg ? 0 : Format->getFirstArg() - 1);
+      CheckPrintfScanfArguments(TheCall, HasVAListArg,
+                                Format->getFormatIdx() - 1,
+                                HasVAListArg ? 0 : Format->getFirstArg() - 1,
+                                !b);
     }
   }
 
-  for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
-       NonNull = NonNull->getNext<NonNullAttr>())
-    CheckNonNullArguments(NonNull, TheCall);
+  specific_attr_iterator<NonNullAttr>
+    i = FDecl->specific_attr_begin<NonNullAttr>(),
+    e = FDecl->specific_attr_end<NonNullAttr>();
+
+  for (; i != e; ++i)
+    CheckNonNullArguments(*i, TheCall);
 
   return false;
 }
@@ -362,12 +375,13 @@ bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
   if (!Ty->isBlockPointerType())
     return false;
 
-  if (!CheckablePrintfAttr(Format, TheCall))
+  const bool b = Format->getType() == "scanf";
+  if (!b && !CheckablePrintfAttr(Format, TheCall))
     return false;
 
   bool HasVAListArg = Format->getFirstArg() == 0;
-  CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
-                       HasVAListArg ? 0 : Format->getFirstArg() - 1);
+  CheckPrintfScanfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1,
+                            HasVAListArg ? 0 : Format->getFirstArg() - 1, !b);
 
   return false;
 }
@@ -380,8 +394,8 @@ bool Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
 ///
 /// This function goes through and does final semantic checking for these
 /// builtins,
-Sema::OwningExprResult
-Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
+ExprResult
+Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) {
   CallExpr *TheCall = (CallExpr *)TheCallResult.get();
   DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
   FunctionDecl *FDecl = cast<FunctionDecl>(DRE->getDecl());
@@ -415,6 +429,10 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
     return ExprError();
   }
 
+  // The majority of builtins return a value, but a few have special return
+  // types, so allow them to override appropriately below.
+  QualType ResultType = ValType;
+
   // We need to figure out which concrete builtin this maps onto.  For example,
   // __sync_fetch_and_add with a 2 byte object turns into
   // __sync_fetch_and_add_2.
@@ -483,11 +501,13 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
   case Builtin::BI__sync_bool_compare_and_swap:
     BuiltinIndex = 11;
     NumFixed = 2;
+    ResultType = Context.BoolTy;
     break;
   case Builtin::BI__sync_lock_test_and_set: BuiltinIndex = 12; break;
   case Builtin::BI__sync_lock_release:
     BuiltinIndex = 13;
     NumFixed = 0;
+    ResultType = Context.VoidTy;
     break;
   }
 
@@ -508,19 +528,10 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
   FunctionDecl *NewBuiltinDecl =
     cast<FunctionDecl>(LazilyCreateBuiltin(NewBuiltinII, NewBuiltinID,
                                            TUScope, false, DRE->getLocStart()));
-  const FunctionProtoType *BuiltinFT =
-    NewBuiltinDecl->getType()->getAs<FunctionProtoType>();
-
-  QualType OrigValType = ValType;
-  ValType = BuiltinFT->getArgType(0)->getAs<PointerType>()->getPointeeType();
-
-  // If the first type needs to be converted (e.g. void** -> int*), do it now.
-  if (BuiltinFT->getArgType(0) != FirstArg->getType()) {
-    ImpCastExprToType(FirstArg, BuiltinFT->getArgType(0), CastExpr::CK_BitCast);
-    TheCall->setArg(0, FirstArg);
-  }
 
-  // Next, walk the valid ones promoting to the right type.
+  // The first argument --- the pointer --- has a fixed type; we
+  // deduce the types of the rest of the arguments accordingly.  Walk
+  // the remaining arguments, converting them to the deduced value type.
   for (unsigned i = 0; i != NumFixed; ++i) {
     Expr *Arg = TheCall->getArg(i+1);
 
@@ -529,14 +540,13 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
       Arg = ICE->getSubExpr();
       ICE->setSubExpr(0);
-      ICE->Destroy(Context);
       TheCall->setArg(i+1, Arg);
     }
 
     // GCC does an implicit conversion to the pointer or integer ValType.  This
     // can fail in some cases (1i -> int**), check for this error case now.
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath))
       return ExprError();
 
@@ -546,7 +556,7 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
     // pass in 42.  The 42 gets converted to char.  This is even more strange
     // for things like 45.123 -> char, etc.
     // FIXME: Do this check.
-    ImpCastExprToType(Arg, ValType, Kind);
+    ImpCastExprToType(Arg, ValType, Kind, VK_RValue, &BasePath);
     TheCall->setArg(i+1, Arg);
   }
 
@@ -560,28 +570,10 @@ Sema::SemaBuiltinAtomicOverloaded(OwningExprResult TheCallResult) {
   UsualUnaryConversions(PromotedCall);
   TheCall->setCallee(PromotedCall);
 
-  // Change the result type of the call to match the result type of the decl.
-  TheCall->setType(NewBuiltinDecl->getCallResultType());
-
-  // If the value type was converted to an integer when processing the
-  // arguments (e.g. void* -> int), we need to convert the result back.
-  if (!Context.hasSameUnqualifiedType(ValType, OrigValType)) {
-    Expr *E = TheCallResult.takeAs<Expr>();
-
-    assert(ValType->isIntegerType() &&
-           "We always convert atomic operation values to integers.");
-    // FIXME: Handle floating point value type here too.
-    CastExpr::CastKind Kind;
-    if (OrigValType->isIntegerType())
-      Kind = CastExpr::CK_IntegralCast;
-    else if (OrigValType->hasPointerRepresentation())
-      Kind = CastExpr::CK_IntegralToPointer;
-    else
-      llvm_unreachable("Unhandled original value type!");
-
-    ImpCastExprToType(E, OrigValType, Kind);
-    return Owned(E);
-  }
+  // Change the result type of the call to match the original value type. This
+  // is arbitrary, but the codegen for these builtins ins design to handle it
+  // gracefully.
+  TheCall->setType(ResultType);
 
   return move(TheCallResult);
 }
@@ -604,16 +596,11 @@ bool Sema::CheckObjCString(Expr *Arg) {
     return true;
   }
 
-  const char *Data = Literal->getStrData();
-  unsigned Length = Literal->getByteLength();
-
-  for (unsigned i = 0; i < Length; ++i) {
-    if (!Data[i]) {
-      Diag(getLocationOfStringLiteralByte(Literal, i),
-           diag::warn_cfstring_literal_contains_nul_character)
-        << Arg->getSourceRange();
-      break;
-    }
+  size_t NulPos = Literal->getString().find('\0');
+  if (NulPos != llvm::StringRef::npos) {
+    Diag(getLocationOfStringLiteralByte(Literal, NulPos),
+         diag::warn_cfstring_literal_contains_nul_character)
+      << Arg->getSourceRange();
   }
 
   return false;
@@ -753,7 +740,6 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
       assert(Cast->getType()->isSpecificBuiltinType(BuiltinType::Double) &&
              "promotion from float to double is the only expected cast here");
       Cast->setSubExpr(0);
-      Cast->Destroy(Context);
       TheCall->setArg(NumArgs-1, CastArg);
       OrigArg = CastArg;
     }
@@ -764,7 +750,7 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs) {
 
 /// SemaBuiltinShuffleVector - Handle __builtin_shufflevector.
 // This is declared to take (...), so we have to check everything.
-Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
+ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
   if (TheCall->getNumArgs() < 2)
     return ExprError(Diag(TheCall->getLocEnd(),
                           diag::err_typecheck_call_too_few_args_at_least)
@@ -797,7 +783,7 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
     // with mask.  If so, verify that RHS is an integer vector type with the
     // same number of elts as lhs.
     if (TheCall->getNumArgs() == 2) {
-      if (!RHSType->isIntegerType() || 
+      if (!RHSType->hasIntegerRepresentation() || 
           RHSType->getAs<VectorType>()->getNumElements() != numElements)
         Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
           << SourceRange(TheCall->getArg(1)->getLocStart(),
@@ -941,29 +927,31 @@ bool Sema::SemaBuiltinLongjmp(CallExpr *TheCall) {
 // Handle i > 1 ? "x" : "y", recursivelly
 bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
                                   bool HasVAListArg,
-                                  unsigned format_idx, unsigned firstDataArg) {
+                                  unsigned format_idx, unsigned firstDataArg,
+                                  bool isPrintf) {
+
   if (E->isTypeDependent() || E->isValueDependent())
     return false;
 
   switch (E->getStmtClass()) {
   case Stmt::ConditionalOperatorClass: {
     const ConditionalOperator *C = cast<ConditionalOperator>(E);
-    return SemaCheckStringLiteral(C->getTrueExpr(), TheCall,
-                                  HasVAListArg, format_idx, firstDataArg)
-        && SemaCheckStringLiteral(C->getRHS(), TheCall,
-                                  HasVAListArg, format_idx, firstDataArg);
+    return SemaCheckStringLiteral(C->getTrueExpr(), TheCall, HasVAListArg,
+                                  format_idx, firstDataArg, isPrintf)
+        && SemaCheckStringLiteral(C->getRHS(), TheCall, HasVAListArg,
+                                  format_idx, firstDataArg, isPrintf);
   }
 
   case Stmt::ImplicitCastExprClass: {
     const ImplicitCastExpr *Expr = cast<ImplicitCastExpr>(E);
     return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
-                                  format_idx, firstDataArg);
+                                  format_idx, firstDataArg, isPrintf);
   }
 
   case Stmt::ParenExprClass: {
     const ParenExpr *Expr = cast<ParenExpr>(E);
     return SemaCheckStringLiteral(Expr->getSubExpr(), TheCall, HasVAListArg,
-                                  format_idx, firstDataArg);
+                                  format_idx, firstDataArg, isPrintf);
   }
 
   case Stmt::DeclRefExprClass: {
@@ -985,7 +973,8 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
       if (isConstant) {
         if (const Expr *Init = VD->getAnyInitializer())
           return SemaCheckStringLiteral(Init, TheCall,
-                                        HasVAListArg, format_idx, firstDataArg);
+                                        HasVAListArg, format_idx, firstDataArg,
+                                        isPrintf);
       }
 
       // For vprintf* functions (i.e., HasVAListArg==true), we add a
@@ -1025,7 +1014,7 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
             const Expr *Arg = CE->getArg(ArgIndex - 1);
 
             return SemaCheckStringLiteral(Arg, TheCall, HasVAListArg,
-                                          format_idx, firstDataArg);
+                                          format_idx, firstDataArg, isPrintf);
           }
         }
       }
@@ -1043,8 +1032,8 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
       StrE = cast<StringLiteral>(E);
 
     if (StrE) {
-      CheckPrintfString(StrE, E, TheCall, HasVAListArg, format_idx,
-                        firstDataArg);
+      CheckFormatString(StrE, E, TheCall, HasVAListArg, format_idx,
+                        firstDataArg, isPrintf);
       return true;
     }
 
@@ -1059,7 +1048,8 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
 void
 Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
                             const CallExpr *TheCall) {
-  for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+  for (NonNullAttr::args_iterator i = NonNull->args_begin(),
+                                  e = NonNull->args_end();
        i != e; ++i) {
     const Expr *ArgExpr = TheCall->getArg(*i);
     if (ArgExpr->isNullPointerConstant(Context,
@@ -1069,55 +1059,13 @@ Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
   }
 }
 
-/// CheckPrintfArguments - Check calls to printf (and similar functions) for
-/// correct use of format strings.
-///
-///  HasVAListArg - A predicate indicating whether the printf-like
-///    function is passed an explicit va_arg argument (e.g., vprintf)
-///
-///  format_idx - The index into Args for the format string.
-///
-/// Improper format strings to functions in the printf family can be
-/// the source of bizarre bugs and very serious security holes.  A
-/// good source of information is available in the following paper
-/// (which includes additional references):
-///
-///  FormatGuard: Automatic Protection From printf Format String
-///  Vulnerabilities, Proceedings of the 10th USENIX Security Symposium, 2001.
-///
-/// TODO:
-/// Functionality implemented:
-///
-///  We can statically check the following properties for string
-///  literal format strings for non v.*printf functions (where the
-///  arguments are passed directly):
-//
-///  (1) Are the number of format conversions equal to the number of
-///      data arguments?
-///
-///  (2) Does each format conversion correctly match the type of the
-///      corresponding data argument?
-///
-/// Moreover, for all printf functions we can:
-///
-///  (3) Check for a missing format string (when not caught by type checking).
-///
-///  (4) Check for no-operation flags; e.g. using "#" with format
-///      conversion 'c'  (TODO)
-///
-///  (5) Check the use of '%n', a major source of security holes.
-///
-///  (6) Check for malformed format conversions that don't specify anything.
-///
-///  (7) Check for empty format strings.  e.g: printf("");
-///
-///  (8) Check that the format string is a wide literal.
-///
-/// All of these checks can be done by parsing the format string.
-///
+/// CheckPrintfScanfArguments - Check calls to printf and scanf (and similar
+/// functions) for correct use of format strings.
 void
-Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
-                           unsigned format_idx, unsigned firstDataArg) {
+Sema::CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
+                                unsigned format_idx, unsigned firstDataArg,
+                                bool isPrintf) {
+
   const Expr *Fn = TheCall->getCallee();
 
   // The way the format attribute works in GCC, the implicit this argument
@@ -1132,9 +1080,9 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
       --firstDataArg;
   }
 
-  // CHECK: printf-like function is called with no format string.
+  // CHECK: printf/scanf-like function is called with no format string.
   if (format_idx >= TheCall->getNumArgs()) {
-    Diag(TheCall->getRParenLoc(), diag::warn_printf_missing_format_string)
+    Diag(TheCall->getRParenLoc(), diag::warn_missing_format_string)
       << Fn->getSourceRange();
     return;
   }
@@ -1154,23 +1102,24 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
   // ObjC string uses the same format specifiers as C string, so we can use
   // the same format string checking logic for both ObjC and C strings.
   if (SemaCheckStringLiteral(OrigFormatExpr, TheCall, HasVAListArg, format_idx,
-                             firstDataArg))
+                             firstDataArg, isPrintf))
     return;  // Literal format string found, check done!
 
   // If there are no arguments specified, warn with -Wformat-security, otherwise
   // warn only with -Wformat-nonliteral.
   if (TheCall->getNumArgs() == format_idx+1)
     Diag(TheCall->getArg(format_idx)->getLocStart(),
-         diag::warn_printf_nonliteral_noargs)
+         diag::warn_format_nonliteral_noargs)
       << OrigFormatExpr->getSourceRange();
   else
     Diag(TheCall->getArg(format_idx)->getLocStart(),
-         diag::warn_printf_nonliteral)
+         diag::warn_format_nonliteral)
            << OrigFormatExpr->getSourceRange();
 }
 
 namespace {
-class CheckPrintfHandler : public analyze_printf::FormatStringHandler {
+class CheckFormatHandler : public analyze_format_string::FormatStringHandler {
+protected:
   Sema &S;
   const StringLiteral *FExpr;
   const Expr *OrigFormatExpr;
@@ -1185,7 +1134,7 @@ class CheckPrintfHandler : public analyze_printf::FormatStringHandler {
   bool usesPositionalArgs;
   bool atFirstArg;
 public:
-  CheckPrintfHandler(Sema &s, const StringLiteral *fexpr,
+  CheckFormatHandler(Sema &s, const StringLiteral *fexpr,
                      const Expr *origFormatExpr, unsigned firstDataArg,
                      unsigned numDataArgs, bool isObjCLiteral,
                      const char *beg, bool hasVAListArg,
@@ -1203,55 +1152,43 @@ public:
 
   void DoneProcessing();
 
-  void HandleIncompleteFormatSpecifier(const char *startSpecifier,
-                                       unsigned specifierLen);
-
-  bool
-  HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
-                                   const char *startSpecifier,
-                                   unsigned specifierLen);
-
+  void HandleIncompleteSpecifier(const char *startSpecifier,
+                                 unsigned specifierLen);
+    
   virtual void HandleInvalidPosition(const char *startSpecifier,
                                      unsigned specifierLen,
-                                     analyze_printf::PositionContext p);
+                                     analyze_format_string::PositionContext p);
 
   virtual void HandleZeroPosition(const char *startPos, unsigned posLen);
 
   void HandleNullChar(const char *nullCharacter);
 
-  bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
-                             const char *startSpecifier,
-                             unsigned specifierLen);
-private:
+protected:
+  bool HandleInvalidConversionSpecifier(unsigned argIndex, SourceLocation Loc,
+                                        const char *startSpec,
+                                        unsigned specifierLen,
+                                        const char *csStart, unsigned csLen);
+  
   SourceRange getFormatStringRange();
-  CharSourceRange getFormatSpecifierRange(const char *startSpecifier,
-                                          unsigned specifierLen);
+  CharSourceRange getSpecifierRange(const char *startSpecifier,
+                                    unsigned specifierLen);
   SourceLocation getLocationOfByte(const char *x);
 
-  bool HandleAmount(const analyze_printf::OptionalAmount &Amt, unsigned k,
-                    const char *startSpecifier, unsigned specifierLen);
-  void HandleInvalidAmount(const analyze_printf::FormatSpecifier &FS,
-                           const analyze_printf::OptionalAmount &Amt,
-                           unsigned type,
-                           const char *startSpecifier, unsigned specifierLen);
-  void HandleFlag(const analyze_printf::FormatSpecifier &FS,
-                  const analyze_printf::OptionalFlag &flag,
-                  const char *startSpecifier, unsigned specifierLen);
-  void HandleIgnoredFlag(const analyze_printf::FormatSpecifier &FS,
-                         const analyze_printf::OptionalFlag &ignoredFlag,
-                         const analyze_printf::OptionalFlag &flag,
-                         const char *startSpecifier, unsigned specifierLen);
-
   const Expr *getDataArg(unsigned i) const;
+  
+  bool CheckNumArgs(const analyze_format_string::FormatSpecifier &FS,
+                    const analyze_format_string::ConversionSpecifier &CS,
+                    const char *startSpecifier, unsigned specifierLen,
+                    unsigned argIndex);
 };
 }
 
-SourceRange CheckPrintfHandler::getFormatStringRange() {
+SourceRange CheckFormatHandler::getFormatStringRange() {
   return OrigFormatExpr->getSourceRange();
 }
 
-CharSourceRange CheckPrintfHandler::
-getFormatSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
+CharSourceRange CheckFormatHandler::
+getSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
   SourceLocation Start = getLocationOfByte(startSpecifier);
   SourceLocation End   = getLocationOfByte(startSpecifier + specifierLen - 1);
 
@@ -1261,39 +1198,67 @@ getFormatSpecifierRange(const char *startSpecifier, unsigned specifierLen) {
   return CharSourceRange::getCharRange(Start, End);
 }
 
-SourceLocation CheckPrintfHandler::getLocationOfByte(const char *x) {
+SourceLocation CheckFormatHandler::getLocationOfByte(const char *x) {
   return S.getLocationOfStringLiteralByte(FExpr, x - Beg);
 }
 
-void CheckPrintfHandler::
-HandleIncompleteFormatSpecifier(const char *startSpecifier,
-                                unsigned specifierLen) {
+void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier,
+                                                   unsigned specifierLen){
   SourceLocation Loc = getLocationOfByte(startSpecifier);
   S.Diag(Loc, diag::warn_printf_incomplete_specifier)
-    << getFormatSpecifierRange(startSpecifier, specifierLen);
+    << getSpecifierRange(startSpecifier, specifierLen);
 }
 
 void
-CheckPrintfHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
-                                          analyze_printf::PositionContext p) {
+CheckFormatHandler::HandleInvalidPosition(const char *startPos, unsigned posLen,
+                                     analyze_format_string::PositionContext p) {
   SourceLocation Loc = getLocationOfByte(startPos);
-  S.Diag(Loc, diag::warn_printf_invalid_positional_specifier)
-    << (unsigned) p << getFormatSpecifierRange(startPos, posLen);
+  S.Diag(Loc, diag::warn_format_invalid_positional_specifier)
+    << (unsigned) p << getSpecifierRange(startPos, posLen);
 }
 
-void CheckPrintfHandler::HandleZeroPosition(const char *startPos,
+void CheckFormatHandler::HandleZeroPosition(const char *startPos,
                                             unsigned posLen) {
   SourceLocation Loc = getLocationOfByte(startPos);
-  S.Diag(Loc, diag::warn_printf_zero_positional_specifier)
-    << getFormatSpecifierRange(startPos, posLen);
+  S.Diag(Loc, diag::warn_format_zero_positional_specifier)
+    << getSpecifierRange(startPos, posLen);
+}
+
+void CheckFormatHandler::HandleNullChar(const char *nullCharacter) {
+  // The presence of a null character is likely an error.
+  S.Diag(getLocationOfByte(nullCharacter),
+         diag::warn_printf_format_string_contains_null_char)
+    << getFormatStringRange();
 }
 
-bool CheckPrintfHandler::
-HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
-                                 const char *startSpecifier,
-                                 unsigned specifierLen) {
+const Expr *CheckFormatHandler::getDataArg(unsigned i) const {
+  return TheCall->getArg(FirstDataArg + i);
+}
 
-  unsigned argIndex = FS.getArgIndex();
+void CheckFormatHandler::DoneProcessing() {
+    // Does the number of data arguments exceed the number of
+    // format conversions in the format string?
+  if (!HasVAListArg) {
+      // Find any arguments that weren't covered.
+    CoveredArgs.flip();
+    signed notCoveredArg = CoveredArgs.find_first();
+    if (notCoveredArg >= 0) {
+      assert((unsigned)notCoveredArg < NumDataArgs);
+      S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(),
+             diag::warn_printf_data_arg_not_used)
+      << getFormatStringRange();
+    }
+  }
+}
+
+bool
+CheckFormatHandler::HandleInvalidConversionSpecifier(unsigned argIndex,
+                                                     SourceLocation Loc,
+                                                     const char *startSpec,
+                                                     unsigned specifierLen,
+                                                     const char *csStart,
+                                                     unsigned csLen) {
+  
   bool keepGoing = true;
   if (argIndex < NumDataArgs) {
     // Consider the argument coverered, even though the specifier doesn't
@@ -1308,32 +1273,95 @@ HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
     // gibberish when trying to match arguments.
     keepGoing = false;
   }
+  
+  S.Diag(Loc, diag::warn_format_invalid_conversion)
+    << llvm::StringRef(csStart, csLen)
+    << getSpecifierRange(startSpec, specifierLen);
+  
+  return keepGoing;
+}
 
-  const analyze_printf::ConversionSpecifier &CS =
-    FS.getConversionSpecifier();
-  SourceLocation Loc = getLocationOfByte(CS.getStart());
-  S.Diag(Loc, diag::warn_printf_invalid_conversion)
-      << llvm::StringRef(CS.getStart(), CS.getLength())
-      << getFormatSpecifierRange(startSpecifier, specifierLen);
+bool
+CheckFormatHandler::CheckNumArgs(
+  const analyze_format_string::FormatSpecifier &FS,
+  const analyze_format_string::ConversionSpecifier &CS,
+  const char *startSpecifier, unsigned specifierLen, unsigned argIndex) {
 
-  return keepGoing;
+  if (argIndex >= NumDataArgs) {
+    if (FS.usesPositionalArg())  {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_positional_arg_exceeds_data_args)
+      << (argIndex+1) << NumDataArgs
+      << getSpecifierRange(startSpecifier, specifierLen);
+    }
+    else {
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_printf_insufficient_data_args)
+      << getSpecifierRange(startSpecifier, specifierLen);
+    }
+    
+    return false;
+  }
+  return true;
 }
 
-void CheckPrintfHandler::HandleNullChar(const char *nullCharacter) {
-  // The presence of a null character is likely an error.
-  S.Diag(getLocationOfByte(nullCharacter),
-         diag::warn_printf_format_string_contains_null_char)
-    << getFormatStringRange();
+//===--- CHECK: Printf format string checking ------------------------------===//
+
+namespace {
+class CheckPrintfHandler : public CheckFormatHandler {
+public:
+  CheckPrintfHandler(Sema &s, const StringLiteral *fexpr,
+                     const Expr *origFormatExpr, unsigned firstDataArg,
+                     unsigned numDataArgs, bool isObjCLiteral,
+                     const char *beg, bool hasVAListArg,
+                     const CallExpr *theCall, unsigned formatIdx)
+  : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg,
+                       numDataArgs, isObjCLiteral, beg, hasVAListArg,
+                       theCall, formatIdx) {}
+  
+  
+  bool HandleInvalidPrintfConversionSpecifier(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen);
+  
+  bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS,
+                             const char *startSpecifier,
+                             unsigned specifierLen);
+  
+  bool HandleAmount(const analyze_format_string::OptionalAmount &Amt, unsigned k,
+                    const char *startSpecifier, unsigned specifierLen);
+  void HandleInvalidAmount(const analyze_printf::PrintfSpecifier &FS,
+                           const analyze_printf::OptionalAmount &Amt,
+                           unsigned type,
+                           const char *startSpecifier, unsigned specifierLen);
+  void HandleFlag(const analyze_printf::PrintfSpecifier &FS,
+                  const analyze_printf::OptionalFlag &flag,
+                  const char *startSpecifier, unsigned specifierLen);
+  void HandleIgnoredFlag(const analyze_printf::PrintfSpecifier &FS,
+                         const analyze_printf::OptionalFlag &ignoredFlag,
+                         const analyze_printf::OptionalFlag &flag,
+                         const char *startSpecifier, unsigned specifierLen);
+};  
 }
 
-const Expr *CheckPrintfHandler::getDataArg(unsigned i) const {
-  return TheCall->getArg(FirstDataArg + i);
+bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
+                                      const analyze_printf::PrintfSpecifier &FS,
+                                      const char *startSpecifier,
+                                      unsigned specifierLen) {
+  const analyze_printf::PrintfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+  
+  return HandleInvalidConversionSpecifier(FS.getArgIndex(),
+                                          getLocationOfByte(CS.getStart()),
+                                          startSpecifier, specifierLen,
+                                          CS.getStart(), CS.getLength());
 }
 
-bool
-CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
-                                 unsigned k, const char *startSpecifier,
-                                 unsigned specifierLen) {
+bool CheckPrintfHandler::HandleAmount(
+                               const analyze_format_string::OptionalAmount &Amt,
+                               unsigned k, const char *startSpecifier,
+                               unsigned specifierLen) {
 
   if (Amt.hasDataArgument()) {
     if (!HasVAListArg) {
@@ -1341,7 +1369,7 @@ CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
       if (argIndex >= NumDataArgs) {
         S.Diag(getLocationOfByte(Amt.getStart()),
                diag::warn_printf_asterisk_missing_arg)
-          << k << getFormatSpecifierRange(startSpecifier, specifierLen);
+          << k << getSpecifierRange(startSpecifier, specifierLen);
         // Don't do any more checking.  We will just emit
         // spurious errors.
         return false;
@@ -1363,7 +1391,7 @@ CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
                diag::warn_printf_asterisk_wrong_type)
           << k
           << ATR.getRepresentativeType(S.Context) << T
-          << getFormatSpecifierRange(startSpecifier, specifierLen)
+          << getSpecifierRange(startSpecifier, specifierLen)
           << Arg->getSourceRange();
         // Don't do any more checking.  We will just emit
         // spurious errors.
@@ -1375,20 +1403,21 @@ CheckPrintfHandler::HandleAmount(const analyze_printf::OptionalAmount &Amt,
 }
 
 void CheckPrintfHandler::HandleInvalidAmount(
-                                      const analyze_printf::FormatSpecifier &FS,
+                                      const analyze_printf::PrintfSpecifier &FS,
                                       const analyze_printf::OptionalAmount &Amt,
                                       unsigned type,
                                       const char *startSpecifier,
                                       unsigned specifierLen) {
-  const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier();
+  const analyze_printf::PrintfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
   switch (Amt.getHowSpecified()) {
   case analyze_printf::OptionalAmount::Constant:
     S.Diag(getLocationOfByte(Amt.getStart()),
         diag::warn_printf_nonsensical_optional_amount)
       << type
       << CS.toString()
-      << getFormatSpecifierRange(startSpecifier, specifierLen)
-      << FixItHint::CreateRemoval(getFormatSpecifierRange(Amt.getStart(),
+      << getSpecifierRange(startSpecifier, specifierLen)
+      << FixItHint::CreateRemoval(getSpecifierRange(Amt.getStart(),
           Amt.getConstantLength()));
     break;
 
@@ -1397,26 +1426,27 @@ void CheckPrintfHandler::HandleInvalidAmount(
         diag::warn_printf_nonsensical_optional_amount)
       << type
       << CS.toString()
-      << getFormatSpecifierRange(startSpecifier, specifierLen);
+      << getSpecifierRange(startSpecifier, specifierLen);
     break;
   }
 }
 
-void CheckPrintfHandler::HandleFlag(const analyze_printf::FormatSpecifier &FS,
+void CheckPrintfHandler::HandleFlag(const analyze_printf::PrintfSpecifier &FS,
                                     const analyze_printf::OptionalFlag &flag,
                                     const char *startSpecifier,
                                     unsigned specifierLen) {
   // Warn about pointless flag with a fixit removal.
-  const analyze_printf::ConversionSpecifier &CS = FS.getConversionSpecifier();
+  const analyze_printf::PrintfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
   S.Diag(getLocationOfByte(flag.getPosition()),
       diag::warn_printf_nonsensical_flag)
     << flag.toString() << CS.toString()
-    << getFormatSpecifierRange(startSpecifier, specifierLen)
-    << FixItHint::CreateRemoval(getFormatSpecifierRange(flag.getPosition(), 1));
+    << getSpecifierRange(startSpecifier, specifierLen)
+    << FixItHint::CreateRemoval(getSpecifierRange(flag.getPosition(), 1));
 }
 
 void CheckPrintfHandler::HandleIgnoredFlag(
-                                const analyze_printf::FormatSpecifier &FS,
+                                const analyze_printf::PrintfSpecifier &FS,
                                 const analyze_printf::OptionalFlag &ignoredFlag,
                                 const analyze_printf::OptionalFlag &flag,
                                 const char *startSpecifier,
@@ -1425,30 +1455,33 @@ void CheckPrintfHandler::HandleIgnoredFlag(
   S.Diag(getLocationOfByte(ignoredFlag.getPosition()),
       diag::warn_printf_ignored_flag)
     << ignoredFlag.toString() << flag.toString()
-    << getFormatSpecifierRange(startSpecifier, specifierLen)
-    << FixItHint::CreateRemoval(getFormatSpecifierRange(
+    << getSpecifierRange(startSpecifier, specifierLen)
+    << FixItHint::CreateRemoval(getSpecifierRange(
         ignoredFlag.getPosition(), 1));
 }
 
 bool
-CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
+CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
                                             &FS,
                                           const char *startSpecifier,
                                           unsigned specifierLen) {
 
+  using namespace analyze_format_string;
   using namespace analyze_printf;  
-  const ConversionSpecifier &CS = FS.getConversionSpecifier();
+  const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
 
-  if (atFirstArg) {
-    atFirstArg = false;
-    usesPositionalArgs = FS.usesPositionalArg();
-  }
-  else if (usesPositionalArgs != FS.usesPositionalArg()) {
-    // Cannot mix-and-match positional and non-positional arguments.
-    S.Diag(getLocationOfByte(CS.getStart()),
-           diag::warn_printf_mix_positional_nonpositional_args)
-      << getFormatSpecifierRange(startSpecifier, specifierLen);
-    return false;
+  if (FS.consumesDataArgument()) {
+    if (atFirstArg) {
+        atFirstArg = false;
+        usesPositionalArgs = FS.usesPositionalArg();
+    }
+    else if (usesPositionalArgs != FS.usesPositionalArg()) {
+      // Cannot mix-and-match positional and non-positional arguments.
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_format_mix_positional_nonpositional_args)
+        << getSpecifierRange(startSpecifier, specifierLen);
+      return false;
+    }
   }
 
   // First check if the field width, precision, and conversion specifier
@@ -1481,7 +1514,8 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
   // Check for using an Objective-C specific conversion specifier
   // in a non-ObjC literal.
   if (!IsObjCLiteral && CS.isObjCArg()) {
-    return HandleInvalidConversionSpecifier(FS, startSpecifier, specifierLen);
+    return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
+                                                  specifierLen);
   }
 
   // Check for invalid use of field width
@@ -1520,17 +1554,17 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
   const LengthModifier &LM = FS.getLengthModifier();
   if (!FS.hasValidLengthModifier())
     S.Diag(getLocationOfByte(LM.getStart()),
-        diag::warn_printf_nonsensical_length)
+        diag::warn_format_nonsensical_length)
       << LM.toString() << CS.toString()
-      << getFormatSpecifierRange(startSpecifier, specifierLen)
-      << FixItHint::CreateRemoval(getFormatSpecifierRange(LM.getStart(),
+      << getSpecifierRange(startSpecifier, specifierLen)
+      << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(),
           LM.getLength()));
 
   // Are we using '%n'?
-  if (CS.getKind() == ConversionSpecifier::OutIntPtrArg) {
+  if (CS.getKind() == ConversionSpecifier::nArg) {
     // Issue a warning about this being a possible security issue.
     S.Diag(getLocationOfByte(CS.getStart()), diag::warn_printf_write_back)
-      << getFormatSpecifierRange(startSpecifier, specifierLen);
+      << getSpecifierRange(startSpecifier, specifierLen);
     // Continue checking the other format specifiers.
     return true;
   }
@@ -1539,22 +1573,8 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
   if (HasVAListArg)
     return true;
 
-  if (argIndex >= NumDataArgs) {
-    if (FS.usesPositionalArg())  {
-      S.Diag(getLocationOfByte(CS.getStart()),
-             diag::warn_printf_positional_arg_exceeds_data_args)
-        << (argIndex+1) << NumDataArgs
-        << getFormatSpecifierRange(startSpecifier, specifierLen);
-    }
-    else {
-      S.Diag(getLocationOfByte(CS.getStart()),
-             diag::warn_printf_insufficient_data_args)
-        << getFormatSpecifierRange(startSpecifier, specifierLen);
-    }
-
-    // Don't do any more checking.
+  if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
     return false;
-  }
 
   // Now type check the data expression that matches the
   // format specifier.
@@ -1570,7 +1590,7 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
           return true;
 
     // We may be able to offer a FixItHint if it is a supported type.
-    FormatSpecifier fixedFS = FS;
+    PrintfSpecifier fixedFS = FS;
     bool success = fixedFS.fixType(Ex->getType());
 
     if (success) {
@@ -1579,20 +1599,23 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
       llvm::raw_svector_ostream os(buf);
       fixedFS.toString(os);
 
+      // FIXME: getRepresentativeType() perhaps should return a string
+      // instead of a QualType to better handle when the representative
+      // type is 'wint_t' (which is defined in the system headers).
       S.Diag(getLocationOfByte(CS.getStart()),
           diag::warn_printf_conversion_argument_type_mismatch)
         << ATR.getRepresentativeType(S.Context) << Ex->getType()
-        << getFormatSpecifierRange(startSpecifier, specifierLen)
+        << getSpecifierRange(startSpecifier, specifierLen)
         << Ex->getSourceRange()
         << FixItHint::CreateReplacement(
-            getFormatSpecifierRange(startSpecifier, specifierLen),
+            getSpecifierRange(startSpecifier, specifierLen),
             os.str());
     }
     else {
       S.Diag(getLocationOfByte(CS.getStart()),
              diag::warn_printf_conversion_argument_type_mismatch)
         << ATR.getRepresentativeType(S.Context) << Ex->getType()
-        << getFormatSpecifierRange(startSpecifier, specifierLen)
+        << getSpecifierRange(startSpecifier, specifierLen)
         << Ex->getSourceRange();
     }
   }
@@ -1600,54 +1623,173 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
   return true;
 }
 
-void CheckPrintfHandler::DoneProcessing() {
-  // Does the number of data arguments exceed the number of
-  // format conversions in the format string?
-  if (!HasVAListArg) {
-    // Find any arguments that weren't covered.
-    CoveredArgs.flip();
-    signed notCoveredArg = CoveredArgs.find_first();
-    if (notCoveredArg >= 0) {
-      assert((unsigned)notCoveredArg < NumDataArgs);
-      S.Diag(getDataArg((unsigned) notCoveredArg)->getLocStart(),
-             diag::warn_printf_data_arg_not_used)
-        << getFormatStringRange();
+//===--- CHECK: Scanf format string checking ------------------------------===//
+
+namespace {  
+class CheckScanfHandler : public CheckFormatHandler {
+public:
+  CheckScanfHandler(Sema &s, const StringLiteral *fexpr,
+                    const Expr *origFormatExpr, unsigned firstDataArg,
+                    unsigned numDataArgs, bool isObjCLiteral,
+                    const char *beg, bool hasVAListArg,
+                    const CallExpr *theCall, unsigned formatIdx)
+  : CheckFormatHandler(s, fexpr, origFormatExpr, firstDataArg,
+                       numDataArgs, isObjCLiteral, beg, hasVAListArg,
+                       theCall, formatIdx) {}
+  
+  bool HandleScanfSpecifier(const analyze_scanf::ScanfSpecifier &FS,
+                            const char *startSpecifier,
+                            unsigned specifierLen);
+  
+  bool HandleInvalidScanfConversionSpecifier(
+          const analyze_scanf::ScanfSpecifier &FS,
+          const char *startSpecifier,
+          unsigned specifierLen);
+
+  void HandleIncompleteScanList(const char *start, const char *end);
+};
+}
+
+void CheckScanfHandler::HandleIncompleteScanList(const char *start,
+                                                 const char *end) {
+  S.Diag(getLocationOfByte(end), diag::warn_scanf_scanlist_incomplete)
+    << getSpecifierRange(start, end - start);
+}
+
+bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
+                                        const analyze_scanf::ScanfSpecifier &FS,
+                                        const char *startSpecifier,
+                                        unsigned specifierLen) {
+
+  const analyze_scanf::ScanfConversionSpecifier &CS =
+    FS.getConversionSpecifier();
+
+  return HandleInvalidConversionSpecifier(FS.getArgIndex(),
+                                          getLocationOfByte(CS.getStart()),
+                                          startSpecifier, specifierLen,
+                                          CS.getStart(), CS.getLength());
+}
+
+bool CheckScanfHandler::HandleScanfSpecifier(
+                                       const analyze_scanf::ScanfSpecifier &FS,
+                                       const char *startSpecifier,
+                                       unsigned specifierLen) {
+  
+  using namespace analyze_scanf;
+  using namespace analyze_format_string;  
+
+  const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
+
+  // Handle case where '%' and '*' don't consume an argument.  These shouldn't
+  // be used to decide if we are using positional arguments consistently.
+  if (FS.consumesDataArgument()) {
+    if (atFirstArg) {
+      atFirstArg = false;
+      usesPositionalArgs = FS.usesPositionalArg();
+    }
+    else if (usesPositionalArgs != FS.usesPositionalArg()) {
+      // Cannot mix-and-match positional and non-positional arguments.
+      S.Diag(getLocationOfByte(CS.getStart()),
+             diag::warn_format_mix_positional_nonpositional_args)
+        << getSpecifierRange(startSpecifier, specifierLen);
+      return false;
+    }
+  }
+  
+  // Check if the field with is non-zero.
+  const OptionalAmount &Amt = FS.getFieldWidth();
+  if (Amt.getHowSpecified() == OptionalAmount::Constant) {
+    if (Amt.getConstantAmount() == 0) {
+      const CharSourceRange &R = getSpecifierRange(Amt.getStart(),
+                                                   Amt.getConstantLength());
+      S.Diag(getLocationOfByte(Amt.getStart()),
+             diag::warn_scanf_nonzero_width)
+        << R << FixItHint::CreateRemoval(R);
     }
   }
+  
+  if (!FS.consumesDataArgument()) {
+    // FIXME: Technically specifying a precision or field width here
+    // makes no sense.  Worth issuing a warning at some point.
+    return true;
+  }
+  
+  // Consume the argument.
+  unsigned argIndex = FS.getArgIndex();
+  if (argIndex < NumDataArgs) {
+      // The check to see if the argIndex is valid will come later.
+      // We set the bit here because we may exit early from this
+      // function if we encounter some other error.
+    CoveredArgs.set(argIndex);
+  }
+  
+  // Check the length modifier is valid with the given conversion specifier.
+  const LengthModifier &LM = FS.getLengthModifier();
+  if (!FS.hasValidLengthModifier()) {
+    S.Diag(getLocationOfByte(LM.getStart()),
+           diag::warn_format_nonsensical_length)
+      << LM.toString() << CS.toString()
+      << getSpecifierRange(startSpecifier, specifierLen)
+      << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(),
+                                                    LM.getLength()));
+  }
+
+  // The remaining checks depend on the data arguments.
+  if (HasVAListArg)
+    return true;
+  
+  if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
+    return false;
+  
+  // FIXME: Check that the argument type matches the format specifier.
+  
+  return true;
 }
 
-void Sema::CheckPrintfString(const StringLiteral *FExpr,
+void Sema::CheckFormatString(const StringLiteral *FExpr,
                              const Expr *OrigFormatExpr,
                              const CallExpr *TheCall, bool HasVAListArg,
-                             unsigned format_idx, unsigned firstDataArg) {
-
+                             unsigned format_idx, unsigned firstDataArg,
+                             bool isPrintf) {
+  
   // CHECK: is the format string a wide literal?
   if (FExpr->isWide()) {
     Diag(FExpr->getLocStart(),
-         diag::warn_printf_format_string_is_wide_literal)
+         diag::warn_format_string_is_wide_literal)
     << OrigFormatExpr->getSourceRange();
     return;
   }
-
+  
   // Str - The format string.  NOTE: this is NOT null-terminated!
-  const char *Str = FExpr->getStrData();
-
+  llvm::StringRef StrRef = FExpr->getString();
+  const char *Str = StrRef.data();
+  unsigned StrLen = StrRef.size();
+  
   // CHECK: empty format string?
-  unsigned StrLen = FExpr->getByteLength();
-
   if (StrLen == 0) {
-    Diag(FExpr->getLocStart(), diag::warn_printf_empty_format_string)
+    Diag(FExpr->getLocStart(), diag::warn_empty_format_string)
     << OrigFormatExpr->getSourceRange();
     return;
   }
-
-  CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
-                       TheCall->getNumArgs() - firstDataArg,
-                       isa<ObjCStringLiteral>(OrigFormatExpr), Str,
-                       HasVAListArg, TheCall, format_idx);
-
-  if (!analyze_printf::ParseFormatString(H, Str, Str + StrLen))
-    H.DoneProcessing();
+  
+  if (isPrintf) {
+    CheckPrintfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+                         TheCall->getNumArgs() - firstDataArg,
+                         isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+                         HasVAListArg, TheCall, format_idx);
+  
+    if (!analyze_format_string::ParsePrintfString(H, Str, Str + StrLen))
+      H.DoneProcessing();
+  }
+  else {
+    CheckScanfHandler H(*this, FExpr, OrigFormatExpr, firstDataArg,
+                        TheCall->getNumArgs() - firstDataArg,
+                        isa<ObjCStringLiteral>(OrigFormatExpr), Str,
+                        HasVAListArg, TheCall, format_idx);
+    
+    if (!analyze_format_string::ParseScanfString(H, Str, Str + StrLen))
+      H.DoneProcessing();
+  }
 }
 
 //===--- CHECK: Return Address of Stack Variable --------------------------===//
@@ -1729,7 +1871,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
     // is AddrOf.  All others don't make sense as pointers.
     UnaryOperator *U = cast<UnaryOperator>(E);
 
-    if (U->getOpcode() == UnaryOperator::AddrOf)
+    if (U->getOpcode() == UO_AddrOf)
       return EvalVal(U->getSubExpr());
     else
       return NULL;
@@ -1739,9 +1881,9 @@ static DeclRefExpr* EvalAddr(Expr *E) {
     // Handle pointer arithmetic.  All other binary operators are not valid
     // in this context.
     BinaryOperator *B = cast<BinaryOperator>(E);
-    BinaryOperator::Opcode op = B->getOpcode();
+    BinaryOperatorKind op = B->getOpcode();
 
-    if (op != BinaryOperator::Add && op != BinaryOperator::Sub)
+    if (op != BO_Add && op != BO_Sub)
       return NULL;
 
     Expr *Base = B->getLHS();
@@ -1814,7 +1956,7 @@ static DeclRefExpr* EvalAddr(Expr *E) {
 ///  EvalVal - This function is complements EvalAddr in the mutual recursion.
 ///   See the comments for EvalAddr for more details.
 static DeclRefExpr* EvalVal(Expr *E) {
-
+do {
   // We should only be called for evaluating non-pointer expressions, or
   // expressions with a pointer type that are not used as references but instead
   // are l-values (e.g., DeclRefExpr with a pointer type).
@@ -1823,6 +1965,15 @@ static DeclRefExpr* EvalVal(Expr *E) {
   // viewed AST node.  We then recursively traverse the AST by calling
   // EvalAddr and EvalVal appropriately.
   switch (E->getStmtClass()) {
+  case Stmt::ImplicitCastExprClass: {
+    ImplicitCastExpr *IE = cast<ImplicitCastExpr>(E);
+    if (IE->getValueKind() == VK_LValue) {
+      E = IE->getSubExpr();
+      continue;
+    }
+    return NULL;
+  }
+
   case Stmt::DeclRefExprClass: {
     // DeclRefExpr: the base case.  When we hit a DeclRefExpr we are looking
     //  at code that refers to a variable's name.  We check if it has local
@@ -1835,9 +1986,11 @@ static DeclRefExpr* EvalVal(Expr *E) {
     return NULL;
   }
 
-  case Stmt::ParenExprClass:
+  case Stmt::ParenExprClass: {
     // Ignore parentheses.
-    return EvalVal(cast<ParenExpr>(E)->getSubExpr());
+    E = cast<ParenExpr>(E)->getSubExpr();
+    continue;
+  }
 
   case Stmt::UnaryOperatorClass: {
     // The only unary operator that make sense to handle here
@@ -1845,7 +1998,7 @@ static DeclRefExpr* EvalVal(Expr *E) {
     // handling all sorts of rvalues passed to a unary operator.
     UnaryOperator *U = cast<UnaryOperator>(E);
 
-    if (U->getOpcode() == UnaryOperator::Deref)
+    if (U->getOpcode() == UO_Deref)
       return EvalAddr(U->getSubExpr());
 
     return NULL;
@@ -1876,16 +2029,22 @@ static DeclRefExpr* EvalVal(Expr *E) {
     MemberExpr *M = cast<MemberExpr>(E);
 
     // Check for indirect access.  We only want direct field accesses.
-    if (!M->isArrow())
-      return EvalVal(M->getBase());
-    else
+    if (M->isArrow())
       return NULL;
+
+    // Check whether the member type is itself a reference, in which case
+    // we're not going to refer to the member, but to what the member refers to.
+    if (M->getMemberDecl()->getType()->isReferenceType())
+      return NULL;
+
+    return EvalVal(M->getBase());
   }
 
   // Everything else: we simply don't reason about them.
   default:
     return NULL;
   }
+} while (true);
 }
 
 //===--- CHECK: Floating-Point comparisons (-Wfloat-equal) ---------------===//
@@ -1954,7 +2113,6 @@ struct IntRange {
   /// True if the int is known not to have negative values.
   bool NonNegative;
 
-  IntRange() {}
   IntRange(unsigned Width, bool NonNegative)
     : Width(Width), NonNegative(NonNegative)
   {}
@@ -2063,13 +2221,13 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
   // user has an explicit widening cast, we should treat the value as
   // being of the new, wider type.
   if (ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E)) {
-    if (CE->getCastKind() == CastExpr::CK_NoOp)
+    if (CE->getCastKind() == CK_NoOp)
       return GetExprRange(C, CE->getSubExpr(), MaxWidth);
 
     IntRange OutputTypeRange = IntRange::forType(C, CE->getType());
 
-    bool isIntegerCast = (CE->getCastKind() == CastExpr::CK_IntegralCast);
-    if (!isIntegerCast && CE->getCastKind() == CastExpr::CK_Unknown)
+    bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
+    if (!isIntegerCast && CE->getCastKind() == CK_Unknown)
       isIntegerCast = CE->getSubExpr()->getType()->isIntegerType();
 
     // Assume that non-integer casts can span the full range of the type.
@@ -2108,38 +2266,38 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
     switch (BO->getOpcode()) {
 
     // Boolean-valued operations are single-bit and positive.
-    case BinaryOperator::LAnd:
-    case BinaryOperator::LOr:
-    case BinaryOperator::LT:
-    case BinaryOperator::GT:
-    case BinaryOperator::LE:
-    case BinaryOperator::GE:
-    case BinaryOperator::EQ:
-    case BinaryOperator::NE:
+    case BO_LAnd:
+    case BO_LOr:
+    case BO_LT:
+    case BO_GT:
+    case BO_LE:
+    case BO_GE:
+    case BO_EQ:
+    case BO_NE:
       return IntRange::forBoolType();
 
     // The type of these compound assignments is the type of the LHS,
     // so the RHS is not necessarily an integer.
-    case BinaryOperator::MulAssign:
-    case BinaryOperator::DivAssign:
-    case BinaryOperator::RemAssign:
-    case BinaryOperator::AddAssign:
-    case BinaryOperator::SubAssign:
+    case BO_MulAssign:
+    case BO_DivAssign:
+    case BO_RemAssign:
+    case BO_AddAssign:
+    case BO_SubAssign:
       return IntRange::forType(C, E->getType());
 
     // Operations with opaque sources are black-listed.
-    case BinaryOperator::PtrMemD:
-    case BinaryOperator::PtrMemI:
+    case BO_PtrMemD:
+    case BO_PtrMemI:
       return IntRange::forType(C, E->getType());
 
     // Bitwise-and uses the *infinum* of the two source ranges.
-    case BinaryOperator::And:
-    case BinaryOperator::AndAssign:
+    case BO_And:
+    case BO_AndAssign:
       return IntRange::meet(GetExprRange(C, BO->getLHS(), MaxWidth),
                             GetExprRange(C, BO->getRHS(), MaxWidth));
 
     // Left shift gets black-listed based on a judgement call.
-    case BinaryOperator::Shl:
+    case BO_Shl:
       // ...except that we want to treat '1 << (blah)' as logically
       // positive.  It's an important idiom.
       if (IntegerLiteral *I
@@ -2151,12 +2309,12 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
       }
       // fallthrough
 
-    case BinaryOperator::ShlAssign:
+    case BO_ShlAssign:
       return IntRange::forType(C, E->getType());
 
     // Right shift by a constant can narrow its left argument.
-    case BinaryOperator::Shr:
-    case BinaryOperator::ShrAssign: {
+    case BO_Shr:
+    case BO_ShrAssign: {
       IntRange L = GetExprRange(C, BO->getLHS(), MaxWidth);
 
       // If the shift amount is a positive constant, drop the width by
@@ -2175,11 +2333,11 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
     }
 
     // Comma acts as its right operand.
-    case BinaryOperator::Comma:
+    case BO_Comma:
       return GetExprRange(C, BO->getRHS(), MaxWidth);
 
     // Black-list pointer subtractions.
-    case BinaryOperator::Sub:
+    case BO_Sub:
       if (BO->getLHS()->getType()->isPointerType())
         return IntRange::forType(C, E->getType());
       // fallthrough
@@ -2198,13 +2356,12 @@ IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
   if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
     switch (UO->getOpcode()) {
     // Boolean-valued operations are white-listed.
-    case UnaryOperator::LNot:
+    case UO_LNot:
       return IntRange::forBoolType();
 
     // Operations with opaque sources are black-listed.
-    case UnaryOperator::Deref:
-    case UnaryOperator::AddrOf: // should be impossible
-    case UnaryOperator::OffsetOf:
+    case UO_Deref:
+    case UO_AddrOf: // should be impossible
       return IntRange::forType(C, E->getType());
 
     default:
@@ -2277,20 +2434,20 @@ bool IsZero(Sema &S, Expr *E) {
 }
 
 void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) {
-  BinaryOperator::Opcode op = E->getOpcode();
-  if (op == BinaryOperator::LT && IsZero(S, E->getRHS())) {
+  BinaryOperatorKind op = E->getOpcode();
+  if (op == BO_LT && IsZero(S, E->getRHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
       << "< 0" << "false"
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-  } else if (op == BinaryOperator::GE && IsZero(S, E->getRHS())) {
+  } else if (op == BO_GE && IsZero(S, E->getRHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_lunsigned_always_true_comparison)
       << ">= 0" << "true"
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-  } else if (op == BinaryOperator::GT && IsZero(S, E->getLHS())) {
+  } else if (op == BO_GT && IsZero(S, E->getLHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
       << "0 >" << "false" 
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-  } else if (op == BinaryOperator::LE && IsZero(S, E->getLHS())) {
+  } else if (op == BO_LE && IsZero(S, E->getLHS())) {
     S.Diag(E->getOperatorLoc(), diag::warn_runsigned_always_true_comparison)
       << "0 <=" << "true" 
       << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
@@ -2319,7 +2476,7 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
   // We don't do anything special if this isn't an unsigned integral
   // comparison:  we're only interested in integral comparisons, and
   // signed comparisons only happen in cases we don't care to warn about.
-  if (!T->isUnsignedIntegerType())
+  if (!T->hasUnsignedIntegerRepresentation())
     return AnalyzeImpConvsInComparison(S, E);
 
   Expr *lex = E->getLHS()->IgnoreParenImpCasts();
@@ -2328,12 +2485,12 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
   // Check to see if one of the (unmodified) operands is of different
   // signedness.
   Expr *signedOperand, *unsignedOperand;
-  if (lex->getType()->isSignedIntegerType()) {
-    assert(!rex->getType()->isSignedIntegerType() &&
+  if (lex->getType()->hasSignedIntegerRepresentation()) {
+    assert(!rex->getType()->hasSignedIntegerRepresentation() &&
            "unsigned comparison between two signed integer expressions?");
     signedOperand = lex;
     unsignedOperand = rex;
-  } else if (rex->getType()->isSignedIntegerType()) {
+  } else if (rex->getType()->hasSignedIntegerRepresentation()) {
     signedOperand = rex;
     unsignedOperand = lex;
   } else {
@@ -2648,3 +2805,48 @@ bool Sema::CheckParmsForFunctionDef(FunctionDecl *FD) {
 
   return HasInvalidParm;
 }
+
+/// CheckCastAlign - Implements -Wcast-align, which warns when a
+/// pointer cast increases the alignment requirements.
+void Sema::CheckCastAlign(Expr *Op, QualType T, SourceRange TRange) {
+  // This is actually a lot of work to potentially be doing on every
+  // cast; don't do it if we're ignoring -Wcast_align (as is the default).
+  if (getDiagnostics().getDiagnosticLevel(diag::warn_cast_align)
+        == Diagnostic::Ignored)
+    return;
+
+  // Ignore dependent types.
+  if (T->isDependentType() || Op->getType()->isDependentType())
+    return;
+
+  // Require that the destination be a pointer type.
+  const PointerType *DestPtr = T->getAs<PointerType>();
+  if (!DestPtr) return;
+
+  // If the destination has alignment 1, we're done.
+  QualType DestPointee = DestPtr->getPointeeType();
+  if (DestPointee->isIncompleteType()) return;
+  CharUnits DestAlign = Context.getTypeAlignInChars(DestPointee);
+  if (DestAlign.isOne()) return;
+
+  // Require that the source be a pointer type.
+  const PointerType *SrcPtr = Op->getType()->getAs<PointerType>();
+  if (!SrcPtr) return;
+  QualType SrcPointee = SrcPtr->getPointeeType();
+
+  // Whitelist casts from cv void*.  We already implicitly
+  // whitelisted casts to cv void*, since they have alignment 1.
+  // Also whitelist casts involving incomplete types, which implicitly
+  // includes 'void'.
+  if (SrcPointee->isIncompleteType()) return;
+
+  CharUnits SrcAlign = Context.getTypeAlignInChars(SrcPointee);
+  if (SrcAlign >= DestAlign) return;
+
+  Diag(TRange.getBegin(), diag::warn_cast_align)
+    << Op->getType() << T
+    << static_cast<unsigned>(SrcAlign.getQuantity())
+    << static_cast<unsigned>(DestAlign.getQuantity())
+    << TRange << Op->getSourceRange();
+}
+
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 5528875..f00d1cd 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -10,10 +10,14 @@
 //  This file defines the code-completion semantic actions.
 //
 //===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Overload.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Lex/MacroInfo.h"
@@ -21,11 +25,13 @@
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
 #include <list>
 #include <map>
 #include <vector>
 
 using namespace clang;
+using namespace sema;
 
 namespace {
   /// \brief A container of code-completion results.
@@ -37,7 +43,7 @@ namespace {
     /// filtered out (returns false).
     typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
     
-    typedef CodeCompleteConsumer::Result Result;
+    typedef CodeCompletionResult Result;
     
   private:
     /// \brief The actual results we have found.
@@ -130,17 +136,28 @@ namespace {
     /// different levels of, e.g., the inheritance hierarchy.
     std::list<ShadowMap> ShadowMaps;
     
+    /// \brief If we're potentially referring to a C++ member function, the set
+    /// of qualifiers applied to the object type.
+    Qualifiers ObjectTypeQualifiers;
+    
+    /// \brief Whether the \p ObjectTypeQualifiers field is active.
+    bool HasObjectTypeQualifiers;
+    
+    /// \brief The selector that we prefer.
+    Selector PreferredSelector;
+    
     void AdjustResultPriorityForPreferredType(Result &R);
 
   public:
     explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
-      : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
+      : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false),
+        HasObjectTypeQualifiers(false) { }
     
     /// \brief Whether we should include code patterns in the completion
     /// results.
     bool includeCodePatterns() const {
       return SemaRef.CodeCompleter && 
-      SemaRef.CodeCompleter->includeCodePatterns();
+             SemaRef.CodeCompleter->includeCodePatterns();
     }
     
     /// \brief Set the filter used for code-completion results.
@@ -161,6 +178,27 @@ namespace {
       PreferredType = SemaRef.Context.getCanonicalType(T); 
     }
     
+    /// \brief Set the cv-qualifiers on the object type, for us in filtering
+    /// calls to member functions.
+    ///
+    /// When there are qualifiers in this set, they will be used to filter
+    /// out member functions that aren't available (because there will be a 
+    /// cv-qualifier mismatch) or prefer functions with an exact qualifier
+    /// match.
+    void setObjectTypeQualifiers(Qualifiers Quals) {
+      ObjectTypeQualifiers = Quals;
+      HasObjectTypeQualifiers = true;
+    }
+    
+    /// \brief Set the preferred selector.
+    ///
+    /// When an Objective-C method declaration result is added, and that
+    /// method's selector matches this preferred selector, we give that method
+    /// a slight priority boost.
+    void setPreferredSelector(Selector Sel) {
+      PreferredSelector = Sel;
+    }
+    
     /// \brief Specify whether nested-name-specifiers are allowed.
     void allowNestedNameSpecifiers(bool Allow = true) {
       AllowNestedNameSpecifiers = Allow;
@@ -227,6 +265,7 @@ namespace {
     //@{
     bool IsOrdinaryName(NamedDecl *ND) const;
     bool IsOrdinaryNonTypeName(NamedDecl *ND) const;
+    bool IsIntegralConstantValue(NamedDecl *ND) const;
     bool IsOrdinaryNonValueName(NamedDecl *ND) const;
     bool IsNestedNameSpecifier(NamedDecl *ND) const;
     bool IsEnum(NamedDecl *ND) const;
@@ -238,6 +277,7 @@ namespace {
     bool IsMember(NamedDecl *ND) const;
     bool IsObjCIvar(NamedDecl *ND) const;
     bool IsObjCMessageReceiver(NamedDecl *ND) const;
+    bool IsObjCCollection(NamedDecl *ND) const;
     //@}    
   };  
 }
@@ -365,8 +405,12 @@ getRequiredQualification(ASTContext &Context,
     DeclContext *Parent = TargetParents.back();
     TargetParents.pop_back();
     
-    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
+    if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
+      if (!Namespace->getIdentifier())
+        continue;
+
       Result = NestedNameSpecifier::Create(Context, Result, Namespace);
+    }
     else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
       Result = NestedNameSpecifier::Create(Context, Result,
                                            false,
@@ -425,6 +469,12 @@ bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
   if (isa<CXXConstructorDecl>(ND))
     return false;
   
+  if (Filter == &ResultBuilder::IsNestedNameSpecifier ||
+      ((isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND)) &&
+       Filter != &ResultBuilder::IsNamespace &&
+       Filter != &ResultBuilder::IsNamespaceOrAlias))
+    AsNestedNameSpecifier = true;
+
   // Filter out any unwanted results.
   if (Filter && !(this->*Filter)(ND)) {
     // Check whether it is interesting as a nested-name-specifier.
@@ -438,11 +488,7 @@ bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
     }
 
     return false;
-  }
-
-  if (Filter == &ResultBuilder::IsNestedNameSpecifier)
-    AsNestedNameSpecifier = true;
-  
+  }  
   // ... then it must be interesting!
   return true;
 }
@@ -455,13 +501,13 @@ bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
   if (!SemaRef.getLangOptions().CPlusPlus)
     return true;
   
-  DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
+  DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getRedeclContext();
   
   // There is no way to qualify a name declared in a function or method.
   if (HiddenCtx->isFunctionOrMethod())
     return true;
   
-  if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
+  if (HiddenCtx == Hiding->getDeclContext()->getRedeclContext())
     return true;
   
   // We can refer to the result with the appropriate qualification. Do it.
@@ -475,21 +521,9 @@ bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
   return false;
 }
 
-enum SimplifiedTypeClass {
-  STC_Arithmetic,
-  STC_Array,
-  STC_Block,
-  STC_Function,
-  STC_ObjectiveC,
-  STC_Other,
-  STC_Pointer,
-  STC_Record,
-  STC_Void
-};
-
 /// \brief A simplified classification of types used to determine whether two
 /// types are "similar enough" when adjusting priorities.
-static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
+SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
   switch (T->getTypeClass()) {
   case Type::Builtin:
     switch (cast<BuiltinType>(T)->getKind()) {
@@ -560,7 +594,7 @@ static SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T) {
 
 /// \brief Get the type that a given expression will have if this declaration
 /// is used as an expression in its "typical" code-completion form.
-static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
+QualType clang::getDeclUsageType(ASTContext &C, NamedDecl *ND) {
   ND = cast<NamedDecl>(ND->getUnderlyingDecl());
   
   if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
@@ -594,9 +628,12 @@ void ResultBuilder::AdjustResultPriorityForPreferredType(Result &R) {
   
   CanQualType TC = SemaRef.Context.getCanonicalType(T);
   // Check for exactly-matching types (modulo qualifiers).
-  if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC))
-    R.Priority /= CCF_ExactTypeMatch;
-  // Check for nearly-matching types, based on classification of each.
+  if (SemaRef.Context.hasSameUnqualifiedType(PreferredType, TC)) {
+    if (PreferredType->isVoidType())
+      R.Priority += CCD_VoidMatch;
+    else
+      R.Priority /= CCF_ExactTypeMatch;
+  } // Check for nearly-matching types, based on classification of each.
   else if ((getSimplifiedTypeClass(PreferredType)
                                                == getSimplifiedTypeClass(TC)) &&
            !(PreferredType->isEnumeralType() && TC->isEnumeralType()))
@@ -681,7 +718,14 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
   // Make sure that any given declaration only shows up in the result set once.
   if (!AllDeclsFound.insert(CanonDecl))
     return;
-  
+
+  // If this is an Objective-C method declaration whose selector matches our
+  // preferred selector, give it a priority boost.
+  if (!PreferredSelector.isNull())
+    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+      if (PreferredSelector == Method->getSelector())
+        R.Priority += CCD_SelectorMatch;
+
   // If the filter is for nested-name-specifiers, then this result starts a
   // nested-name-specifier.
   if (AsNestedNameSpecifier) {
@@ -689,7 +733,7 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
     R.Priority = CCP_NestedNameSpecifier;
   } else if (!PreferredType.isNull())
       AdjustResultPriorityForPreferredType(R);
-
+      
   // If this result is supposed to have an informative qualifier, add one.
   if (R.QualifierIsInformative && !R.Qualifier &&
       !R.StartsNestedNameSpecifier) {
@@ -742,7 +786,7 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
   }
   else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
            isa<CXXRecordDecl>(R.Declaration->getDeclContext()
-                                                  ->getLookupContext()))
+                                                  ->getRedeclContext()))
     R.QualifierIsInformative = true;
 
   // If this result is supposed to have an informative qualifier, add one.
@@ -762,9 +806,30 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
   if (InBaseClass)
     R.Priority += CCD_InBaseClass;
   
+  // If this is an Objective-C method declaration whose selector matches our
+  // preferred selector, give it a priority boost.
+  if (!PreferredSelector.isNull())
+    if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(R.Declaration))
+      if (PreferredSelector == Method->getSelector())
+        R.Priority += CCD_SelectorMatch;
+
   if (!PreferredType.isNull())
     AdjustResultPriorityForPreferredType(R);
   
+  if (HasObjectTypeQualifiers)
+    if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
+      if (Method->isInstance()) {
+        Qualifiers MethodQuals
+                        = Qualifiers::fromCVRMask(Method->getTypeQualifiers());
+        if (ObjectTypeQualifiers == MethodQuals)
+          R.Priority += CCD_ObjectQualifierMatch;
+        else if (ObjectTypeQualifiers - MethodQuals) {
+          // The method cannot be invoked, because doing so would drop 
+          // qualifiers.
+          return;
+        }
+      }
+  
   // Insert this result into the set of results.
   Results.push_back(R);
 }
@@ -821,6 +886,17 @@ bool ResultBuilder::IsOrdinaryNonTypeName(NamedDecl *ND) const {
   return ND->getIdentifierNamespace() & IDNS;
 }
 
+bool ResultBuilder::IsIntegralConstantValue(NamedDecl *ND) const {
+  if (!IsOrdinaryNonTypeName(ND))
+    return 0;
+  
+  if (ValueDecl *VD = dyn_cast<ValueDecl>(ND->getUnderlyingDecl()))
+    if (VD->getType()->isIntegralOrEnumerationType())
+      return true;
+        
+  return false;
+}
+
 /// \brief Determines whether this given declaration will be found by
 /// ordinary name lookup.
 bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
@@ -888,7 +964,10 @@ bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
 
 /// \brief Determines whether the given declaration is a type.
 bool ResultBuilder::IsType(NamedDecl *ND) const {
-  return isa<TypeDecl>(ND);
+  if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
+    ND = Using->getTargetDecl();
+  
+  return isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
 }
 
 /// \brief Determines which members of a class should be visible via
@@ -944,6 +1023,20 @@ bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
   return isObjCReceiverType(SemaRef.Context, T);
 }
 
+bool ResultBuilder::IsObjCCollection(NamedDecl *ND) const {
+  if ((SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryName(ND)) ||
+      (!SemaRef.getLangOptions().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
+    return false;
+  
+  QualType T = getDeclUsageType(SemaRef.Context, ND);
+  if (T.isNull())
+    return false;
+  
+  T = SemaRef.Context.getBaseElementType(T);
+  return T->isObjCObjectType() || T->isObjCObjectPointerType() ||
+         T->isObjCIdType() || 
+         (SemaRef.getLangOptions().CPlusPlus && T->isRecordType());
+}
 
 /// \rief Determines whether the given declaration is an Objective-C
 /// instance variable.
@@ -971,7 +1064,7 @@ namespace {
 /// \brief Add type specifiers for the current language as keyword results.
 static void AddTypeSpecifierResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   Results.AddResult(Result("short", CCP_Type));
   Results.AddResult(Result("long", CCP_Type));
   Results.AddResult(Result("signed", CCP_Type));
@@ -1046,10 +1139,10 @@ static void AddTypeSpecifierResults(const LangOptions &LangOpts,
   }
 }
 
-static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
+static void AddStorageSpecifiers(Sema::ParserCompletionContext CCC,
                                  const LangOptions &LangOpts, 
                                  ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   // Note: we don't suggest either "auto" or "register", because both
   // are pointless as storage specifiers. Elsewhere, we suggest "auto"
   // in C++0x as a type specifier.
@@ -1057,13 +1150,13 @@ static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
   Results.AddResult(Result("static"));
 }
 
-static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
+static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
                                   const LangOptions &LangOpts, 
                                   ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   switch (CCC) {
-  case Action::CCC_Class:
-  case Action::CCC_MemberTemplate:
+  case Sema::PCC_Class:
+  case Sema::PCC_MemberTemplate:
     if (LangOpts.CPlusPlus) {
       Results.AddResult(Result("explicit"));
       Results.AddResult(Result("friend"));
@@ -1072,20 +1165,21 @@ static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
     }    
     // Fall through
 
-  case Action::CCC_ObjCInterface:
-  case Action::CCC_ObjCImplementation:
-  case Action::CCC_Namespace:
-  case Action::CCC_Template:
+  case Sema::PCC_ObjCInterface:
+  case Sema::PCC_ObjCImplementation:
+  case Sema::PCC_Namespace:
+  case Sema::PCC_Template:
     if (LangOpts.CPlusPlus || LangOpts.C99)
       Results.AddResult(Result("inline"));
     break;
 
-  case Action::CCC_ObjCInstanceVariableList:
-  case Action::CCC_Expression:
-  case Action::CCC_Statement:
-  case Action::CCC_ForInit:
-  case Action::CCC_Condition:
-  case Action::CCC_RecoveryInFunction:
+  case Sema::PCC_ObjCInstanceVariableList:
+  case Sema::PCC_Expression:
+  case Sema::PCC_Statement:
+  case Sema::PCC_ForInit:
+  case Sema::PCC_Condition:
+  case Sema::PCC_RecoveryInFunction:
+  case Sema::PCC_Type:
     break;
   }
 }
@@ -1110,31 +1204,32 @@ static void AddTypedefResult(ResultBuilder &Results) {
   Pattern->AddPlaceholderChunk("type");
   Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
   Pattern->AddPlaceholderChunk("name");
-  Results.AddResult(CodeCompleteConsumer::Result(Pattern));        
+  Results.AddResult(CodeCompletionResult(Pattern));        
 }
 
-static bool WantTypesInContext(Action::CodeCompletionContext CCC,
+static bool WantTypesInContext(Sema::ParserCompletionContext CCC,
                                const LangOptions &LangOpts) {
   if (LangOpts.CPlusPlus)
     return true;
   
   switch (CCC) {
-  case Action::CCC_Namespace:
-  case Action::CCC_Class:
-  case Action::CCC_ObjCInstanceVariableList:
-  case Action::CCC_Template:
-  case Action::CCC_MemberTemplate:
-  case Action::CCC_Statement:
-  case Action::CCC_RecoveryInFunction:
+  case Sema::PCC_Namespace:
+  case Sema::PCC_Class:
+  case Sema::PCC_ObjCInstanceVariableList:
+  case Sema::PCC_Template:
+  case Sema::PCC_MemberTemplate:
+  case Sema::PCC_Statement:
+  case Sema::PCC_RecoveryInFunction:
+  case Sema::PCC_Type:
     return true;
     
-  case Action::CCC_ObjCInterface:
-  case Action::CCC_ObjCImplementation:
-  case Action::CCC_Expression:
-  case Action::CCC_Condition:
+  case Sema::PCC_ObjCInterface:
+  case Sema::PCC_ObjCImplementation:
+  case Sema::PCC_Expression:
+  case Sema::PCC_Condition:
     return false;
     
-  case Action::CCC_ForInit:
+  case Sema::PCC_ForInit:
     return LangOpts.ObjC1 || LangOpts.C99;
   }
   
@@ -1142,13 +1237,13 @@ static bool WantTypesInContext(Action::CodeCompletionContext CCC,
 }
 
 /// \brief Add language constructs that show up for "ordinary" names.
-static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
+static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
                                    Sema &SemaRef,
                                    ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   switch (CCC) {
-  case Action::CCC_Namespace:
+  case Sema::PCC_Namespace:
     if (SemaRef.getLangOptions().CPlusPlus) {
       CodeCompletionString *Pattern = 0;
       
@@ -1207,7 +1302,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
     AddTypedefResult(Results);
     // Fall through
 
-  case Action::CCC_Class:
+  case Sema::PCC_Class:
     if (SemaRef.getLangOptions().CPlusPlus) {
       // Using declaration
       CodeCompletionString *Pattern = new CodeCompletionString;
@@ -1231,7 +1326,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
         Results.AddResult(Result(Pattern));
       }
 
-      if (CCC == Action::CCC_Class) {
+      if (CCC == Sema::PCC_Class) {
         AddTypedefResult(Results);
 
         // public:
@@ -1255,8 +1350,8 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
     }
     // Fall through
 
-  case Action::CCC_Template:
-  case Action::CCC_MemberTemplate:
+  case Sema::PCC_Template:
+  case Sema::PCC_MemberTemplate:
     if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
       // template < parameters >
       CodeCompletionString *Pattern = new CodeCompletionString;
@@ -1271,24 +1366,24 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
     AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     break;
 
-  case Action::CCC_ObjCInterface:
+  case Sema::PCC_ObjCInterface:
     AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     break;
       
-  case Action::CCC_ObjCImplementation:
+  case Sema::PCC_ObjCImplementation:
     AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     break;
       
-  case Action::CCC_ObjCInstanceVariableList:
+  case Sema::PCC_ObjCInstanceVariableList:
     AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
     break;
       
-  case Action::CCC_RecoveryInFunction:
-  case Action::CCC_Statement: {
+  case Sema::PCC_RecoveryInFunction:
+  case Sema::PCC_Statement: {
     AddTypedefResult(Results);
 
     CodeCompletionString *Pattern = 0;
@@ -1344,7 +1439,7 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
     }
     
     // Switch-specific statements.
-    if (!SemaRef.getSwitchStack().empty()) {
+    if (!SemaRef.getCurFunction()->SwitchStack.empty()) {
       // case expression:
       Pattern = new CodeCompletionString;
       Pattern->AddTypedTextChunk("case");
@@ -1460,12 +1555,12 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
   }
 
   // Fall through (for statement expressions).
-  case Action::CCC_ForInit:
-  case Action::CCC_Condition:
+  case Sema::PCC_ForInit:
+  case Sema::PCC_Condition:
     AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
     // Fall through: conditions and statements can have expressions.
 
-  case Action::CCC_Expression: {
+  case Sema::PCC_Expression: {
     CodeCompletionString *Pattern = 0;
     if (SemaRef.getLangOptions().CPlusPlus) {
       // 'this', if we're in a non-static member function.
@@ -1600,12 +1695,15 @@ static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
     Results.AddResult(Result(Pattern));
     break;
   }
+      
+  case Sema::PCC_Type:
+    break;
   }
 
   if (WantTypesInContext(CCC, SemaRef.getLangOptions()))
     AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
 
-  if (SemaRef.getLangOptions().CPlusPlus)
+  if (SemaRef.getLangOptions().CPlusPlus && CCC != Sema::PCC_Type)
     Results.AddResult(Result("operator"));
 }
 
@@ -1645,6 +1743,117 @@ static void AddResultTypeChunk(ASTContext &Context,
   Result->AddResultTypeChunk(TypeStr);
 }
 
+static void MaybeAddSentinel(ASTContext &Context, NamedDecl *FunctionOrMethod,
+                             CodeCompletionString *Result) {
+  if (SentinelAttr *Sentinel = FunctionOrMethod->getAttr<SentinelAttr>())
+    if (Sentinel->getSentinel() == 0) {
+      if (Context.getLangOptions().ObjC1 &&
+          Context.Idents.get("nil").hasMacroDefinition())
+        Result->AddTextChunk(", nil");
+      else if (Context.Idents.get("NULL").hasMacroDefinition())
+        Result->AddTextChunk(", NULL");
+      else
+        Result->AddTextChunk(", (void*)0");
+    }
+}
+
+static std::string FormatFunctionParameter(ASTContext &Context,
+                                           ParmVarDecl *Param,
+                                           bool SuppressName = false) {
+  bool ObjCMethodParam = isa<ObjCMethodDecl>(Param->getDeclContext());
+  if (Param->getType()->isDependentType() ||
+      !Param->getType()->isBlockPointerType()) {
+    // The argument for a dependent or non-block parameter is a placeholder 
+    // containing that parameter's type.
+    std::string Result;
+    
+    if (Param->getIdentifier() && !ObjCMethodParam && !SuppressName)
+      Result = Param->getIdentifier()->getName();
+    
+    Param->getType().getAsStringInternal(Result, 
+                                         Context.PrintingPolicy);
+    
+    if (ObjCMethodParam) {
+      Result = "(" + Result;
+      Result += ")";
+      if (Param->getIdentifier() && !SuppressName)
+        Result += Param->getIdentifier()->getName();
+    }
+    return Result;
+  }
+  
+  // The argument for a block pointer parameter is a block literal with
+  // the appropriate type.
+  FunctionProtoTypeLoc *Block = 0;
+  TypeLoc TL;
+  if (TypeSourceInfo *TSInfo = Param->getTypeSourceInfo()) {
+    TL = TSInfo->getTypeLoc().getUnqualifiedLoc();
+    while (true) {
+      // Look through typedefs.
+      if (TypedefTypeLoc *TypedefTL = dyn_cast<TypedefTypeLoc>(&TL)) {
+        if (TypeSourceInfo *InnerTSInfo
+            = TypedefTL->getTypedefDecl()->getTypeSourceInfo()) {
+          TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
+          continue;
+        }
+      }
+      
+      // Look through qualified types
+      if (QualifiedTypeLoc *QualifiedTL = dyn_cast<QualifiedTypeLoc>(&TL)) {
+        TL = QualifiedTL->getUnqualifiedLoc();
+        continue;
+      }
+      
+      // Try to get the function prototype behind the block pointer type,
+      // then we're done.
+      if (BlockPointerTypeLoc *BlockPtr
+          = dyn_cast<BlockPointerTypeLoc>(&TL)) {
+        TL = BlockPtr->getPointeeLoc();
+        Block = dyn_cast<FunctionProtoTypeLoc>(&TL);
+      }
+      break;
+    }
+  }
+
+  if (!Block) {
+    // We were unable to find a FunctionProtoTypeLoc with parameter names
+    // for the block; just use the parameter type as a placeholder.
+    std::string Result;
+    Param->getType().getUnqualifiedType().
+                            getAsStringInternal(Result, Context.PrintingPolicy);
+    
+    if (ObjCMethodParam) {
+      Result = "(" + Result;
+      Result += ")";
+      if (Param->getIdentifier())
+        Result += Param->getIdentifier()->getName();
+    }
+      
+    return Result;
+  }
+  
+  // We have the function prototype behind the block pointer type, as it was
+  // written in the source.
+  std::string Result = "(^)(";
+  for (unsigned I = 0, N = Block->getNumArgs(); I != N; ++I) {
+    if (I)
+      Result += ", ";
+    Result += FormatFunctionParameter(Context, Block->getArg(I));
+    
+    if (I == N - 1 && Block->getTypePtr()->isVariadic())
+      Result += ", ...";
+  }
+  if (Block->getTypePtr()->isVariadic() && Block->getNumArgs() == 0)
+    Result += "...";
+  else if (Block->getNumArgs() == 0 && !Context.getLangOptions().CPlusPlus)
+    Result += "void";
+             
+  Result += ")";
+  Block->getTypePtr()->getResultType().getAsStringInternal(Result, 
+                                                        Context.PrintingPolicy);
+  return Result;
+}
+
 /// \brief Add function parameter chunks to the given code completion string.
 static void AddFunctionParameterChunks(ASTContext &Context,
                                        FunctionDecl *Function,
@@ -1668,21 +1877,23 @@ static void AddFunctionParameterChunks(ASTContext &Context,
       CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
     
     // Format the placeholder string.
-    std::string PlaceholderStr;
-    if (Param->getIdentifier())
-      PlaceholderStr = Param->getIdentifier()->getName();
-    
-    Param->getType().getAsStringInternal(PlaceholderStr, 
-                                         Context.PrintingPolicy);
-    
+    std::string PlaceholderStr = FormatFunctionParameter(Context, Param);
+        
+    if (Function->isVariadic() && P == N - 1)
+      PlaceholderStr += ", ...";
+
     // Add the placeholder string.
     CCStr->AddPlaceholderChunk(PlaceholderStr);
   }
   
   if (const FunctionProtoType *Proto 
         = Function->getType()->getAs<FunctionProtoType>())
-    if (Proto->isVariadic())
-      CCStr->AddPlaceholderChunk(", ...");
+    if (Proto->isVariadic()) {
+      if (Proto->getNumArgs() == 0)
+        CCStr->AddPlaceholderChunk("...");
+
+      MaybeAddSentinel(Context, Function, CCStr);
+    }
 }
 
 /// \brief Add template parameter chunks to the given code completion string.
@@ -1799,13 +2010,15 @@ static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
 /// how to use this result, or NULL to indicate that the string or name of the
 /// result is all that is needed.
 CodeCompletionString *
-CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
+CodeCompletionResult::CreateCodeCompletionString(Sema &S,
+                                               CodeCompletionString *Result) {
   typedef CodeCompletionString::Chunk Chunk;
   
   if (Kind == RK_Pattern)
-    return Pattern->Clone();
+    return Pattern->Clone(Result);
   
-  CodeCompletionString *Result = new CodeCompletionString;
+  if (!Result)
+    Result = new CodeCompletionString;
 
   if (Kind == RK_Keyword) {
     Result->AddTypedTextChunk(Keyword);
@@ -1978,10 +2191,20 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
         continue;
 
       std::string Arg;
-      (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
-      Arg = "(" + Arg + ")";
-      if (IdentifierInfo *II = (*P)->getIdentifier())
-        Arg += II->getName().str();
+      
+      if ((*P)->getType()->isBlockPointerType() && !DeclaringEntity)
+        Arg = FormatFunctionParameter(S.Context, *P, true);
+      else {
+        (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
+        Arg = "(" + Arg + ")";
+        if (IdentifierInfo *II = (*P)->getIdentifier())
+          if (DeclaringEntity || AllParametersAreInformative)
+            Arg += II->getName().str();
+      }
+      
+      if (Method->isVariadic() && (P + 1) == PEnd)
+        Arg += ", ...";
+      
       if (DeclaringEntity)
         Result->AddTextChunk(Arg);
       else if (AllParametersAreInformative)
@@ -1991,12 +2214,16 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
     }
 
     if (Method->isVariadic()) {
-      if (DeclaringEntity)
-        Result->AddTextChunk(", ...");
-      else if (AllParametersAreInformative)
-        Result->AddInformativeChunk(", ...");
-      else
-        Result->AddPlaceholderChunk(", ...");
+      if (Method->param_size() == 0) {
+        if (DeclaringEntity)
+          Result->AddTextChunk(", ...");
+        else if (AllParametersAreInformative)
+          Result->AddInformativeChunk(", ...");
+        else
+          Result->AddPlaceholderChunk(", ...");
+      }
+      
+      MaybeAddSentinel(S.Context, Method, Result);
     }
     
     return Result;
@@ -2076,226 +2303,421 @@ CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
   return Result;
 }
 
-namespace {
-  struct SortCodeCompleteResult {
-    typedef CodeCompleteConsumer::Result Result;
-    
-    bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
-      Selector XSel = X.getObjCSelector();
-      Selector YSel = Y.getObjCSelector();
-      if (!XSel.isNull() && !YSel.isNull()) {
-        // We are comparing two selectors.
-        unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
-        if (N == 0)
-          ++N;
-        for (unsigned I = 0; I != N; ++I) {
-          IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
-          IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
-          if (!XId || !YId)
-            return XId && !YId;
-          
-          switch (XId->getName().compare_lower(YId->getName())) {
-          case -1: return true;
-          case 1: return false;
-          default: break;
-          }
-        }
-    
-        return XSel.getNumArgs() < YSel.getNumArgs();
-      }
+unsigned clang::getMacroUsagePriority(llvm::StringRef MacroName, 
+                                      bool PreferredTypeIsPointer) {
+  unsigned Priority = CCP_Macro;
+  
+  // Treat the "nil" and "NULL" macros as null pointer constants.
+  if (MacroName.equals("nil") || MacroName.equals("NULL")) {
+    Priority = CCP_Constant;
+    if (PreferredTypeIsPointer)
+      Priority = Priority / CCF_SimilarTypeMatch;
+  }
+  
+  return Priority;
+}
 
-      // For non-selectors, order by kind.
-      if (X.getNameKind() != Y.getNameKind())
-        return X.getNameKind() < Y.getNameKind();
-      
-      // Order identifiers by comparison of their lowercased names.
-      if (IdentifierInfo *XId = X.getAsIdentifierInfo())
-        return XId->getName().compare_lower(
-                                     Y.getAsIdentifierInfo()->getName()) < 0;
-
-      // Order overloaded operators by the order in which they appear
-      // in our list of operators.
-      if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
-        return XOp < Y.getCXXOverloadedOperator();
-
-      // Order C++0x user-defined literal operators lexically by their
-      // lowercased suffixes.
-      if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
-        return XLit->getName().compare_lower(
-                                  Y.getCXXLiteralIdentifier()->getName()) < 0;
-
-      // The only stable ordering we have is to turn the name into a
-      // string and then compare the lower-case strings. This is
-      // inefficient, but thankfully does not happen too often.
-      return llvm::StringRef(X.getAsString()).compare_lower(
-                                                 Y.getAsString()) < 0;
-    }
-    
-    /// \brief Retrieve the name that should be used to order a result.
-    ///
-    /// If the name needs to be constructed as a string, that string will be
-    /// saved into Saved and the returned StringRef will refer to it.
-    static llvm::StringRef getOrderedName(const Result &R,
-                                          std::string &Saved) {
-      switch (R.Kind) {
-      case Result::RK_Keyword:
-        return R.Keyword;
-          
-      case Result::RK_Pattern:
-        return R.Pattern->getTypedText();
-          
-      case Result::RK_Macro:
-        return R.Macro->getName();
-          
-      case Result::RK_Declaration:
-        // Handle declarations below.
-        break;
-      }
-            
-      DeclarationName Name = R.Declaration->getDeclName();
-      
-      // If the name is a simple identifier (by far the common case), or a
-      // zero-argument selector, just return a reference to that identifier.
-      if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
-        return Id->getName();
-      if (Name.isObjCZeroArgSelector())
-        if (IdentifierInfo *Id
-                          = Name.getObjCSelector().getIdentifierInfoForSlot(0))
-          return Id->getName();
-      
-      Saved = Name.getAsString();
-      return Saved;
-    }
-    
-    bool operator()(const Result &X, const Result &Y) const {
-      std::string XSaved, YSaved;
-      llvm::StringRef XStr = getOrderedName(X, XSaved);
-      llvm::StringRef YStr = getOrderedName(Y, YSaved);
-      int cmp = XStr.compare_lower(YStr);
-      if (cmp)
-        return cmp < 0;
-      
-      // Non-hidden names precede hidden names.
-      if (X.Hidden != Y.Hidden)
-        return !X.Hidden;
+CXCursorKind clang::getCursorKindForDecl(Decl *D) {
+  if (!D)
+    return CXCursor_UnexposedDecl;
+  
+  switch (D->getKind()) {
+    case Decl::Enum:               return CXCursor_EnumDecl;
+    case Decl::EnumConstant:       return CXCursor_EnumConstantDecl;
+    case Decl::Field:              return CXCursor_FieldDecl;
+    case Decl::Function:  
+      return CXCursor_FunctionDecl;
+    case Decl::ObjCCategory:       return CXCursor_ObjCCategoryDecl;
+    case Decl::ObjCCategoryImpl:   return CXCursor_ObjCCategoryImplDecl;
+    case Decl::ObjCClass:
+      // FIXME
+      return CXCursor_UnexposedDecl;
+    case Decl::ObjCForwardProtocol:
+      // FIXME
+      return CXCursor_UnexposedDecl;      
+    case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl;
+    case Decl::ObjCInterface:      return CXCursor_ObjCInterfaceDecl;
+    case Decl::ObjCIvar:           return CXCursor_ObjCIvarDecl; 
+    case Decl::ObjCMethod:
+      return cast<ObjCMethodDecl>(D)->isInstanceMethod()
+      ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
+    case Decl::CXXMethod:          return CXCursor_CXXMethod;
+    case Decl::CXXConstructor:     return CXCursor_Constructor;
+    case Decl::CXXDestructor:      return CXCursor_Destructor;
+    case Decl::CXXConversion:      return CXCursor_ConversionFunction;
+    case Decl::ObjCProperty:       return CXCursor_ObjCPropertyDecl;
+    case Decl::ObjCProtocol:       return CXCursor_ObjCProtocolDecl;
+    case Decl::ParmVar:            return CXCursor_ParmDecl;
+    case Decl::Typedef:            return CXCursor_TypedefDecl;
+    case Decl::Var:                return CXCursor_VarDecl;
+    case Decl::Namespace:          return CXCursor_Namespace;
+    case Decl::NamespaceAlias:     return CXCursor_NamespaceAlias;
+    case Decl::TemplateTypeParm:   return CXCursor_TemplateTypeParameter;
+    case Decl::NonTypeTemplateParm:return CXCursor_NonTypeTemplateParameter;
+    case Decl::TemplateTemplateParm:return CXCursor_TemplateTemplateParameter;
+    case Decl::FunctionTemplate:   return CXCursor_FunctionTemplate;
+    case Decl::ClassTemplate:      return CXCursor_ClassTemplate;
+    case Decl::ClassTemplatePartialSpecialization:
+      return CXCursor_ClassTemplatePartialSpecialization;
+    case Decl::UsingDirective:     return CXCursor_UsingDirective;
       
-      // Non-nested-name-specifiers precede nested-name-specifiers.
-      if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
-        return !X.StartsNestedNameSpecifier;
+    case Decl::Using:
+    case Decl::UnresolvedUsingValue:
+    case Decl::UnresolvedUsingTypename: 
+      return CXCursor_UsingDeclaration;
       
-      return false;
-    }
-  };
+    default:
+      if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+        switch (TD->getTagKind()) {
+          case TTK_Struct: return CXCursor_StructDecl;
+          case TTK_Class:  return CXCursor_ClassDecl;
+          case TTK_Union:  return CXCursor_UnionDecl;
+          case TTK_Enum:   return CXCursor_EnumDecl;
+        }
+      }
+  }
+  
+  return CXCursor_UnexposedDecl;
 }
 
 static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results,
                             bool TargetTypeIsPointer = false) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   Results.EnterNewScope();
   for (Preprocessor::macro_iterator M = PP.macro_begin(), 
                                  MEnd = PP.macro_end();
        M != MEnd; ++M) {
-    unsigned Priority = CCP_Macro;
-    
-    // Treat the "nil" and "NULL" macros as null pointer constants.
-    if (M->first->isStr("nil") || M->first->isStr("NULL")) {
-      Priority = CCP_Constant;
-      if (TargetTypeIsPointer)
-        Priority = Priority / CCF_SimilarTypeMatch;
-    }
-      
-    Results.AddResult(Result(M->first, Priority));
+    Results.AddResult(Result(M->first, 
+                             getMacroUsagePriority(M->first->getName(),
+                                                   TargetTypeIsPointer)));
   }
   Results.ExitScope();
 }
 
+static void AddPrettyFunctionResults(const LangOptions &LangOpts, 
+                                     ResultBuilder &Results) {
+  typedef CodeCompletionResult Result;
+  
+  Results.EnterNewScope();
+  Results.AddResult(Result("__PRETTY_FUNCTION__", CCP_Constant));
+  Results.AddResult(Result("__FUNCTION__", CCP_Constant));
+  if (LangOpts.C99 || LangOpts.CPlusPlus0x)
+    Results.AddResult(Result("__func__", CCP_Constant));
+  Results.ExitScope();
+}
+
 static void HandleCodeCompleteResults(Sema *S,
                                       CodeCompleteConsumer *CodeCompleter,
-                                     CodeCompleteConsumer::Result *Results,
-                                     unsigned NumResults) {
-  std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
-
+                                      CodeCompletionContext Context,
+                                      CodeCompletionResult *Results,
+                                      unsigned NumResults) {
   if (CodeCompleter)
-    CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
+    CodeCompleter->ProcessCodeCompleteResults(*S, Context, Results, NumResults);
   
   for (unsigned I = 0; I != NumResults; ++I)
     Results[I].Destroy();
 }
 
+static enum CodeCompletionContext::Kind mapCodeCompletionContext(Sema &S, 
+                                            Sema::ParserCompletionContext PCC) {
+  switch (PCC) {
+  case Sema::PCC_Namespace:
+    return CodeCompletionContext::CCC_TopLevel;
+      
+  case Sema::PCC_Class:
+    return CodeCompletionContext::CCC_ClassStructUnion;
+
+  case Sema::PCC_ObjCInterface:
+    return CodeCompletionContext::CCC_ObjCInterface;
+      
+  case Sema::PCC_ObjCImplementation:
+    return CodeCompletionContext::CCC_ObjCImplementation;
+
+  case Sema::PCC_ObjCInstanceVariableList:
+    return CodeCompletionContext::CCC_ObjCIvarList;
+      
+  case Sema::PCC_Template:
+  case Sema::PCC_MemberTemplate:
+  case Sema::PCC_RecoveryInFunction:
+    return CodeCompletionContext::CCC_Other;
+      
+  case Sema::PCC_Expression:
+  case Sema::PCC_ForInit:
+  case Sema::PCC_Condition:
+    return CodeCompletionContext::CCC_Expression;
+      
+  case Sema::PCC_Statement:
+    return CodeCompletionContext::CCC_Statement;
+
+  case Sema::PCC_Type:
+    return CodeCompletionContext::CCC_Type;
+  }
+  
+  return CodeCompletionContext::CCC_Other;
+}
+
+/// \brief If we're in a C++ virtual member function, add completion results
+/// that invoke the functions we override, since it's common to invoke the 
+/// overridden function as well as adding new functionality.
+///
+/// \param S The semantic analysis object for which we are generating results.
+///
+/// \param InContext This context in which the nested-name-specifier preceding
+/// the code-completion point 
+static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
+                                  ResultBuilder &Results) {
+  // Look through blocks.
+  DeclContext *CurContext = S.CurContext;
+  while (isa<BlockDecl>(CurContext))
+    CurContext = CurContext->getParent();
+  
+  
+  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(CurContext);
+  if (!Method || !Method->isVirtual())
+    return;
+  
+  // We need to have names for all of the parameters, if we're going to 
+  // generate a forwarding call.
+  for (CXXMethodDecl::param_iterator P = Method->param_begin(),
+                                  PEnd = Method->param_end();
+       P != PEnd;
+       ++P) {
+    if (!(*P)->getDeclName())
+      return;
+  }
+
+  for (CXXMethodDecl::method_iterator M = Method->begin_overridden_methods(),
+                                   MEnd = Method->end_overridden_methods();
+       M != MEnd; ++M) {
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    CXXMethodDecl *Overridden = const_cast<CXXMethodDecl *>(*M);
+    if (Overridden->getCanonicalDecl() == Method->getCanonicalDecl())
+      continue;
+        
+    // If we need a nested-name-specifier, add one now.
+    if (!InContext) {
+      NestedNameSpecifier *NNS
+        = getRequiredQualification(S.Context, CurContext,
+                                   Overridden->getDeclContext());
+      if (NNS) {
+        std::string Str;
+        llvm::raw_string_ostream OS(Str);
+        NNS->print(OS, S.Context.PrintingPolicy);
+        Pattern->AddTextChunk(OS.str());
+      }
+    } else if (!InContext->Equals(Overridden->getDeclContext()))
+      continue;
+    
+    Pattern->AddTypedTextChunk(Overridden->getNameAsString());
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    bool FirstParam = true;
+    for (CXXMethodDecl::param_iterator P = Method->param_begin(),
+                                    PEnd = Method->param_end();
+         P != PEnd; ++P) {
+      if (FirstParam)
+        FirstParam = false;
+      else
+        Pattern->AddChunk(CodeCompletionString::CK_Comma);
+
+      Pattern->AddPlaceholderChunk((*P)->getIdentifier()->getName());
+    }
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern,
+                                           CCP_SuperCompletion,
+                                           CXCursor_CXXMethod));
+    Results.Ignore(Overridden);
+  }
+}
+
 void Sema::CodeCompleteOrdinaryName(Scope *S, 
-                                    CodeCompletionContext CompletionContext) {
-  typedef CodeCompleteConsumer::Result Result;
-  ResultBuilder Results(*this);
+                                    ParserCompletionContext CompletionContext) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);  
+  Results.EnterNewScope();
 
   // Determine how to filter results, e.g., so that the names of
   // values (functions, enumerators, function templates, etc.) are
   // only allowed where we can have an expression.
   switch (CompletionContext) {
-  case CCC_Namespace:
-  case CCC_Class:
-  case CCC_ObjCInterface:
-  case CCC_ObjCImplementation:
-  case CCC_ObjCInstanceVariableList:
-  case CCC_Template:
-  case CCC_MemberTemplate:
+  case PCC_Namespace:
+  case PCC_Class:
+  case PCC_ObjCInterface:
+  case PCC_ObjCImplementation:
+  case PCC_ObjCInstanceVariableList:
+  case PCC_Template:
+  case PCC_MemberTemplate:
+  case PCC_Type:
     Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
     break;
 
-  case CCC_Expression:
-  case CCC_Statement:
-  case CCC_ForInit:
-  case CCC_Condition:
+  case PCC_Statement:
+    // For statements that are expressions, we prefer to call 'void' functions 
+    // rather than functions that return a result, since then the result would
+    // be ignored.
+    Results.setPreferredType(Context.VoidTy);
+    // Fall through
+      
+  case PCC_Expression:
+  case PCC_ForInit:
+  case PCC_Condition:
     if (WantTypesInContext(CompletionContext, getLangOptions()))
       Results.setFilter(&ResultBuilder::IsOrdinaryName);
     else
       Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
+      
+    if (getLangOptions().CPlusPlus)
+      MaybeAddOverrideCalls(*this, /*InContext=*/0, Results);
     break;
       
-  case CCC_RecoveryInFunction:
+  case PCC_RecoveryInFunction:
     // Unfiltered
     break;
   }
 
+  // If we are in a C++ non-static member function, check the qualifiers on
+  // the member function to filter/prioritize the results list.
+  if (CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext))
+    if (CurMethod->isInstance())
+      Results.setObjectTypeQualifiers(
+                      Qualifiers::fromCVRMask(CurMethod->getTypeQualifiers()));
+  
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
 
-  Results.EnterNewScope();
   AddOrdinaryNameResults(CompletionContext, S, *this, Results);
   Results.ExitScope();
 
+  switch (CompletionContext) {
+  case PCC_Expression:
+  case PCC_Statement:
+  case PCC_RecoveryInFunction:
+    if (S->getFnParent())
+      AddPrettyFunctionResults(PP.getLangOptions(), Results);        
+    break;
+    
+  case PCC_Namespace:
+  case PCC_Class:
+  case PCC_ObjCInterface:
+  case PCC_ObjCImplementation:
+  case PCC_ObjCInstanceVariableList:
+  case PCC_Template:
+  case PCC_MemberTemplate:
+  case PCC_ForInit:
+  case PCC_Condition:
+  case PCC_Type:
+    break;
+  }
+  
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            mapCodeCompletionContext(*this, CompletionContext),
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteDeclarator(Scope *S,
+                                  bool AllowNonIdentifiers,
+                                  bool AllowNestedNameSpecifiers) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);    
+  Results.EnterNewScope();
+  
+  // Type qualifiers can come after names.
+  Results.AddResult(Result("const"));
+  Results.AddResult(Result("volatile"));
+  if (getLangOptions().C99)
+    Results.AddResult(Result("restrict"));
+
+  if (getLangOptions().CPlusPlus) {
+    if (AllowNonIdentifiers) {
+      Results.AddResult(Result("operator")); 
+    }
+    
+    // Add nested-name-specifiers.
+    if (AllowNestedNameSpecifiers) {
+      Results.allowNestedNameSpecifiers();
+      CodeCompletionDeclConsumer Consumer(Results, CurContext);
+      LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer,
+                         CodeCompleter->includeGlobals());
+    }
+  }
+  Results.ExitScope();
+
+  // Note that we intentionally suppress macro results here, since we do not
+  // encourage using macros to produce the names of entities.
+
+  HandleCodeCompleteResults(this, CodeCompleter,
+                        AllowNestedNameSpecifiers
+                          ? CodeCompletionContext::CCC_PotentiallyQualifiedName
+                          : CodeCompletionContext::CCC_Name,
+                            Results.data(), Results.size());
 }
 
+struct Sema::CodeCompleteExpressionData {
+  CodeCompleteExpressionData(QualType PreferredType = QualType()) 
+    : PreferredType(PreferredType), IntegralConstantExpression(false),
+      ObjCCollection(false) { }
+  
+  QualType PreferredType;
+  bool IntegralConstantExpression;
+  bool ObjCCollection;
+  llvm::SmallVector<Decl *, 4> IgnoreDecls;
+};
+
 /// \brief Perform code-completion in an expression context when we know what
 /// type we're looking for.
-void Sema::CodeCompleteExpression(Scope *S, QualType T) {
-  typedef CodeCompleteConsumer::Result Result;
+///
+/// \param IntegralConstantExpression Only permit integral constant 
+/// expressions.
+void Sema::CodeCompleteExpression(Scope *S, 
+                                  const CodeCompleteExpressionData &Data) {
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   
-  if (WantTypesInContext(CCC_Expression, getLangOptions()))
+  if (Data.ObjCCollection)
+    Results.setFilter(&ResultBuilder::IsObjCCollection);
+  else if (Data.IntegralConstantExpression)
+    Results.setFilter(&ResultBuilder::IsIntegralConstantValue);
+  else if (WantTypesInContext(PCC_Expression, getLangOptions()))
     Results.setFilter(&ResultBuilder::IsOrdinaryName);
   else
     Results.setFilter(&ResultBuilder::IsOrdinaryNonTypeName);
-  Results.setPreferredType(T.getNonReferenceType());
+
+  if (!Data.PreferredType.isNull())
+    Results.setPreferredType(Data.PreferredType.getNonReferenceType());
+  
+  // Ignore any declarations that we were told that we don't care about.
+  for (unsigned I = 0, N = Data.IgnoreDecls.size(); I != N; ++I)
+    Results.Ignore(Data.IgnoreDecls[I]);
   
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   Results.EnterNewScope();
-  AddOrdinaryNameResults(CCC_Expression, S, *this, Results);
+  AddOrdinaryNameResults(PCC_Expression, S, *this, Results);
   Results.ExitScope();
   
   bool PreferredTypeIsPointer = false;
-  if (!T.isNull())
-    PreferredTypeIsPointer = T->isAnyPointerType() || 
-      T->isMemberPointerType() || T->isBlockPointerType();
+  if (!Data.PreferredType.isNull())
+    PreferredTypeIsPointer = Data.PreferredType->isAnyPointerType()
+      || Data.PreferredType->isMemberPointerType() 
+      || Data.PreferredType->isBlockPointerType();
   
+  if (S->getFnParent() && 
+      !Data.ObjCCollection && 
+      !Data.IntegralConstantExpression)
+    AddPrettyFunctionResults(PP.getLangOptions(), Results);        
+
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results, PreferredTypeIsPointer);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                CodeCompletionContext(CodeCompletionContext::CCC_Expression, 
+                                      Data.PreferredType),
+                            Results.data(),Results.size());
 }
 
 
@@ -2303,7 +2725,7 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
                               bool AllowCategories,
                               DeclContext *CurContext,
                               ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
 
   // Add properties in this container.
   for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
@@ -2327,9 +2749,9 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
     }
     
     // Look through protocols.
-    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
-                                              E = IFace->protocol_end(); 
-         I != E; ++I)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         I = IFace->all_referenced_protocol_begin(),
+         E = IFace->all_referenced_protocol_end(); I != E; ++I)
       AddObjCProperties(*I, AllowCategories, CurContext, Results);
     
     // Look in the superclass.
@@ -2339,8 +2761,8 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
   } else if (const ObjCCategoryDecl *Category
                                     = dyn_cast<ObjCCategoryDecl>(Container)) {
     // Look through protocols.
-    for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
-                                           PEnd = Category->protocol_end(); 
+    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
+                                          PEnd = Category->protocol_end(); 
          P != PEnd; ++P)
       AddObjCProperties(*P, AllowCategories, CurContext, Results);
   }
@@ -2352,7 +2774,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
   if (!BaseE || !CodeCompleter)
     return;
   
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   Expr *Base = static_cast<Expr *>(BaseE);
   QualType BaseType = Base->getType();
@@ -2361,7 +2783,7 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
     if (const PointerType *Ptr = BaseType->getAs<PointerType>())
       BaseType = Ptr->getPointeeType();
     else if (BaseType->isObjCObjectPointerType())
-    /*Do nothing*/ ;
+      /*Do nothing*/ ;
     else
       return;
   }
@@ -2369,10 +2791,15 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
   ResultBuilder Results(*this, &ResultBuilder::IsMember);
   Results.EnterNewScope();
   if (const RecordType *Record = BaseType->getAs<RecordType>()) {
+    // Indicate that we are performing a member access, and the cv-qualifiers
+    // for the base object type.
+    Results.setObjectTypeQualifiers(BaseType.getQualifiers());
+    
     // Access to a C/C++ class, struct, or union.
     Results.allowNestedNameSpecifiers();
     CodeCompletionDeclConsumer Consumer(Results, CurContext);
-    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
+    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
+                       CodeCompleter->includeGlobals());
 
     if (getLangOptions().CPlusPlus) {
       if (!Results.empty()) {
@@ -2420,7 +2847,8 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
     if (Class) {
       CodeCompletionDeclConsumer Consumer(Results, CurContext);
       Results.setFilter(&ResultBuilder::IsObjCIvar);
-      LookupVisibleDecls(Class, LookupMemberName, Consumer);
+      LookupVisibleDecls(Class, LookupMemberName, Consumer,
+                         CodeCompleter->includeGlobals());
     }
   }
   
@@ -2429,27 +2857,35 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
   Results.ExitScope();
 
   // Hand off the results found for code completion.
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+            CodeCompletionContext(CodeCompletionContext::CCC_MemberAccess,
+                                              BaseType),
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
   if (!CodeCompleter)
     return;
   
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder::LookupFilter Filter = 0;
+  enum CodeCompletionContext::Kind ContextKind
+    = CodeCompletionContext::CCC_Other;
   switch ((DeclSpec::TST)TagSpec) {
   case DeclSpec::TST_enum:
     Filter = &ResultBuilder::IsEnum;
+    ContextKind = CodeCompletionContext::CCC_EnumTag;
     break;
     
   case DeclSpec::TST_union:
     Filter = &ResultBuilder::IsUnion;
+    ContextKind = CodeCompletionContext::CCC_UnionTag;
     break;
     
   case DeclSpec::TST_struct:
   case DeclSpec::TST_class:
     Filter = &ResultBuilder::IsClassOrStruct;
+    ContextKind = CodeCompletionContext::CCC_ClassOrStructTag;
     break;
     
   default:
@@ -2462,22 +2898,46 @@ void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
 
   // First pass: look for tags.
   Results.setFilter(Filter);
-  LookupVisibleDecls(S, LookupTagName, Consumer);
+  LookupVisibleDecls(S, LookupTagName, Consumer,
+                     CodeCompleter->includeGlobals());
 
-  // Second pass: look for nested name specifiers.
-  Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
-  LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  if (CodeCompleter->includeGlobals()) {
+    // Second pass: look for nested name specifiers.
+    Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
+    LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
+  }
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, ContextKind,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
+    Results.AddResult("const");
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
+    Results.AddResult("volatile");
+  if (getLangOptions().C99 &&
+      !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
+    Results.AddResult("restrict");
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_TypeQualifiers,
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteCase(Scope *S) {
-  if (getSwitchStack().empty() || !CodeCompleter)
+  if (getCurFunction()->SwitchStack.empty() || !CodeCompleter)
     return;
   
-  SwitchStmt *Switch = getSwitchStack().back();
-  if (!Switch->getCond()->getType()->isEnumeralType())
+  SwitchStmt *Switch = getCurFunction()->SwitchStack.back();
+  if (!Switch->getCond()->getType()->isEnumeralType()) {
+    CodeCompleteExpressionData Data(Switch->getCond()->getType());
+    Data.IntegralConstantExpression = true;
+    CodeCompleteExpression(S, Data);
     return;
+  }
   
   // Code-complete the cases of a switch statement over an enumeration type
   // by providing the list of 
@@ -2541,14 +3001,16 @@ void Sema::CodeCompleteCase(Scope *S) {
     if (EnumeratorsSeen.count(*E))
       continue;
     
-    Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
+    Results.AddResult(CodeCompletionResult(*E, Qualifier),
                       CurContext, 0, false);
   }
   Results.ExitScope();
 
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Expression,
+                            Results.data(),Results.size());
 }
 
 namespace {
@@ -2562,7 +3024,7 @@ namespace {
     
     bool 
     operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
-      return S.isBetterOverloadCandidate(X, Y, Loc);
+      return isBetterOverloadCandidate(S, X, Y, Loc);
     }
   };
 }
@@ -2594,7 +3056,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
   // Ignore type-dependent call expressions entirely.
   if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args, NumArgs) ||
       Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
-    CodeCompleteOrdinaryName(S, CCC_Expression);
+    CodeCompleteOrdinaryName(S, PCC_Expression);
     return;
   }
 
@@ -2678,7 +3140,7 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
   }
 
   if (ParamType.isNull())
-    CodeCompleteOrdinaryName(S, CCC_Expression);
+    CodeCompleteOrdinaryName(S, PCC_Expression);
   else
     CodeCompleteExpression(S, ParamType);
   
@@ -2687,10 +3149,10 @@ void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
                                              Results.size());
 }
 
-void Sema::CodeCompleteInitializer(Scope *S, DeclPtrTy D) {
-  ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D.getAs<Decl>());
+void Sema::CodeCompleteInitializer(Scope *S, Decl *D) {
+  ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D);
   if (!VD) {
-    CodeCompleteOrdinaryName(S, CCC_Expression);
+    CodeCompleteOrdinaryName(S, PCC_Expression);
     return;
   }
   
@@ -2708,7 +3170,7 @@ void Sema::CodeCompleteReturn(Scope *S) {
     ResultType = Method->getResultType();
   
   if (ResultType.isNull())
-    CodeCompleteOrdinaryName(S, CCC_Expression);
+    CodeCompleteOrdinaryName(S, PCC_Expression);
   else
     CodeCompleteExpression(S, ResultType);
 }
@@ -2717,7 +3179,7 @@ void Sema::CodeCompleteAssignmentRHS(Scope *S, ExprTy *LHS) {
   if (LHS)
     CodeCompleteExpression(S, static_cast<Expr *>(LHS)->getType());
   else
-    CodeCompleteOrdinaryName(S, CCC_Expression);
+    CodeCompleteOrdinaryName(S, PCC_Expression);
 }
 
 void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
@@ -2735,16 +3197,29 @@ void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
     return;
 
   ResultBuilder Results(*this);
-  CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
   
+  Results.EnterNewScope();
   // The "template" keyword can follow "::" in the grammar, but only
   // put it into the grammar if the nested-name-specifier is dependent.
   NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
   if (!Results.empty() && NNS->isDependent())
     Results.AddResult("template");
+
+  // Add calls to overridden virtual functions, if there are any.
+  //
+  // FIXME: This isn't wonderful, because we don't know whether we're actually
+  // in a context that permits expressions. This is a general issue with
+  // qualified-id completions.
+  if (!EnteringContext)
+    MaybeAddOverrideCalls(*this, Ctx, Results);
+  Results.ExitScope();  
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
+
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Name,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteUsing(Scope *S) {
@@ -2756,15 +3231,18 @@ void Sema::CodeCompleteUsing(Scope *S) {
   
   // If we aren't in class scope, we could see the "namespace" keyword.
   if (!S->isClassScope())
-    Results.AddResult(CodeCompleteConsumer::Result("namespace"));
+    Results.AddResult(CodeCompletionResult("namespace"));
   
   // After "using", we can see anything that would start a 
   // nested-name-specifier.
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteUsingDirective(Scope *S) {
@@ -2776,9 +3254,12 @@ void Sema::CodeCompleteUsingDirective(Scope *S) {
   ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
   Results.EnterNewScope();
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Namespace,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteNamespaceDecl(Scope *S)  {
@@ -2807,12 +3288,14 @@ void Sema::CodeCompleteNamespaceDecl(Scope *S)  {
     for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator 
          NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
          NS != NSEnd; ++NS)
-      Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
+      Results.AddResult(CodeCompletionResult(NS->second, 0),
                         CurContext, 0, false);
     Results.ExitScope();
   }
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteNamespaceAliasDecl(Scope *S)  {
@@ -2822,15 +3305,18 @@ void Sema::CodeCompleteNamespaceAliasDecl(Scope *S)  {
   // After "namespace", we expect to see a namespace or alias.
   ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Namespace,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteOperatorName(Scope *S) {
   if (!CodeCompleter)
     return;
 
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this, &ResultBuilder::IsType);
   Results.EnterNewScope();
   
@@ -2843,13 +3329,122 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
   // Add any type names visible from the current scope
   Results.allowNestedNameSpecifiers();
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   // Add any type specifiers
   AddTypeSpecifierResults(getLangOptions(), Results);
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Type,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteConstructorInitializer(Decl *ConstructorD,
+                                    CXXBaseOrMemberInitializer** Initializers,
+                                              unsigned NumInitializers) {
+  CXXConstructorDecl *Constructor
+    = static_cast<CXXConstructorDecl *>(ConstructorD);
+  if (!Constructor)
+    return;
+  
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Fill in any already-initialized fields or base classes.
+  llvm::SmallPtrSet<FieldDecl *, 4> InitializedFields;
+  llvm::SmallPtrSet<CanQualType, 4> InitializedBases;
+  for (unsigned I = 0; I != NumInitializers; ++I) {
+    if (Initializers[I]->isBaseInitializer())
+      InitializedBases.insert(
+        Context.getCanonicalType(QualType(Initializers[I]->getBaseClass(), 0)));
+    else
+      InitializedFields.insert(cast<FieldDecl>(Initializers[I]->getMember()));
+  }
+  
+  // Add completions for base classes.
+  bool SawLastInitializer = (NumInitializers == 0);
+  CXXRecordDecl *ClassDecl = Constructor->getParent();
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+                                       BaseEnd = ClassDecl->bases_end();
+       Base != BaseEnd; ++Base) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
+      SawLastInitializer
+        = NumInitializers > 0 && 
+          Initializers[NumInitializers - 1]->isBaseInitializer() &&
+          Context.hasSameUnqualifiedType(Base->getType(),
+               QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
+      continue;
+    }
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(
+                           Base->getType().getAsString(Context.PrintingPolicy));
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, 
+                                   SawLastInitializer? CCP_NextInitializer
+                                                     : CCP_MemberDeclaration));
+    SawLastInitializer = false;
+  }
+  
+  // Add completions for virtual base classes.
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                       BaseEnd = ClassDecl->vbases_end();
+       Base != BaseEnd; ++Base) {
+    if (!InitializedBases.insert(Context.getCanonicalType(Base->getType()))) {
+      SawLastInitializer
+        = NumInitializers > 0 && 
+          Initializers[NumInitializers - 1]->isBaseInitializer() &&
+          Context.hasSameUnqualifiedType(Base->getType(),
+               QualType(Initializers[NumInitializers - 1]->getBaseClass(), 0));
+      continue;
+    }
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(
+                           Base->getType().getAsString(Context.PrintingPolicy));
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, 
+                                   SawLastInitializer? CCP_NextInitializer
+                                                     : CCP_MemberDeclaration));
+    SawLastInitializer = false;
+  }
+  
+  // Add completions for members.
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                  FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    if (!InitializedFields.insert(cast<FieldDecl>(Field->getCanonicalDecl()))) {
+      SawLastInitializer
+        = NumInitializers > 0 && 
+          Initializers[NumInitializers - 1]->isMemberInitializer() &&
+          Initializers[NumInitializers - 1]->getMember() == *Field;
+      continue;
+    }
+    
+    if (!Field->getDeclName())
+      continue;
+    
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk(Field->getIdentifier()->getName());
+    Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+    Pattern->AddPlaceholderChunk("args");
+    Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(CodeCompletionResult(Pattern, 
+                                   SawLastInitializer? CCP_NextInitializer
+                                                     : CCP_MemberDeclaration));
+    SawLastInitializer = false;
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Name,
+                            Results.data(), Results.size());
 }
 
 // Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
@@ -2858,7 +3453,7 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
 static void AddObjCImplementationResults(const LangOptions &LangOpts,
                                          ResultBuilder &Results,
                                          bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   // Since we have an implementation, we can end it.
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
   
@@ -2883,7 +3478,7 @@ static void AddObjCImplementationResults(const LangOptions &LangOpts,
 static void AddObjCInterfaceResults(const LangOptions &LangOpts,
                                     ResultBuilder &Results,
                                     bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   // Since we have an interface or protocol, we can end it.
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
@@ -2901,7 +3496,7 @@ static void AddObjCInterfaceResults(const LangOptions &LangOpts,
 }
 
 static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   CodeCompletionString *Pattern = 0;
   
   // @class name ;
@@ -2946,9 +3541,9 @@ static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
   Results.AddResult(Result(Pattern));
 }
 
-void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
+void Sema::CodeCompleteObjCAtDirective(Scope *S, Decl *ObjCImpDecl,
                                        bool InInterface) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   Results.EnterNewScope();
   if (ObjCImpDecl)
@@ -2958,11 +3553,13 @@ void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
   else
     AddObjCTopLevelResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   CodeCompletionString *Pattern = 0;
 
   // @encode ( type-name )
@@ -2991,7 +3588,7 @@ static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
 }
 
 static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   CodeCompletionString *Pattern = 0;
   
   if (Results.includeCodePatterns()) {
@@ -3041,7 +3638,7 @@ static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
 static void AddObjCVisibilityResults(const LangOptions &LangOpts,
                                      ResultBuilder &Results,
                                      bool NeedAt) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
   Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
@@ -3054,7 +3651,9 @@ void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
   Results.EnterNewScope();
   AddObjCVisibilityResults(getLangOptions(), Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCAtStatement(Scope *S) {
@@ -3063,7 +3662,9 @@ void Sema::CodeCompleteObjCAtStatement(Scope *S) {
   AddObjCStatementResults(Results, false);
   AddObjCExpressionResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCAtExpression(Scope *S) {
@@ -3071,7 +3672,9 @@ void Sema::CodeCompleteObjCAtExpression(Scope *S) {
   Results.EnterNewScope();
   AddObjCExpressionResults(Results, false);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 /// \brief Determine whether the addition of the given flag to an Objective-C
@@ -3110,37 +3713,39 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
   
   unsigned Attributes = ODS.getPropertyAttributes();
   
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   Results.EnterNewScope();
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
-    Results.AddResult(CodeCompleteConsumer::Result("readonly"));
+    Results.AddResult(CodeCompletionResult("readonly"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
-    Results.AddResult(CodeCompleteConsumer::Result("assign"));
+    Results.AddResult(CodeCompletionResult("assign"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
-    Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
+    Results.AddResult(CodeCompletionResult("readwrite"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
-    Results.AddResult(CodeCompleteConsumer::Result("retain"));
+    Results.AddResult(CodeCompletionResult("retain"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
-    Results.AddResult(CodeCompleteConsumer::Result("copy"));
+    Results.AddResult(CodeCompletionResult("copy"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
-    Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
+    Results.AddResult(CodeCompletionResult("nonatomic"));
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
     CodeCompletionString *Setter = new CodeCompletionString;
     Setter->AddTypedTextChunk("setter");
     Setter->AddTextChunk(" = ");
     Setter->AddPlaceholderChunk("method");
-    Results.AddResult(CodeCompleteConsumer::Result(Setter));
+    Results.AddResult(CodeCompletionResult(Setter));
   }
   if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
     CodeCompletionString *Getter = new CodeCompletionString;
     Getter->AddTypedTextChunk("getter");
     Getter->AddTextChunk(" = ");
     Getter->AddPlaceholderChunk("method");
-    Results.AddResult(CodeCompleteConsumer::Result(Getter));
+    Results.AddResult(CodeCompletionResult(Getter));
   }
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 /// \brief Descripts the kind of Objective-C method that we want to find
@@ -3151,26 +3756,33 @@ enum ObjCMethodKind {
   MK_OneArgSelector //< One-argument selector.
 };
 
-static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
-                                   ObjCMethodKind WantKind,
-                                   IdentifierInfo **SelIdents,
-                                   unsigned NumSelIdents) {
-  Selector Sel = Method->getSelector();
+static bool isAcceptableObjCSelector(Selector Sel,
+                                     ObjCMethodKind WantKind,
+                                     IdentifierInfo **SelIdents,
+                                     unsigned NumSelIdents) {
   if (NumSelIdents > Sel.getNumArgs())
     return false;
-      
+  
   switch (WantKind) {
-  case MK_Any:             break;
-  case MK_ZeroArgSelector: return Sel.isUnarySelector();
-  case MK_OneArgSelector:  return Sel.getNumArgs() == 1;
+    case MK_Any:             break;
+    case MK_ZeroArgSelector: return Sel.isUnarySelector();
+    case MK_OneArgSelector:  return Sel.getNumArgs() == 1;
   }
-
+  
   for (unsigned I = 0; I != NumSelIdents; ++I)
     if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
       return false;
-
+  
   return true;
 }
+
+static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
+                                   ObjCMethodKind WantKind,
+                                   IdentifierInfo **SelIdents,
+                                   unsigned NumSelIdents) {
+  return isAcceptableObjCSelector(Method->getSelector(), WantKind, SelIdents,
+                                  NumSelIdents);
+}
                                    
 /// \brief Add all of the Objective-C methods in the given Objective-C 
 /// container to the set of results.
@@ -3195,8 +3807,9 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
                            IdentifierInfo **SelIdents,
                            unsigned NumSelIdents,
                            DeclContext *CurContext,
-                           ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+                           ResultBuilder &Results,
+                           bool InOriginalClass = true) {
+  typedef CodeCompletionResult Result;
   for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
                                        MEnd = Container->meth_end();
        M != MEnd; ++M) {
@@ -3209,6 +3822,8 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
       Result R = Result(*M, 0);
       R.StartParameter = NumSelIdents;
       R.AllParametersAreInformative = (WantKind != MK_Any);
+      if (!InOriginalClass)
+        R.Priority += CCD_InBaseClass;
       Results.MaybeAddResult(R, CurContext);
     }
   }
@@ -3223,13 +3838,13 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
                                             E = Protocols.end(); 
        I != E; ++I)
     AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents, 
-                   CurContext, Results);
+                   CurContext, Results, false);
   
   // Add methods in categories.
   for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
        CatDecl = CatDecl->getNextClassCategory()) {
     AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents, 
-                   NumSelIdents, CurContext, Results);
+                   NumSelIdents, CurContext, Results, InOriginalClass);
     
     // Add a categories protocol methods.
     const ObjCList<ObjCProtocolDecl> &Protocols 
@@ -3238,37 +3853,36 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
                                               E = Protocols.end();
          I != E; ++I)
       AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                     NumSelIdents, CurContext, Results);
+                     NumSelIdents, CurContext, Results, false);
     
     // Add methods in category implementations.
     if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
       AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 
-                     NumSelIdents, CurContext, Results);
+                     NumSelIdents, CurContext, Results, InOriginalClass);
   }
   
   // Add methods in superclass.
   if (IFace->getSuperClass())
     AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 
-                   SelIdents, NumSelIdents, CurContext, Results);
+                   SelIdents, NumSelIdents, CurContext, Results, false);
 
   // Add methods in our implementation, if any.
   if (ObjCImplementationDecl *Impl = IFace->getImplementation())
     AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
-                   NumSelIdents, CurContext, Results);
+                   NumSelIdents, CurContext, Results, InOriginalClass);
 }
 
 
-void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
-                                          DeclPtrTy *Methods,
+void Sema::CodeCompleteObjCPropertyGetter(Scope *S, Decl *ClassDecl,
+                                          Decl **Methods,
                                           unsigned NumMethods) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
 
   // Try to find the interface where getters might live.
-  ObjCInterfaceDecl *Class
-    = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
+  ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl);
   if (!Class) {
     if (ObjCCategoryDecl *Category
-          = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
+          = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl))
       Class = Category->getClassInterface();
 
     if (!Class)
@@ -3283,7 +3897,7 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
   // pushed into DeclContexts early enough. Argh!
   for (unsigned I = 0; I != NumMethods; ++I) { 
     if (ObjCMethodDecl *Method
-            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
       if (Method->isInstanceMethod() &&
           isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
         Result R = Result(Method, 0);
@@ -3294,20 +3908,22 @@ void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
 
   AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
-void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
-                                          DeclPtrTy *Methods,
+void Sema::CodeCompleteObjCPropertySetter(Scope *S, Decl *ObjCImplDecl,
+                                          Decl **Methods,
                                           unsigned NumMethods) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
 
   // Try to find the interface where setters might live.
   ObjCInterfaceDecl *Class
-    = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
+    = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl);
   if (!Class) {
     if (ObjCCategoryDecl *Category
-          = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
+          = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl))
       Class = Category->getClassInterface();
 
     if (!Class)
@@ -3322,7 +3938,7 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
   // pushed into DeclContexts early enough. Argh!
   for (unsigned I = 0; I != NumMethods; ++I) { 
     if (ObjCMethodDecl *Method
-            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
+            = dyn_cast_or_null<ObjCMethodDecl>(Methods[I]))
       if (Method->isInstanceMethod() &&
           isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
         Result R = Result(Method, 0);
@@ -3334,7 +3950,54 @@ void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
   AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCPassingType(Scope *S, ObjCDeclSpec &DS) {
+  typedef CodeCompletionResult Result;
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // Add context-sensitive, Objective-C parameter-passing keywords.
+  bool AddedInOut = false;
+  if ((DS.getObjCDeclQualifier() & 
+       (ObjCDeclSpec::DQ_In | ObjCDeclSpec::DQ_Inout)) == 0) {
+    Results.AddResult("in");
+    Results.AddResult("inout");
+    AddedInOut = true;
+  }
+  if ((DS.getObjCDeclQualifier() & 
+       (ObjCDeclSpec::DQ_Out | ObjCDeclSpec::DQ_Inout)) == 0) {
+    Results.AddResult("out");
+    if (!AddedInOut)
+      Results.AddResult("inout");
+  }
+  if ((DS.getObjCDeclQualifier() & 
+       (ObjCDeclSpec::DQ_Bycopy | ObjCDeclSpec::DQ_Byref |
+        ObjCDeclSpec::DQ_Oneway)) == 0) {
+     Results.AddResult("bycopy");
+     Results.AddResult("byref");
+     Results.AddResult("oneway");
+  }
+  
+  // Add various builtin type names and specifiers.
+  AddOrdinaryNameResults(PCC_Type, S, *this, Results);
+  Results.ExitScope();
+  
+  // Add the various type names
+  Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
+  CodeCompletionDeclConsumer Consumer(Results, CurContext);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
+  
+  if (CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Type,
+                            Results.data(), Results.size());
 }
 
 /// \brief When we have an expression with type "id", we may assume
@@ -3407,28 +4070,138 @@ static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
     .Default(0);
 }
 
+// Add a special completion for a message send to "super", which fills in the
+// most likely case of forwarding all of our arguments to the superclass 
+// function.
+///
+/// \param S The semantic analysis object.
+///
+/// \param S NeedSuperKeyword Whether we need to prefix this completion with
+/// the "super" keyword. Otherwise, we just need to provide the arguments.
+///
+/// \param SelIdents The identifiers in the selector that have already been
+/// provided as arguments for a send to "super".
+///
+/// \param NumSelIdents The number of identifiers in \p SelIdents.
+///
+/// \param Results The set of results to augment.
+///
+/// \returns the Objective-C method declaration that would be invoked by 
+/// this "super" completion. If NULL, no completion was added.
+static ObjCMethodDecl *AddSuperSendCompletion(Sema &S, bool NeedSuperKeyword,
+                                              IdentifierInfo **SelIdents,
+                                              unsigned NumSelIdents,
+                                              ResultBuilder &Results) {
+  ObjCMethodDecl *CurMethod = S.getCurMethodDecl();
+  if (!CurMethod)
+    return 0;
+  
+  ObjCInterfaceDecl *Class = CurMethod->getClassInterface();
+  if (!Class)
+    return 0;
+  
+  // Try to find a superclass method with the same selector.
+  ObjCMethodDecl *SuperMethod = 0;
+  while ((Class = Class->getSuperClass()) && !SuperMethod)
+    SuperMethod = Class->getMethod(CurMethod->getSelector(), 
+                                   CurMethod->isInstanceMethod());
+
+  if (!SuperMethod)
+    return 0;
+  
+  // Check whether the superclass method has the same signature.
+  if (CurMethod->param_size() != SuperMethod->param_size() ||
+      CurMethod->isVariadic() != SuperMethod->isVariadic())
+    return 0;
+      
+  for (ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin(),
+                                   CurPEnd = CurMethod->param_end(),
+                                    SuperP = SuperMethod->param_begin();
+       CurP != CurPEnd; ++CurP, ++SuperP) {
+    // Make sure the parameter types are compatible.
+    if (!S.Context.hasSameUnqualifiedType((*CurP)->getType(), 
+                                          (*SuperP)->getType()))
+      return 0;
+    
+    // Make sure we have a parameter name to forward!
+    if (!(*CurP)->getIdentifier())
+      return 0;
+  }
+  
+  // We have a superclass method. Now, form the send-to-super completion.
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  
+  // Give this completion a return type.
+  AddResultTypeChunk(S.Context, SuperMethod, Pattern);
+
+  // If we need the "super" keyword, add it (plus some spacing).
+  if (NeedSuperKeyword) {
+    Pattern->AddTypedTextChunk("super");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  }
+  
+  Selector Sel = CurMethod->getSelector();
+  if (Sel.isUnarySelector()) {
+    if (NeedSuperKeyword)
+      Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+    else
+      Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+  } else {
+    ObjCMethodDecl::param_iterator CurP = CurMethod->param_begin();
+    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I, ++CurP) {
+      if (I > NumSelIdents)
+        Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+      
+      if (I < NumSelIdents)
+        Pattern->AddInformativeChunk(
+                       Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+      else if (NeedSuperKeyword || I > NumSelIdents) {
+        Pattern->AddTextChunk(
+                        Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+        Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());
+      } else {
+        Pattern->AddTypedTextChunk(
+                              Sel.getIdentifierInfoForSlot(I)->getName().str() + ":");
+        Pattern->AddPlaceholderChunk((*CurP)->getIdentifier()->getName());        
+      }
+    }
+  }
+  
+  Results.AddResult(CodeCompletionResult(Pattern, CCP_SuperCompletion,
+                                         SuperMethod->isInstanceMethod()
+                                           ? CXCursor_ObjCInstanceMethodDecl
+                                           : CXCursor_ObjCClassMethodDecl));
+  return SuperMethod;
+}
+                                   
 void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   
   // Find anything that looks like it could be a message receiver.
   Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
   CodeCompletionDeclConsumer Consumer(Results, CurContext);
   Results.EnterNewScope();
-  LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
+  LookupVisibleDecls(S, LookupOrdinaryName, Consumer,
+                     CodeCompleter->includeGlobals());
   
   // If we are in an Objective-C method inside a class that has a superclass,
   // add "super" as an option.
   if (ObjCMethodDecl *Method = getCurMethodDecl())
     if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
-      if (Iface->getSuperClass())
+      if (Iface->getSuperClass()) {
         Results.AddResult(Result("super"));
+        
+        AddSuperSendCompletion(*this, /*NeedSuperKeyword=*/true, 0, 0, Results);
+      }
   
   Results.ExitScope();
   
   if (CodeCompleter->includeMacros())
     AddMacroResults(PP, Results);
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_ObjCMessageReceiver,
+                            Results.data(), Results.size());
   
 }
 
@@ -3454,10 +4227,11 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
       // an instance method.
       QualType SuperTy = Context.getObjCInterfaceType(CDecl);
       SuperTy = Context.getObjCObjectPointerType(SuperTy);
-      OwningExprResult Super
+      ExprResult Super
         = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
       return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
-                                             SelIdents, NumSelIdents);
+                                             SelIdents, NumSelIdents,
+                                             /*IsSuper=*/true);
     }
 
     // Fall through to send to the superclass in CDecl.
@@ -3480,7 +4254,7 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
       CXXScopeSpec SS;
       UnqualifiedId id;
       id.setIdentifier(Super, SuperLoc);
-      OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
+      ExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
       return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
                                              SelIdents, NumSelIdents);
     }
@@ -3488,17 +4262,24 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
     // Fall through
   }
 
-  TypeTy *Receiver = 0;
+  ParsedType Receiver;
   if (CDecl)
-    Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
+    Receiver = ParsedType::make(Context.getObjCInterfaceType(CDecl));
   return CodeCompleteObjCClassMessage(S, Receiver, SelIdents, 
-                                      NumSelIdents);
+                                      NumSelIdents, /*IsSuper=*/true);
 }
 
-void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
                                         IdentifierInfo **SelIdents,
                                         unsigned NumSelIdents) {
-  typedef CodeCompleteConsumer::Result Result;
+  CodeCompleteObjCClassMessage(S, Receiver, SelIdents, NumSelIdents, false);
+}
+
+void Sema::CodeCompleteObjCClassMessage(Scope *S, ParsedType Receiver,
+                                        IdentifierInfo **SelIdents,
+                                        unsigned NumSelIdents,
+                                        bool IsSuper) {
+  typedef CodeCompletionResult Result;
   ObjCInterfaceDecl *CDecl = 0;
 
   // If the given name refers to an interface type, retrieve the
@@ -3515,6 +4296,20 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
   ResultBuilder Results(*this);
   Results.EnterNewScope();
 
+  // If this is a send-to-super, try to add the special "super" send 
+  // completion.
+  if (IsSuper) {
+    if (ObjCMethodDecl *SuperMethod
+          = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents, 
+                                   Results))
+      Results.Ignore(SuperMethod);
+  }
+
+  // If we're inside an Objective-C method definition, prefer its selector to
+  // others.
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+    Results.setPreferredSelector(CurMethod->getSelector());
+
   if (CDecl) 
     AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext, 
                    Results);  
@@ -3522,25 +4317,23 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
     // We're messaging "id" as a type; provide all class/factory methods.
 
     // If we have an external source, load the entire class method
-    // pool from the PCH file.
+    // pool from the AST file.
     if (ExternalSource) {
       for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
            I != N; ++I) {
         Selector Sel = ExternalSource->GetExternalSelector(I);
-        if (Sel.isNull() || FactoryMethodPool.count(Sel) || 
-            InstanceMethodPool.count(Sel))
+        if (Sel.isNull() || MethodPool.count(Sel))
           continue;
 
-        ReadMethodPool(Sel, /*isInstance=*/false);
+        ReadMethodPool(Sel);
       }
     }
 
-    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
-           M = FactoryMethodPool.begin(),
-           MEnd = FactoryMethodPool.end();
-         M != MEnd;
-         ++M) {
-      for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+    for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                                    MEnd = MethodPool.end();
+         M != MEnd; ++M) {
+      for (ObjCMethodList *MethList = &M->second.second;
+           MethList && MethList->Method; 
            MethList = MethList->Next) {
         if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
                                     NumSelIdents))
@@ -3555,13 +4348,22 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
   }
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(), Results.size());
 }
 
 void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
                                            IdentifierInfo **SelIdents,
                                            unsigned NumSelIdents) {
-  typedef CodeCompleteConsumer::Result Result;
+  CodeCompleteObjCInstanceMessage(S, Receiver, SelIdents, NumSelIdents, false);
+}
+
+void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
+                                           IdentifierInfo **SelIdents,
+                                           unsigned NumSelIdents,
+                                           bool IsSuper) {
+  typedef CodeCompletionResult Result;
   
   Expr *RecExpr = static_cast<Expr *>(Receiver);
   
@@ -3574,6 +4376,20 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
   ResultBuilder Results(*this);
   Results.EnterNewScope();
 
+  // If this is a send-to-super, try to add the special "super" send 
+  // completion.
+  if (IsSuper) {
+    if (ObjCMethodDecl *SuperMethod
+          = AddSuperSendCompletion(*this, false, SelIdents, NumSelIdents, 
+                                   Results))
+      Results.Ignore(SuperMethod);
+  }
+  
+  // If we're inside an Objective-C method definition, prefer its selector to
+  // others.
+  if (ObjCMethodDecl *CurMethod = getCurMethodDecl())
+    Results.setPreferredSelector(CurMethod->getSelector());
+
   // If we're messaging an expression with type "id" or "Class", check
   // whether we know something special about the receiver that allows
   // us to assume a more-specific receiver type.
@@ -3623,25 +4439,23 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
     // about as code-completion results.
 
     // If we have an external source, load the entire class method
-    // pool from the PCH file.
+    // pool from the AST file.
     if (ExternalSource) {
       for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
            I != N; ++I) {
         Selector Sel = ExternalSource->GetExternalSelector(I);
-        if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
-            FactoryMethodPool.count(Sel))
+        if (Sel.isNull() || MethodPool.count(Sel))
           continue;
 
-        ReadMethodPool(Sel, /*isInstance=*/true);
+        ReadMethodPool(Sel);
       }
     }
 
-    for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
-           M = InstanceMethodPool.begin(),
-           MEnd = InstanceMethodPool.end();
-         M != MEnd;
-         ++M) {
-      for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+    for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                                    MEnd = MethodPool.end();
+         M != MEnd; ++M) {
+      for (ObjCMethodList *MethList = &M->second.first;
+           MethList && MethList->Method; 
            MethList = MethList->Next) {
         if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
                                     NumSelIdents))
@@ -3656,7 +4470,79 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
   }
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompleteObjCForCollection(Scope *S, 
+                                         DeclGroupPtrTy IterationVar) {
+  CodeCompleteExpressionData Data;
+  Data.ObjCCollection = true;
+  
+  if (IterationVar.getAsOpaquePtr()) {
+    DeclGroupRef DG = IterationVar.getAsVal<DeclGroupRef>();
+    for (DeclGroupRef::iterator I = DG.begin(), End = DG.end(); I != End; ++I) {
+      if (*I)
+        Data.IgnoreDecls.push_back(*I);
+    }
+  }
+  
+  CodeCompleteExpression(S, Data);
+}
+
+void Sema::CodeCompleteObjCSelector(Scope *S, IdentifierInfo **SelIdents,
+                                    unsigned NumSelIdents) {
+  // If we have an external source, load the entire class method
+  // pool from the AST file.
+  if (ExternalSource) {
+    for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
+         I != N; ++I) {
+      Selector Sel = ExternalSource->GetExternalSelector(I);
+      if (Sel.isNull() || MethodPool.count(Sel))
+        continue;
+      
+      ReadMethodPool(Sel);
+    }
+  }
+  
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                               MEnd = MethodPool.end();
+       M != MEnd; ++M) {
+    
+    Selector Sel = M->first;
+    if (!isAcceptableObjCSelector(Sel, MK_Any, SelIdents, NumSelIdents))
+      continue;
+
+    CodeCompletionString *Pattern = new CodeCompletionString;
+    if (Sel.isUnarySelector()) {
+      Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
+      Results.AddResult(Pattern);
+      continue;
+    }
+    
+    std::string Accumulator;
+    for (unsigned I = 0, N = Sel.getNumArgs(); I != N; ++I) {
+      if (I == NumSelIdents) {
+        if (!Accumulator.empty()) {
+          Pattern->AddInformativeChunk(Accumulator);
+          Accumulator.clear();
+        }
+      }
+      
+      Accumulator += Sel.getIdentifierInfoForSlot(I)->getName().str();
+      Accumulator += ':';
+    }
+    Pattern->AddTypedTextChunk(Accumulator);
+    Results.AddResult(Pattern);
+  }
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_SelectorName,
+                            Results.data(), Results.size());
 }
 
 /// \brief Add all of the protocol declarations that we find in the given
@@ -3664,7 +4550,7 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
 static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
                                bool OnlyForwardDeclarations,
                                ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
                                DEnd = Ctx->decls_end();
@@ -3704,7 +4590,9 @@ void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
                      Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_ObjCProtocolName,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
@@ -3716,7 +4604,9 @@ void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
                      Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_ObjCProtocolName,
+                            Results.data(),Results.size());
 }
 
 /// \brief Add all of the Objective-C interface declarations that we find in
@@ -3725,7 +4615,7 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
                                 bool OnlyForwardDeclarations,
                                 bool OnlyUnimplemented,
                                 ResultBuilder &Results) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   for (DeclContext::decl_iterator D = Ctx->decls_begin(), 
                                DEnd = Ctx->decls_end();
@@ -3757,7 +4647,9 @@ void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
                       false, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
@@ -3776,7 +4668,9 @@ void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
                       false, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCImplementationDecl(Scope *S) { 
@@ -3788,13 +4682,15 @@ void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
                       true, Results);
 
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCInterfaceCategory(Scope *S, 
                                              IdentifierInfo *ClassName,
                                              SourceLocation ClassNameLoc) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   ResultBuilder Results(*this);
   
@@ -3819,13 +4715,15 @@ void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
         Results.AddResult(Result(Category, 0), CurContext, 0, false);
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());  
 }
 
 void Sema::CodeCompleteObjCImplementationCategory(Scope *S, 
                                                   IdentifierInfo *ClassName,
                                                   SourceLocation ClassNameLoc) {
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   
   // Find the corresponding interface. If we couldn't find the interface, the
   // program itself is ill-formed. However, we'll try to be helpful still by
@@ -3856,16 +4754,18 @@ void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
   }
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());  
 }
 
-void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
-  typedef CodeCompleteConsumer::Result Result;
+void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, Decl *ObjCImpDecl) {
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
 
   // Figure out where this @synthesize lives.
   ObjCContainerDecl *Container
-    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
   if (!Container || 
       (!isa<ObjCImplementationDecl>(Container) && 
        !isa<ObjCCategoryImplDecl>(Container)))
@@ -3889,18 +4789,20 @@ void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
                       false, CurContext, Results);
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());  
 }
 
 void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S, 
                                                   IdentifierInfo *PropertyName,
-                                                  DeclPtrTy ObjCImpDecl) {
-  typedef CodeCompleteConsumer::Result Result;
+                                                  Decl *ObjCImpDecl) {
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
 
   // Figure out where this @synthesize lives.
   ObjCContainerDecl *Container
-    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
+    = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl);
   if (!Container || 
       (!isa<ObjCImplementationDecl>(Container) && 
        !isa<ObjCCategoryImplDecl>(Container)))
@@ -3927,10 +4829,15 @@ void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
   }
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
-typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
+// Mapping from selectors to the methods that implement that selector, along
+// with the "in original class" flag.
+typedef llvm::DenseMap<Selector, std::pair<ObjCMethodDecl *, bool> > 
+  KnownMethodsMap;
 
 /// \brief Find all of the methods that reside in the given container
 /// (and its superclasses, protocols, etc.) that meet the given
@@ -3941,7 +4848,8 @@ static void FindImplementableMethods(ASTContext &Context,
                                      bool WantInstanceMethods,
                                      QualType ReturnType,
                                      bool IsInImplementation,
-                                     KnownMethodsMap &KnownMethods) {
+                                     KnownMethodsMap &KnownMethods,
+                                     bool InOriginalClass = true) {
   if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
     // Recurse into protocols.
     const ObjCList<ObjCProtocolDecl> &Protocols
@@ -3950,14 +4858,16 @@ static void FindImplementableMethods(ASTContext &Context,
            E = Protocols.end(); 
          I != E; ++I)
       FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods,
+                               InOriginalClass);
 
     // If we're not in the implementation of a class, also visit the
     // superclass.
     if (!IsInImplementation && IFace->getSuperClass())
       FindImplementableMethods(Context, IFace->getSuperClass(), 
                                WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods,
+                               false);
 
     // Add methods from any class extensions (but not from categories;
     // those should go into category implementations).
@@ -3965,7 +4875,8 @@ static void FindImplementableMethods(ASTContext &Context,
          Cat = Cat->getNextClassExtension())
       FindImplementableMethods(Context, const_cast<ObjCCategoryDecl*>(Cat), 
                                WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);      
+                               IsInImplementation, KnownMethods,
+                               InOriginalClass);      
   }
 
   if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
@@ -3976,7 +4887,8 @@ static void FindImplementableMethods(ASTContext &Context,
            E = Protocols.end(); 
          I != E; ++I)
       FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods,
+                               InOriginalClass);
   }
 
   if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
@@ -3987,7 +4899,7 @@ static void FindImplementableMethods(ASTContext &Context,
            E = Protocols.end(); 
          I != E; ++I)
       FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
-                               IsInImplementation, KnownMethods);
+                               IsInImplementation, KnownMethods, false);
   }
 
   // Add methods in this container. This operation occurs last because
@@ -4001,15 +4913,15 @@ static void FindImplementableMethods(ASTContext &Context,
           !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
         continue;
 
-      KnownMethods[(*M)->getSelector()] = *M;
+      KnownMethods[(*M)->getSelector()] = std::make_pair(*M, InOriginalClass);
     }
   }
 }
 
 void Sema::CodeCompleteObjCMethodDecl(Scope *S, 
                                       bool IsInstanceMethod,
-                                      TypeTy *ReturnTy,
-                                      DeclPtrTy IDecl) {
+                                      ParsedType ReturnTy,
+                                      Decl *IDecl) {
   // Determine the return type of the method we're declaring, if
   // provided.
   QualType ReturnType = GetTypeFromParser(ReturnTy);
@@ -4017,7 +4929,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
   // Determine where we should start searching for methods, and where we 
   ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
   bool IsInImplementation = false;
-  if (Decl *D = IDecl.getAs<Decl>()) {
+  if (Decl *D = IDecl) {
     if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
       SearchDecl = Impl->getClassInterface();
       CurrentDecl = Impl;
@@ -4041,7 +4953,9 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
   }
 
   if (!SearchDecl || !CurrentDecl) {
-    HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
+    HandleCodeCompleteResults(this, CodeCompleter, 
+                              CodeCompletionContext::CCC_Other,
+                              0, 0);
     return;
   }
     
@@ -4064,7 +4978,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
   }
 
   // Add declarations or definitions for each of the known methods.
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   Results.EnterNewScope();
   PrintingPolicy Policy(Context.PrintingPolicy);
@@ -4072,7 +4986,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
   for (KnownMethodsMap::iterator M = KnownMethods.begin(), 
                               MEnd = KnownMethods.end();
        M != MEnd; ++M) {
-    ObjCMethodDecl *Method = M->second;
+    ObjCMethodDecl *Method = M->second.first;
     CodeCompletionString *Pattern = new CodeCompletionString;
     
     // If the result type was not already provided, add it to the
@@ -4100,7 +5014,7 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
         Pattern->AddChunk(CodeCompletionString::CK_Colon);
       else if (I < Sel.getNumArgs()) {
         Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
-        Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
+        Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(I)->getName());
         Pattern->AddChunk(CodeCompletionString::CK_Colon);
       } else
         break;
@@ -4113,14 +5027,14 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
       Pattern->AddChunk(CodeCompletionString::CK_RightParen);
       
       if (IdentifierInfo *Id = (*P)->getIdentifier())
-        Pattern->AddTextChunk(Id->getName());
+        Pattern->AddTextChunk(Id->getName());      
     }
 
     if (Method->isVariadic()) {
       if (Method->param_size() > 0)
         Pattern->AddChunk(CodeCompletionString::CK_Comma);
       Pattern->AddTextChunk("...");
-    }
+    }        
 
     if (IsInImplementation && Results.includeCodePatterns()) {
       // We will be defining the method here, so add a compound statement.
@@ -4140,50 +5054,56 @@ void Sema::CodeCompleteObjCMethodDecl(Scope *S,
       Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
     }
 
-    Results.AddResult(Result(Pattern));
+    unsigned Priority = CCP_CodePattern;
+    if (!M->second.second)
+      Priority += CCD_InBaseClass;
+    
+    Results.AddResult(Result(Pattern, Priority, 
+                             Method->isInstanceMethod()
+                               ? CXCursor_ObjCInstanceMethodDecl
+                               : CXCursor_ObjCClassMethodDecl));
   }
 
   Results.ExitScope();
   
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
 }
 
 void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S, 
                                               bool IsInstanceMethod,
                                               bool AtParameterName,
-                                              TypeTy *ReturnTy,
+                                              ParsedType ReturnTy,
                                               IdentifierInfo **SelIdents,
                                               unsigned NumSelIdents) {
-  llvm::DenseMap<Selector, ObjCMethodList> &Pool 
-    = IsInstanceMethod? InstanceMethodPool : FactoryMethodPool;
-  
   // If we have an external source, load the entire class method
-  // pool from the PCH file.
+  // pool from the AST file.
   if (ExternalSource) {
     for (uint32_t I = 0, N = ExternalSource->GetNumExternalSelectors();
          I != N; ++I) {
       Selector Sel = ExternalSource->GetExternalSelector(I);
-      if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
-          FactoryMethodPool.count(Sel))
+      if (Sel.isNull() || MethodPool.count(Sel))
         continue;
-      
-      ReadMethodPool(Sel, IsInstanceMethod);
+
+      ReadMethodPool(Sel);
     }
   }
 
   // Build the set of methods we can see.
-  typedef CodeCompleteConsumer::Result Result;
+  typedef CodeCompletionResult Result;
   ResultBuilder Results(*this);
   
   if (ReturnTy)
     Results.setPreferredType(GetTypeFromParser(ReturnTy).getNonReferenceType());
-  
+
   Results.EnterNewScope();  
-  for (llvm::DenseMap<Selector, ObjCMethodList>::iterator M = Pool.begin(),
-                                                       MEnd = Pool.end();
-       M != MEnd;
-       ++M) {
-    for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method; 
+  for (GlobalMethodPool::iterator M = MethodPool.begin(),
+                                  MEnd = MethodPool.end();
+       M != MEnd; ++M) {
+    for (ObjCMethodList *MethList = IsInstanceMethod ? &M->second.first :
+                                                       &M->second.second;
+         MethList && MethList->Method; 
          MethList = MethList->Next) {
       if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents, 
                                   NumSelIdents))
@@ -4212,5 +5132,270 @@ void Sema::CodeCompleteObjCMethodDeclSelector(Scope *S,
   }
   
   Results.ExitScope();
-  HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_Other,
+                            Results.data(),Results.size());
+}
+
+void Sema::CodeCompletePreprocessorDirective(bool InConditional) {
+  ResultBuilder Results(*this);
+  Results.EnterNewScope();
+  
+  // #if <condition>
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("if");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("condition");
+  Results.AddResult(Pattern);
+  
+  // #ifdef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("ifdef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  // #ifndef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("ifndef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  if (InConditional) {
+    // #elif <condition>
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("elif");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddPlaceholderChunk("condition");
+    Results.AddResult(Pattern);
+
+    // #else
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("else");
+    Results.AddResult(Pattern);
+
+    // #endif
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("endif");
+    Results.AddResult(Pattern);
+  }
+  
+  // #include "header"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+
+  // #include <header>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("<");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk(">");
+  Results.AddResult(Pattern);
+  
+  // #define <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("define");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+  
+  // #define <macro>(<args>)
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("define");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("args");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Pattern);
+  
+  // #undef <macro>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("undef");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("macro");
+  Results.AddResult(Pattern);
+
+  // #line <number>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("line");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("number");
+  Results.AddResult(Pattern);
+  
+  // #line <number> "filename"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("line");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("number");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("filename");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+  
+  // #error <message>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("error");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("message");
+  Results.AddResult(Pattern);
+
+  // #pragma <arguments>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("pragma");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("arguments");
+  Results.AddResult(Pattern);
+
+  if (getLangOptions().ObjC1) {
+    // #import "header"
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("import");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("\"");
+    Pattern->AddPlaceholderChunk("header");
+    Pattern->AddTextChunk("\"");
+    Results.AddResult(Pattern);
+    
+    // #import <header>
+    Pattern = new CodeCompletionString;
+    Pattern->AddTypedTextChunk("import");
+    Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    Pattern->AddTextChunk("<");
+    Pattern->AddPlaceholderChunk("header");
+    Pattern->AddTextChunk(">");
+    Results.AddResult(Pattern);
+  }
+  
+  // #include_next "header"
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include_next");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("\"");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk("\"");
+  Results.AddResult(Pattern);
+  
+  // #include_next <header>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("include_next");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddTextChunk("<");
+  Pattern->AddPlaceholderChunk("header");
+  Pattern->AddTextChunk(">");
+  Results.AddResult(Pattern);
+
+  // #warning <message>
+  Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("warning");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddPlaceholderChunk("message");
+  Results.AddResult(Pattern);
+
+  // Note: #ident and #sccs are such crazy anachronisms that we don't provide
+  // completions for them. And __include_macros is a Clang-internal extension
+  // that we don't want to encourage anyone to use.
+
+  // FIXME: we don't support #assert or #unassert, so don't suggest them.
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_PreprocessorDirective,
+                            Results.data(), Results.size());
+}
+
+void Sema::CodeCompleteInPreprocessorConditionalExclusion(Scope *S) {
+  CodeCompleteOrdinaryName(S,
+                           S->getFnParent()? Sema::PCC_RecoveryInFunction 
+                                           : Sema::PCC_Namespace);
+}
+
+void Sema::CodeCompletePreprocessorMacroName(bool IsDefinition) {
+  ResultBuilder Results(*this);
+  if (!IsDefinition && (!CodeCompleter || CodeCompleter->includeMacros())) {
+    // Add just the names of macros, not their arguments.    
+    Results.EnterNewScope();
+    for (Preprocessor::macro_iterator M = PP.macro_begin(), 
+                                   MEnd = PP.macro_end();
+         M != MEnd; ++M) {
+      CodeCompletionString *Pattern = new CodeCompletionString;
+      Pattern->AddTypedTextChunk(M->first->getName());
+      Results.AddResult(Pattern);
+    }
+    Results.ExitScope();
+  } else if (IsDefinition) {
+    // FIXME: Can we detect when the user just wrote an include guard above?
+  }
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                      IsDefinition? CodeCompletionContext::CCC_MacroName
+                                  : CodeCompletionContext::CCC_MacroNameUse,
+                            Results.data(), Results.size()); 
+}
+
+void Sema::CodeCompletePreprocessorExpression() {
+  ResultBuilder Results(*this);
+  
+  if (!CodeCompleter || CodeCompleter->includeMacros())
+    AddMacroResults(PP, Results);
+  
+    // defined (<macro>)
+  Results.EnterNewScope();
+  CodeCompletionString *Pattern = new CodeCompletionString;
+  Pattern->AddTypedTextChunk("defined");
+  Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
+  Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
+  Pattern->AddPlaceholderChunk("macro");
+  Pattern->AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(Pattern);
+  Results.ExitScope();
+  
+  HandleCodeCompleteResults(this, CodeCompleter, 
+                            CodeCompletionContext::CCC_PreprocessorExpression,
+                            Results.data(), Results.size()); 
+}
+
+void Sema::CodeCompletePreprocessorMacroArgument(Scope *S,
+                                                 IdentifierInfo *Macro,
+                                                 MacroInfo *MacroInfo,
+                                                 unsigned Argument) {
+  // FIXME: In the future, we could provide "overload" results, much like we
+  // do for function calls.
+  
+  CodeCompleteOrdinaryName(S,
+                           S->getFnParent()? Sema::PCC_RecoveryInFunction 
+                                           : Sema::PCC_Namespace);
+}
+
+void Sema::CodeCompleteNaturalLanguage() {
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_NaturalLanguage,
+                            0, 0);
+}
+
+void Sema::GatherGlobalCodeCompletions(
+                 llvm::SmallVectorImpl<CodeCompletionResult> &Results) {
+  ResultBuilder Builder(*this);
+
+  if (!CodeCompleter || CodeCompleter->includeGlobals()) {
+    CodeCompletionDeclConsumer Consumer(Builder, 
+                                        Context.getTranslationUnitDecl());
+    LookupVisibleDecls(Context.getTranslationUnitDecl(), LookupAnyName, 
+                       Consumer);
+  }
+  
+  if (!CodeCompleter || CodeCompleter->includeMacros())
+    AddMacroResults(PP, Builder);
+  
+  Results.clear();
+  Results.insert(Results.end(), 
+                 Builder.data(), Builder.data() + Builder.size());
 }
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index c1c898f..f5e045a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11,19 +11,24 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/CXXFieldCollector.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Parse/ParseDiagnostic.h"
-#include "clang/Parse/Template.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -35,18 +40,10 @@
 #include <cstring>
 #include <functional>
 using namespace clang;
+using namespace sema;
 
-/// getDeclName - Return a pretty name for the specified decl if possible, or
-/// an empty string if not.  This is used for pretty crash reporting.
-std::string Sema::getDeclName(DeclPtrTy d) {
-  Decl *D = d.getAs<Decl>();
-  if (NamedDecl *DN = dyn_cast_or_null<NamedDecl>(D))
-    return DN->getQualifiedNameAsString();
-  return "";
-}
-
-Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
-  return DeclGroupPtrTy::make(DeclGroupRef(Ptr.getAs<Decl>()));
+Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr) {
+  return DeclGroupPtrTy::make(DeclGroupRef(Ptr));
 }
 
 /// \brief If the identifier refers to a type name within this scope,
@@ -60,14 +57,14 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(DeclPtrTy Ptr) {
 ///
 /// If name lookup results in an ambiguity, this routine will complain
 /// and then return NULL.
-Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
-                                Scope *S, CXXScopeSpec *SS,
-                                bool isClassName,
-                                TypeTy *ObjectTypePtr) {
+ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
+                             Scope *S, CXXScopeSpec *SS,
+                             bool isClassName,
+                             ParsedType ObjectTypePtr) {
   // Determine where we will perform name lookup.
   DeclContext *LookupCtx = 0;
   if (ObjectTypePtr) {
-    QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+    QualType ObjectType = ObjectTypePtr.get();
     if (ObjectType->isRecordType())
       LookupCtx = computeDeclContext(ObjectType);
   } else if (SS && SS->isNotEmpty()) {
@@ -85,22 +82,22 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
         // We therefore do not perform any name lookup if the result would
         // refer to a member of an unknown specialization.
         if (!isClassName)
-          return 0;
+          return ParsedType();
         
         // We know from the grammar that this name refers to a type,
         // so build a dependent node to describe the type.
-        return CheckTypenameType(ETK_None,
-                                 (NestedNameSpecifier *)SS->getScopeRep(), II,
-                                 SourceLocation(), SS->getRange(), NameLoc
-                                 ).getAsOpaquePtr();
+        QualType T =
+          CheckTypenameType(ETK_None, SS->getScopeRep(), II,
+                            SourceLocation(), SS->getRange(), NameLoc);
+        return ParsedType::make(T);
       }
       
-      return 0;
+      return ParsedType();
     }
     
     if (!LookupCtx->isDependentContext() &&
         RequireCompleteDeclContext(*SS, LookupCtx))
-      return 0;
+      return ParsedType();
   }
 
   // FIXME: LookupNestedNameSpecifierName isn't the right kind of
@@ -136,7 +133,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
   case LookupResult::FoundOverloaded:
   case LookupResult::FoundUnresolvedValue:
     Result.suppressDiagnostics();
-    return 0;
+    return ParsedType();
 
   case LookupResult::Ambiguous:
     // Recover from type-hiding ambiguities by hiding the type.  We'll
@@ -146,7 +143,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
     // that only makes sense if the identifier was treated like a type.
     if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) {
       Result.suppressDiagnostics();
-      return 0;
+      return ParsedType();
     }
 
     // Look to see if we have a type anywhere in the list of results.
@@ -168,7 +165,7 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
       // will produce the ambiguity, or will complain that it expected
       // a type name.
       Result.suppressDiagnostics();
-      return 0;
+      return ParsedType();
     }
 
     // We found a type within the ambiguous lookup; diagnose the
@@ -199,10 +196,10 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
   } else {
     // If it's not plausibly a type, suppress diagnostics.
     Result.suppressDiagnostics();
-    return 0;
+    return ParsedType();
   }
 
-  return T.getAsOpaquePtr();
+  return ParsedType::make(T);
 }
 
 /// isTagName() - This method is called *for error recovery purposes only*
@@ -233,9 +230,9 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
                                    SourceLocation IILoc,
                                    Scope *S,
                                    CXXScopeSpec *SS,
-                                   TypeTy *&SuggestedType) {
+                                   ParsedType &SuggestedType) {
   // We don't have anything to suggest (yet).
-  SuggestedType = 0;
+  SuggestedType = ParsedType();
   
   // There may have been a typo in the name of the type. Look up typo
   // results, in case we have something that we can suggest.
@@ -282,7 +279,8 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
     CXXScopeSpec EmptySS;
     TemplateTy TemplateResult;
     bool MemberOfUnknownSpecialization;
-    if (isTemplateName(S, SS ? *SS : EmptySS, Name, 0, true, TemplateResult,
+    if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false,
+                       Name, ParsedType(), true, TemplateResult,
                        MemberOfUnknownSpecialization) == TNK_Type_template) {
       TemplateName TplName = TemplateResult.getAsVal<TemplateName>();
       Diag(IILoc, diag::err_template_missing_args) << TplName;
@@ -343,8 +341,10 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) {
     return DC;
   }
 
+  // ObjCMethodDecls are parsed (for some reason) outside the context
+  // of the class.
   if (isa<ObjCMethodDecl>(DC))
-    return Context.getTranslationUnitDecl();
+    return DC->getLexicalParent()->getLexicalParent();
 
   return DC->getLexicalParent();
 }
@@ -360,6 +360,7 @@ void Sema::PopDeclContext() {
   assert(CurContext && "DeclContext imbalance!");
 
   CurContext = getContainingDC(CurContext);
+  assert(CurContext && "Popped translation unit!");
 }
 
 /// EnterDeclaratorContext - Used when we must lookup names in the context
@@ -458,8 +459,8 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
   IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()),
                                IEnd = IdResolver.end();
   for (; I != IEnd; ++I) {
-    if (S->isDeclScope(DeclPtrTy::make(*I)) && D->declarationReplaces(*I)) {
-      S->RemoveDecl(DeclPtrTy::make(*I));
+    if (S->isDeclScope(*I) && D->declarationReplaces(*I)) {
+      S->RemoveDecl(*I);
       IdResolver.RemoveDecl(*I);
 
       // Should only need to replace one decl.
@@ -467,7 +468,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
     }
   }
 
-  S->AddDecl(DeclPtrTy::make(D));
+  S->AddDecl(D);
   IdResolver.AddDecl(D);
 }
 
@@ -475,6 +476,17 @@ bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S) {
   return IdResolver.isDeclInScope(D, Ctx, Context, S);
 }
 
+Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) {
+  DeclContext *TargetDC = DC->getPrimaryContext();
+  do {
+    if (DeclContext *ScopeDC = (DeclContext*) S->getEntity())
+      if (ScopeDC->getPrimaryContext() == TargetDC)
+        return S;
+  } while ((S = S->getParent()));
+
+  return 0;
+}
+
 static bool isOutOfScopePreviousDeclaration(NamedDecl *,
                                             DeclContext*,
                                             ASTContext&);
@@ -517,6 +529,90 @@ static void RemoveUsingDecls(LookupResult &R) {
   F.done();
 }
 
+/// \brief Check for this common pattern:
+/// @code
+/// class S {
+///   S(const S&); // DO NOT IMPLEMENT
+///   void operator=(const S&); // DO NOT IMPLEMENT
+/// };
+/// @endcode
+static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) {
+  // FIXME: Should check for private access too but access is set after we get
+  // the decl here.
+  if (D->isThisDeclarationADefinition())
+    return false;
+
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
+    return CD->isCopyConstructor();
+  return D->isCopyAssignment();
+}
+
+bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
+  assert(D);
+
+  if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>())
+    return false;
+
+  // Ignore class templates.
+  if (D->getDeclContext()->isDependentContext())
+    return false;
+
+  // We warn for unused decls internal to the translation unit.
+  if (D->getLinkage() == ExternalLinkage)
+    return false;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return false;
+
+    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+      if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD))
+        return false;
+    } else {
+      // 'static inline' functions are used in headers; don't warn.
+      if (FD->getStorageClass() == SC_Static &&
+          FD->isInlineSpecified())
+        return false;
+    }
+
+    if (FD->isThisDeclarationADefinition())
+      return !Context.DeclMustBeEmitted(FD);
+    return true;
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    if (VD->isStaticDataMember() &&
+        VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
+      return false;
+
+    if ( VD->isFileVarDecl() &&
+        !VD->getType().isConstant(Context))
+      return !Context.DeclMustBeEmitted(VD);
+  }
+
+   return false;
+ }
+
+ void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) {
+  if (!D)
+    return;
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    const FunctionDecl *First = FD->getFirstDeclaration();
+    if (FD != First && ShouldWarnIfUnusedFileScopedDecl(First))
+      return; // First should already be in the vector.
+  }
+
+  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+    const VarDecl *First = VD->getFirstDeclaration();
+    if (VD != First && ShouldWarnIfUnusedFileScopedDecl(First))
+      return; // First should already be in the vector.
+  }
+
+   if (ShouldWarnIfUnusedFileScopedDecl(D))
+     UnusedFileScopedDecls.push_back(D);
+ }
+
 static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
   if (D->isInvalidDecl())
     return false;
@@ -585,7 +681,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
 
   for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
        I != E; ++I) {
-    Decl *TmpD = (*I).getAs<Decl>();
+    Decl *TmpD = (*I);
     assert(TmpD && "This decl didn't get pushed??");
 
     assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?");
@@ -731,8 +827,8 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
   FunctionDecl *New = FunctionDecl::Create(Context,
                                            Context.getTranslationUnitDecl(),
                                            Loc, II, R, /*TInfo=*/0,
-                                           FunctionDecl::Extern,
-                                           FunctionDecl::None, false,
+                                           SC_Extern,
+                                           SC_None, false,
                                            /*hasPrototype=*/true);
   New->setImplicit();
 
@@ -743,7 +839,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
     for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i)
       Params.push_back(ParmVarDecl::Create(Context, New, SourceLocation(), 0,
                                            FT->getArgType(i), /*TInfo=*/0,
-                                           VarDecl::None, VarDecl::None, 0));
+                                           SC_None, SC_None, 0));
     New->setParams(Params.data(), Params.size());
   }
 
@@ -909,25 +1005,40 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
 /// DeclhasAttr - returns true if decl Declaration already has the target
 /// attribute.
 static bool
-DeclHasAttr(const Decl *decl, const Attr *target) {
-  for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
-    if (attr->getKind() == target->getKind())
+DeclHasAttr(const Decl *D, const Attr *A) {
+  const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+  for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
+    if ((*i)->getKind() == A->getKind()) {
+      // FIXME: Don't hardcode this check
+      if (OA && isa<OwnershipAttr>(*i))
+        return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
       return true;
+    }
 
   return false;
 }
 
-/// MergeAttributes - append attributes from the Old decl to the New one.
-static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
-  for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
-    if (!DeclHasAttr(New, attr) && attr->isMerged()) {
-      Attr *NewAttr = attr->clone(C);
+/// MergeDeclAttributes - append attributes from the Old decl to the New one.
+static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
+  if (!Old->hasAttrs())
+    return;
+  // Ensure that any moving of objects within the allocated map is done before
+  // we process them.
+  if (!New->hasAttrs())
+    New->setAttrs(AttrVec());
+  for (Decl::attr_iterator i = Old->attr_begin(), e = Old->attr_end(); i != e;
+       ++i) {
+    // FIXME: Make this more general than just checking for Overloadable.
+    if (!DeclHasAttr(New, *i) && (*i)->getKind() != attr::Overloadable) {
+      Attr *NewAttr = (*i)->clone(C);
       NewAttr->setInherited(true);
       New->addAttr(NewAttr);
     }
   }
 }
 
+namespace {
+
 /// Used in MergeFunctionDecl to keep track of function parameters in
 /// C.
 struct GNUCompatibleParamWarning {
@@ -936,6 +1047,7 @@ struct GNUCompatibleParamWarning {
   QualType PromotedType;
 };
 
+}
 
 /// getSpecialMember - get the special member enum for a method.
 Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) {
@@ -960,7 +1072,7 @@ static bool canRedefineFunction(const FunctionDecl *FD,
                                 const LangOptions& LangOpts) {
   return (LangOpts.GNUMode && !LangOpts.C99 && !LangOpts.CPlusPlus &&
           FD->isInlineSpecified() &&
-          FD->getStorageClass() == FunctionDecl::Extern);
+          FD->getStorageClass() == SC_Extern);
 }
 
 /// MergeFunctionDecl - We just parsed a function 'New' from
@@ -1014,8 +1126,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
   // Don't complain about this if we're in GNU89 mode and the old function
   // is an extern inline function.
   if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) &&
-      New->getStorageClass() == FunctionDecl::Static &&
-      Old->getStorageClass() != FunctionDecl::Static &&
+      New->getStorageClass() == SC_Static &&
+      Old->getStorageClass() != SC_Static &&
       !canRedefineFunction(Old, getLangOptions())) {
     Diag(New->getLocation(), diag::err_static_non_static)
       << New;
@@ -1196,7 +1308,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
         ParmVarDecl *Param = ParmVarDecl::Create(Context, New,
                                                  SourceLocation(), 0,
                                                  *ParamType, /*TInfo=*/0,
-                                                 VarDecl::None, VarDecl::None,
+                                                 SC_None, SC_None,
                                                  0);
         Param->setImplicit();
         Params.push_back(Param);
@@ -1242,7 +1354,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
                                      NewProto->getArgType(Idx))) {
         ArgTypes.push_back(NewParm->getType());
       } else if (Context.typesAreCompatible(OldParm->getType(),
-                                            NewParm->getType())) {
+                                            NewParm->getType(),
+                                            /*CompareUnqualified=*/true)) {
         GNUCompatibleParamWarning Warn
           = { OldParm, NewParm, NewProto->getArgType(Idx) };
         Warnings.push_back(Warn);
@@ -1257,8 +1370,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
              diag::ext_param_promoted_not_compatible_with_prototype)
           << Warnings[Warn].PromotedType
           << Warnings[Warn].OldParm->getType();
-        Diag(Warnings[Warn].OldParm->getLocation(),
-             diag::note_previous_declaration);
+        if (Warnings[Warn].OldParm->getLocation().isValid())
+          Diag(Warnings[Warn].OldParm->getLocation(),
+               diag::note_previous_declaration);
       }
 
       New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
@@ -1309,11 +1423,11 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
 /// \returns false
 bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
   // Merge the attributes
-  MergeAttributes(New, Old, Context);
+  MergeDeclAttributes(New, Old, Context);
 
   // Merge the storage class.
-  if (Old->getStorageClass() != FunctionDecl::Extern &&
-      Old->getStorageClass() != FunctionDecl::None)
+  if (Old->getStorageClass() != SC_Extern &&
+      Old->getStorageClass() != SC_None)
     New->setStorageClass(Old->getStorageClass());
 
   // Merge "pure" flag.
@@ -1354,7 +1468,18 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
     return New->setInvalidDecl();
   }
 
-  MergeAttributes(New, Old, Context);
+  // C++ [class.mem]p1:
+  //   A member shall not be declared twice in the member-specification [...]
+  // 
+  // Here, we need only consider static data members.
+  if (Old->isStaticDataMember() && !New->isOutOfLine()) {
+    Diag(New->getLocation(), diag::err_duplicate_member) 
+      << New->getIdentifier();
+    Diag(Old->getLocation(), diag::note_previous_declaration);
+    New->setInvalidDecl();
+  }
+  
+  MergeDeclAttributes(New, Old, Context);
 
   // Merge the types
   QualType MergedT;
@@ -1398,8 +1523,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
   New->setType(MergedT);
 
   // C99 6.2.2p4: Check if we have a static decl followed by a non-static.
-  if (New->getStorageClass() == VarDecl::Static &&
-      (Old->getStorageClass() == VarDecl::None || Old->hasExternalStorage())) {
+  if (New->getStorageClass() == SC_Static &&
+      (Old->getStorageClass() == SC_None || Old->hasExternalStorage())) {
     Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_definition);
     return New->setInvalidDecl();
@@ -1415,8 +1540,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
   //   identifier has external linkage.
   if (New->hasExternalStorage() && Old->hasLinkage())
     /* Okay */;
-  else if (New->getStorageClass() != VarDecl::Static &&
-           Old->getStorageClass() == VarDecl::Static) {
+  else if (New->getStorageClass() != SC_Static &&
+           Old->getStorageClass() == SC_Static) {
     Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
     Diag(Old->getLocation(), diag::note_previous_definition);
     return New->setInvalidDecl();
@@ -1475,8 +1600,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
 
 /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
 /// no declarator (e.g. "struct foo;") is parsed.
-Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
-                                                 DeclSpec &DS) {
+Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
+                                            DeclSpec &DS) {
   // FIXME: Error on auto/register at file scope
   // FIXME: Error on inline/virtual/explicit
   // FIXME: Warn on useless __thread
@@ -1489,10 +1614,10 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
       DS.getTypeSpecType() == DeclSpec::TST_struct ||
       DS.getTypeSpecType() == DeclSpec::TST_union ||
       DS.getTypeSpecType() == DeclSpec::TST_enum) {
-    TagD = static_cast<Decl *>(DS.getTypeRep());
+    TagD = DS.getRepAsDecl();
 
     if (!TagD) // We probably had an error
-      return DeclPtrTy();
+      return 0;
 
     // Note that the above type specs guarantee that the
     // type rep is a Decl, whereas in many of the others
@@ -1513,14 +1638,12 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
     // If we're dealing with a class template decl, assume that the
     // template routines are handling it.
     if (TagD && isa<ClassTemplateDecl>(TagD))
-      return DeclPtrTy();
+      return 0;
     return ActOnFriendTypeDecl(S, DS, MultiTemplateParamsArg(*this, 0, 0));
   }
          
   if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
-    // If there are attributes in the DeclSpec, apply them to the record.
-    if (const AttributeList *AL = DS.getAttributes())
-      ProcessDeclAttributeList(S, Record, AL);
+    ProcessDeclAttributeList(S, Record, DS.getAttributes());
     
     if (!Record->getDeclName() && Record->isDefinition() &&
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -1536,7 +1659,7 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
     // about them.
     // FIXME: Should we support Microsoft's extensions in this area?
     if (Record->getDeclName() && getLangOptions().Microsoft)
-      return DeclPtrTy::make(Tag);
+      return Tag;
   }
   
   if (getLangOptions().CPlusPlus && 
@@ -1550,19 +1673,19 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
   if (!DS.isMissingDeclaratorOk() &&
       DS.getTypeSpecType() != DeclSpec::TST_error) {
     // Warn about typedefs of enums without names, since this is an
-    // extension in both Microsoft an GNU.
+    // extension in both Microsoft and GNU.
     if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef &&
         Tag && isa<EnumDecl>(Tag)) {
       Diag(DS.getSourceRange().getBegin(), diag::ext_typedef_without_a_name)
         << DS.getSourceRange();
-      return DeclPtrTy::make(Tag);
+      return Tag;
     }
 
     Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators)
       << DS.getSourceRange();
   }
 
-  return DeclPtrTy::make(Tag);
+  return TagD;
 }
 
 /// We are trying to inject an anonymous member into the given scope;
@@ -1639,7 +1762,7 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
         //   considered to have been defined in the scope in which the
         //   anonymous union is declared.
         Owner->makeDeclVisibleInContext(*F);
-        S->AddDecl(Sema::DeclPtrTy::make(*F));
+        S->AddDecl(*F);
         SemaRef.IdResolver.AddDecl(*F);
 
         // That includes picking up the appropriate access specifier.
@@ -1660,58 +1783,38 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S,
 
 /// StorageClassSpecToVarDeclStorageClass - Maps a DeclSpec::SCS to
 /// a VarDecl::StorageClass. Any error reporting is up to the caller:
-/// illegal input values are mapped to VarDecl::None.
-/// If the input declaration context is a linkage specification
-/// with no braces, then Extern is mapped to None.
-static VarDecl::StorageClass
-StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec,
-                                      DeclContext *DC) {
+/// illegal input values are mapped to SC_None.
+static StorageClass
+StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
   switch (StorageClassSpec) {
-  case DeclSpec::SCS_unspecified:    return VarDecl::None;
-  case DeclSpec::SCS_extern:
-    // If the current context is a C++ linkage specification
-    // having no braces, then the keyword "extern" is properly part
-    // of the linkage specification itself, rather than being
-    // the written storage class specifier.
-    return (DC && isa<LinkageSpecDecl>(DC) &&
-            !cast<LinkageSpecDecl>(DC)->hasBraces())
-      ? VarDecl::None : VarDecl::Extern;
-  case DeclSpec::SCS_static:         return VarDecl::Static;
-  case DeclSpec::SCS_auto:           return VarDecl::Auto;
-  case DeclSpec::SCS_register:       return VarDecl::Register;
-  case DeclSpec::SCS_private_extern: return VarDecl::PrivateExtern;
+  case DeclSpec::SCS_unspecified:    return SC_None;
+  case DeclSpec::SCS_extern:         return SC_Extern;
+  case DeclSpec::SCS_static:         return SC_Static;
+  case DeclSpec::SCS_auto:           return SC_Auto;
+  case DeclSpec::SCS_register:       return SC_Register;
+  case DeclSpec::SCS_private_extern: return SC_PrivateExtern;
     // Illegal SCSs map to None: error reporting is up to the caller.
   case DeclSpec::SCS_mutable:        // Fall through.
-  case DeclSpec::SCS_typedef:        return VarDecl::None;
+  case DeclSpec::SCS_typedef:        return SC_None;
   }
   llvm_unreachable("unknown storage class specifier");
 }
 
 /// StorageClassSpecToFunctionDeclStorageClass - Maps a DeclSpec::SCS to
-/// a FunctionDecl::StorageClass. Any error reporting is up to the caller:
-/// illegal input values are mapped to FunctionDecl::None.
-/// If the input declaration context is a linkage specification
-/// with no braces, then Extern is mapped to None.
-static FunctionDecl::StorageClass
-StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec,
-                                           DeclContext *DC) {
+/// a StorageClass. Any error reporting is up to the caller:
+/// illegal input values are mapped to SC_None.
+static StorageClass
+StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) {
   switch (StorageClassSpec) {
-  case DeclSpec::SCS_unspecified:    return FunctionDecl::None;
-  case DeclSpec::SCS_extern:
-    // If the current context is a C++ linkage specification
-    // having no braces, then the keyword "extern" is properly part
-    // of the linkage specification itself, rather than being
-    // the written storage class specifier.
-    return (DC && isa<LinkageSpecDecl>(DC) &&
-            !cast<LinkageSpecDecl>(DC)->hasBraces())
-      ? FunctionDecl::None : FunctionDecl::Extern;
-  case DeclSpec::SCS_static:         return FunctionDecl::Static;
-  case DeclSpec::SCS_private_extern: return FunctionDecl::PrivateExtern;
+  case DeclSpec::SCS_unspecified:    return SC_None;
+  case DeclSpec::SCS_extern:         return SC_Extern;
+  case DeclSpec::SCS_static:         return SC_Static;
+  case DeclSpec::SCS_private_extern: return SC_PrivateExtern;
     // Illegal SCSs map to None: error reporting is up to the caller.
   case DeclSpec::SCS_auto:           // Fall through.
   case DeclSpec::SCS_mutable:        // Fall through.
   case DeclSpec::SCS_register:       // Fall through.
-  case DeclSpec::SCS_typedef:        return FunctionDecl::None;
+  case DeclSpec::SCS_typedef:        return SC_None;
   }
   llvm_unreachable("unknown storage class specifier");
 }
@@ -1720,9 +1823,9 @@ StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec,
 /// anonymous structure or union. Anonymous unions are a C++ feature
 /// (C++ [class.union]) and a GNU C extension; anonymous structures
 /// are a GNU C and GNU C++ extension.
-Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
-                                                  AccessSpecifier AS,
-                                                  RecordDecl *Record) {
+Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
+                                             AccessSpecifier AS,
+                                             RecordDecl *Record) {
   DeclContext *Owner = Record->getDeclContext();
 
   // Diagnose whether this anonymous struct/union is an extension.
@@ -1782,6 +1885,9 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
             << (int)Record->isUnion() << (int)(FD->getAccess() == AS_protected);
           Invalid = true;
         }
+
+        if (CheckNontrivialField(FD))
+          Invalid = true;
       } else if ((*Mem)->isImplicit()) {
         // Any implicit members are fine.
       } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) {
@@ -1845,17 +1951,17 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
     DeclSpec::SCS SCSpec = DS.getStorageClassSpec();
     assert(SCSpec != DeclSpec::SCS_typedef &&
            "Parser allowed 'typedef' as storage class VarDecl.");
-    VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec, 0);
+    VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
     if (SCSpec == DeclSpec::SCS_mutable) {
       // mutable can only appear on non-static class members, so it's always
       // an error here
       Diag(Record->getLocation(), diag::err_mutable_nonmember);
       Invalid = true;
-      SC = VarDecl::None;
+      SC = SC_None;
     }
     SCSpec = DS.getStorageClassSpecAsWritten();
     VarDecl::StorageClass SCAsWritten
-      = StorageClassSpecToVarDeclStorageClass(SCSpec, 0);
+      = StorageClassSpecToVarDeclStorageClass(SCSpec);
 
     Anon = VarDecl::Create(Context, Owner, Record->getLocation(),
                            /*IdentifierInfo=*/0,
@@ -1886,85 +1992,115 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
   if (Invalid)
     Anon->setInvalidDecl();
 
-  return DeclPtrTy::make(Anon);
+  return Anon;
 }
 
 
 /// GetNameForDeclarator - Determine the full declaration name for the
 /// given Declarator.
-DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
+DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) {
   return GetNameFromUnqualifiedId(D.getName());
 }
 
-/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
-DeclarationName Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
-  switch (Name.getKind()) {
-    case UnqualifiedId::IK_Identifier:
-      return DeclarationName(Name.Identifier);
-      
-    case UnqualifiedId::IK_OperatorFunctionId:
-      return Context.DeclarationNames.getCXXOperatorName(
-                                              Name.OperatorFunctionId.Operator);
-
-    case UnqualifiedId::IK_LiteralOperatorId:
-      return Context.DeclarationNames.getCXXLiteralOperatorName(
-                                                               Name.Identifier);
-
-    case UnqualifiedId::IK_ConversionFunctionId: {
-      QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
-      if (Ty.isNull())
-        return DeclarationName();
-      
-      return Context.DeclarationNames.getCXXConversionFunctionName(
-                                                  Context.getCanonicalType(Ty));
-    }
-      
-    case UnqualifiedId::IK_ConstructorName: {
-      QualType Ty = GetTypeFromParser(Name.ConstructorName);
-      if (Ty.isNull())
-        return DeclarationName();
-      
-      return Context.DeclarationNames.getCXXConstructorName(
-                                                  Context.getCanonicalType(Ty));
-    }
-      
-    case UnqualifiedId::IK_ConstructorTemplateId: {
-      // In well-formed code, we can only have a constructor
-      // template-id that refers to the current context, so go there
-      // to find the actual type being constructed.
-      CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
-      if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
-        return DeclarationName();
+/// \brief Retrieves the declaration name from a parsed unqualified-id.
+DeclarationNameInfo
+Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
+  DeclarationNameInfo NameInfo;
+  NameInfo.setLoc(Name.StartLocation);
 
-      // Determine the type of the class being constructed.
-      QualType CurClassType = Context.getTypeDeclType(CurClass);
+  switch (Name.getKind()) {
 
-      // FIXME: Check two things: that the template-id names the same type as
-      // CurClassType, and that the template-id does not occur when the name
-      // was qualified.
+  case UnqualifiedId::IK_Identifier:
+    NameInfo.setName(Name.Identifier);
+    NameInfo.setLoc(Name.StartLocation);
+    return NameInfo;
+
+  case UnqualifiedId::IK_OperatorFunctionId:
+    NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
+                                           Name.OperatorFunctionId.Operator));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc
+      = Name.OperatorFunctionId.SymbolLocations[0];
+    NameInfo.getInfo().CXXOperatorName.EndOpNameLoc
+      = Name.EndLocation.getRawEncoding();
+    return NameInfo;
+
+  case UnqualifiedId::IK_LiteralOperatorId:
+    NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(
+                                                           Name.Identifier));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation);
+    return NameInfo;
+
+  case UnqualifiedId::IK_ConversionFunctionId: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXConversionFunctionName(
+                                               Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_ConstructorName: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+                                              Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_ConstructorTemplateId: {
+    // In well-formed code, we can only have a constructor
+    // template-id that refers to the current context, so go there
+    // to find the actual type being constructed.
+    CXXRecordDecl *CurClass = dyn_cast<CXXRecordDecl>(CurContext);
+    if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name)
+      return DeclarationNameInfo();
+
+    // Determine the type of the class being constructed.
+    QualType CurClassType = Context.getTypeDeclType(CurClass);
+
+    // FIXME: Check two things: that the template-id names the same type as
+    // CurClassType, and that the template-id does not occur when the name
+    // was qualified.
+
+    NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
+                                    Context.getCanonicalType(CurClassType)));
+    NameInfo.setLoc(Name.StartLocation);
+    // FIXME: should we retrieve TypeSourceInfo?
+    NameInfo.setNamedTypeInfo(0);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_DestructorName: {
+    TypeSourceInfo *TInfo;
+    QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo);
+    if (Ty.isNull())
+      return DeclarationNameInfo();
+    NameInfo.setName(Context.DeclarationNames.getCXXDestructorName(
+                                              Context.getCanonicalType(Ty)));
+    NameInfo.setLoc(Name.StartLocation);
+    NameInfo.setNamedTypeInfo(TInfo);
+    return NameInfo;
+  }
+
+  case UnqualifiedId::IK_TemplateId: {
+    TemplateName TName = Name.TemplateId->Template.get();
+    SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;
+    return Context.getNameForTemplate(TName, TNameLoc);
+  }
+
+  } // switch (Name.getKind())
 
-      return Context.DeclarationNames.getCXXConstructorName(
-                                       Context.getCanonicalType(CurClassType));
-    }
-
-    case UnqualifiedId::IK_DestructorName: {
-      QualType Ty = GetTypeFromParser(Name.DestructorName);
-      if (Ty.isNull())
-        return DeclarationName();
-      
-      return Context.DeclarationNames.getCXXDestructorName(
-                                                           Context.getCanonicalType(Ty));
-    }
-      
-    case UnqualifiedId::IK_TemplateId: {
-      TemplateName TName
-        = TemplateName::getFromVoidPointer(Name.TemplateId->Template);
-      return Context.getNameForTemplate(TName);
-    }
-  }
-  
   assert(false && "Unknown name kind");
-  return DeclarationName();  
+  return DeclarationNameInfo();
 }
 
 /// isNearlyMatchingFunction - Determine whether the C++ functions
@@ -2007,11 +2143,10 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
   switch (DS.getTypeSpecType()) {
   case DeclSpec::TST_typename:
   case DeclSpec::TST_typeofType:
-  case DeclSpec::TST_typeofExpr:
   case DeclSpec::TST_decltype: {
     // Grab the type from the parser.
     TypeSourceInfo *TSI = 0;
-    QualType T = S.GetTypeFromParser(DS.getTypeRep(), &TSI);
+    QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
     if (T.isNull() || !T->isDependentType()) break;
 
     // Make sure there's a type source info.  This isn't really much
@@ -2025,8 +2160,16 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
     if (!TSI) return true;
 
     // Store the new type back in the decl spec.
-    QualType LocType = S.CreateLocInfoType(TSI->getType(), TSI);
-    DS.UpdateTypeRep(LocType.getAsOpaquePtr());
+    ParsedType LocType = S.CreateParsedType(TSI->getType(), TSI);
+    DS.UpdateTypeRep(LocType);
+    break;
+  }
+
+  case DeclSpec::TST_typeofExpr: {
+    Expr *E = DS.getRepAsExpr();
+    ExprResult Result = S.RebuildExprInCurrentInstantiation(E);
+    if (Result.isInvalid()) return true;
+    DS.UpdateExprRep(Result.get());
     break;
   }
 
@@ -2054,11 +2197,16 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
   return false;
 }
 
-Sema::DeclPtrTy
-Sema::HandleDeclarator(Scope *S, Declarator &D,
-                       MultiTemplateParamsArg TemplateParamLists,
-                       bool IsFunctionDefinition) {
-  DeclarationName Name = GetNameForDeclarator(D);
+Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) {
+  return HandleDeclarator(S, D, MultiTemplateParamsArg(*this), false);
+}
+
+Decl *Sema::HandleDeclarator(Scope *S, Declarator &D,
+                             MultiTemplateParamsArg TemplateParamLists,
+                             bool IsFunctionDefinition) {
+  // TODO: consider using NameInfo for diagnostic.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
 
   // All of these full declarators require an identifier.  If it doesn't have
   // one, the ParsedFreeStandingDeclSpec action should be used.
@@ -2067,7 +2215,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
       Diag(D.getDeclSpec().getSourceRange().getBegin(),
            diag::err_declarator_need_ident)
         << D.getDeclSpec().getSourceRange() << D.getSourceRange();
-    return DeclPtrTy();
+    return 0;
   }
 
   // The scope passed in may not be a decl scope.  Zip up the scope tree until
@@ -2091,14 +2239,14 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
            diag::err_template_qualified_declarator_no_match)
         << (NestedNameSpecifier*)D.getCXXScopeSpec().getScopeRep()
         << D.getCXXScopeSpec().getRange();
-      return DeclPtrTy();
+      return 0;
     }
 
     bool IsDependentContext = DC->isDependentContext();
 
     if (!IsDependentContext && 
         RequireCompleteDeclContext(D.getCXXScopeSpec(), DC))
-      return DeclPtrTy();
+      return 0;
 
     if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) {
       Diag(D.getIdentifierLoc(),
@@ -2122,7 +2270,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType R = TInfo->getType();
 
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
                         ForRedeclaration);
 
   // See if this is a redefinition of a variable in the same scope.
@@ -2140,7 +2288,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
         IsLinkageLookup = true;
     } else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern)
       IsLinkageLookup = true;
-    else if (CurContext->getLookupContext()->isTranslationUnit() &&
+    else if (CurContext->getRedeclContext()->isTranslationUnit() &&
              D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
       IsLinkageLookup = true;
 
@@ -2225,7 +2373,7 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
     if (TemplateParamLists.size()) {
       Diag(D.getIdentifierLoc(), diag::err_template_typedef);
-      return DeclPtrTy();
+      return 0;
     }
 
     New = ActOnTypedefDeclarator(S, D, DC, R, TInfo, Previous, Redeclaration);
@@ -2240,14 +2388,14 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
   }
 
   if (New == 0)
-    return DeclPtrTy();
+    return 0;
 
   // If this has an identifier and is not an invalid redeclaration or 
   // function template specialization, add it to the scope stack.
-  if (Name && !(Redeclaration && New->isInvalidDecl()))
+  if (New->getDeclName() && !(Redeclaration && New->isInvalidDecl()))
     PushOnScopeChains(New, S);
 
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 /// TryToFixInvalidVariablyModifiedType - Helper method to turn variable array
@@ -2255,20 +2403,26 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
 /// be errors (for GCC compatibility).
 static QualType TryToFixInvalidVariablyModifiedType(QualType T,
                                                     ASTContext &Context,
-                                                    bool &SizeIsNegative) {
+                                                    bool &SizeIsNegative,
+                                                    llvm::APSInt &Oversized) {
   // This method tries to turn a variable array into a constant
   // array even when the size isn't an ICE.  This is necessary
   // for compatibility with code that depends on gcc's buggy
   // constant expression folding, like struct {char x[(int)(char*)2];}
   SizeIsNegative = false;
-
+  Oversized = 0;
+  
+  if (T->isDependentType())
+    return QualType();
+  
   QualifierCollector Qs;
   const Type *Ty = Qs.strip(T);
 
   if (const PointerType* PTy = dyn_cast<PointerType>(Ty)) {
     QualType Pointee = PTy->getPointeeType();
     QualType FixedType =
-        TryToFixInvalidVariablyModifiedType(Pointee, Context, SizeIsNegative);
+        TryToFixInvalidVariablyModifiedType(Pointee, Context, SizeIsNegative,
+                                            Oversized);
     if (FixedType.isNull()) return FixedType;
     FixedType = Context.getPointerType(FixedType);
     return Qs.apply(FixedType);
@@ -2287,15 +2441,24 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
       !EvalResult.Val.isInt())
     return QualType();
 
+  // Check whether the array size is negative.
   llvm::APSInt &Res = EvalResult.Val.getInt();
-  if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) {
-    // TODO: preserve the size expression in declarator info
-    return Context.getConstantArrayType(VLATy->getElementType(),
-                                        Res, ArrayType::Normal, 0);
+  if (Res.isSigned() && Res.isNegative()) {
+    SizeIsNegative = true;
+    return QualType();
   }
 
-  SizeIsNegative = true;
-  return QualType();
+  // Check whether the array is too large to be addressed.
+  unsigned ActiveSizeBits
+    = ConstantArrayType::getNumAddressingBits(Context, VLATy->getElementType(),
+                                              Res);
+  if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+    Oversized = Res;
+    return QualType();
+  }
+  
+  return Context.getConstantArrayType(VLATy->getElementType(),
+                                      Res, ArrayType::Normal, 0);
 }
 
 /// \brief Register the given locally-scoped external C declaration so
@@ -2320,11 +2483,11 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
   if (S && IdResolver.ReplaceDecl(PrevDecl, ND)) {
     // The previous declaration was found on the identifer resolver
     // chain, so remove it from its scope.
-    while (S && !S->isDeclScope(DeclPtrTy::make(PrevDecl)))
+    while (S && !S->isDeclScope(PrevDecl))
       S = S->getParent();
 
     if (S)
-      S->RemoveDecl(DeclPtrTy::make(PrevDecl));
+      S->RemoveDecl(PrevDecl);
   }
 }
 
@@ -2382,24 +2545,20 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   // Handle attributes prior to checking for duplicates in MergeVarDecl
   ProcessDeclAttributes(S, NewTD, D);
 
-  // Merge the decl with the existing one if appropriate. If the decl is
-  // in an outer scope, it isn't the same thing.
-  FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
-  if (!Previous.empty()) {
-    Redeclaration = true;
-    MergeTypeDefDecl(NewTD, Previous);
-  }
-
   // C99 6.7.7p2: If a typedef name specifies a variably modified type
   // then it shall have block scope.
+  // Note that variably modified types must be fixed before merging the decl so
+  // that redeclarations will match.
   QualType T = NewTD->getUnderlyingType();
   if (T->isVariablyModifiedType()) {
-    FunctionNeedsScopeChecking() = true;
+    getCurFunction()->setHasBranchProtectedScope();
 
     if (S->getFnParent() == 0) {
       bool SizeIsNegative;
+      llvm::APSInt Oversized;
       QualType FixedTy =
-          TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+          TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+                                              Oversized);
       if (!FixedTy.isNull()) {
         Diag(D.getIdentifierLoc(), diag::warn_illegal_constant_array_size);
         NewTD->setTypeSourceInfo(Context.getTrivialTypeSourceInfo(FixedTy));
@@ -2408,6 +2567,9 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
           Diag(D.getIdentifierLoc(), diag::err_typecheck_negative_array_size);
         else if (T->isVariableArrayType())
           Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
+        else if (Oversized.getBoolValue())
+          Diag(D.getIdentifierLoc(), diag::err_array_too_large)
+            << Oversized.toString(10);
         else
           Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
         NewTD->setInvalidDecl();
@@ -2415,10 +2577,18 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     }
   }
 
+  // Merge the decl with the existing one if appropriate. If the decl is
+  // in an outer scope, it isn't the same thing.
+  FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
+  if (!Previous.empty()) {
+    Redeclaration = true;
+    MergeTypeDefDecl(NewTD, Previous);
+  }
+
   // If this is the C FILE type, notify the AST context.
   if (IdentifierInfo *II = NewTD->getIdentifier())
     if (!NewTD->isInvalidDecl() &&
-        NewTD->getDeclContext()->getLookupContext()->isTranslationUnit()) {
+        NewTD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {
       if (II->isStr("FILE"))
         Context.setFILEDecl(NewTD);
       else if (II->isStr("jmp_buf"))
@@ -2452,7 +2622,7 @@ static bool
 isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
                                 ASTContext &Context) {
   if (!PrevDecl)
-    return 0;
+    return false;
 
   if (!PrevDecl->hasLinkage())
     return false;
@@ -2464,30 +2634,25 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
     //   outside the innermost enclosing namespace scope, the block
     //   scope declaration declares that same entity and receives the
     //   linkage of the previous declaration.
-    DeclContext *OuterContext = DC->getLookupContext();
+    DeclContext *OuterContext = DC->getRedeclContext();
     if (!OuterContext->isFunctionOrMethod())
       // This rule only applies to block-scope declarations.
       return false;
-    else {
-      DeclContext *PrevOuterContext = PrevDecl->getDeclContext();
-      if (PrevOuterContext->isRecord())
-        // We found a member function: ignore it.
-        return false;
-      else {
-        // Find the innermost enclosing namespace for the new and
-        // previous declarations.
-        while (!OuterContext->isFileContext())
-          OuterContext = OuterContext->getParent();
-        while (!PrevOuterContext->isFileContext())
-          PrevOuterContext = PrevOuterContext->getParent();
-
-        // The previous declaration is in a different namespace, so it
-        // isn't the same function.
-        if (OuterContext->getPrimaryContext() !=
-            PrevOuterContext->getPrimaryContext())
-          return false;
-      }
-    }
+    
+    DeclContext *PrevOuterContext = PrevDecl->getDeclContext();
+    if (PrevOuterContext->isRecord())
+      // We found a member function: ignore it.
+      return false;
+    
+    // Find the innermost enclosing namespace for the new and
+    // previous declarations.
+    OuterContext = OuterContext->getEnclosingNamespaceContext();
+    PrevOuterContext = PrevOuterContext->getEnclosingNamespaceContext();
+
+    // The previous declaration is in a different namespace, so it
+    // isn't the same function.
+    if (!OuterContext->Equals(PrevOuterContext))
+      return false;
   }
 
   return true;
@@ -2506,7 +2671,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                               LookupResult &Previous,
                               MultiTemplateParamsArg TemplateParamLists,
                               bool &Redeclaration) {
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationName Name = GetNameForDeclarator(D).getName();
 
   // Check that there are no default arguments (C++ only).
   if (getLangOptions().CPlusPlus)
@@ -2515,17 +2680,17 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec();
   assert(SCSpec != DeclSpec::SCS_typedef &&
          "Parser allowed 'typedef' as storage class VarDecl.");
-  VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec, 0);
+  VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec);
   if (SCSpec == DeclSpec::SCS_mutable) {
     // mutable can only appear on non-static class members, so it's always
     // an error here
     Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
     D.setInvalidType();
-    SC = VarDecl::None;
+    SC = SC_None;
   }
   SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
   VarDecl::StorageClass SCAsWritten
-    = StorageClassSpecToVarDeclStorageClass(SCSpec, DC);
+    = StorageClassSpecToVarDeclStorageClass(SCSpec);
 
   IdentifierInfo *II = Name.getAsIdentifierInfo();
   if (!II) {
@@ -2539,11 +2704,11 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   if (!DC->isRecord() && S->getFnParent() == 0) {
     // C99 6.9p2: The storage-class specifiers auto and register shall not
     // appear in the declaration specifiers in an external declaration.
-    if (SC == VarDecl::Auto || SC == VarDecl::Register) {
+    if (SC == SC_Auto || SC == SC_Register) {
 
       // If this is a register variable with an asm label specified, then this
       // is a GNU extension.
-      if (SC == VarDecl::Register && D.getAsmLabel())
+      if (SC == SC_Register && D.getAsmLabel())
         Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register);
       else
         Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
@@ -2552,14 +2717,14 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   }
   if (DC->isRecord() && !CurContext->isRecord()) {
     // This is an out-of-line definition of a static data member.
-    if (SC == VarDecl::Static) {
+    if (SC == SC_Static) {
       Diag(D.getDeclSpec().getStorageClassSpecLoc(),
            diag::err_static_out_of_line)
         << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
-    } else if (SC == VarDecl::None)
-      SC = VarDecl::Static;
+    } else if (SC == SC_None)
+      SC = SC_Static;
   }
-  if (SC == VarDecl::Static) {
+  if (SC == SC_Static) {
     if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
       if (RD->isLocalClass())
         Diag(D.getIdentifierLoc(),
@@ -2613,7 +2778,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
 
   SetNestedNameSpecifier(NewVD, D);
 
-  if (NumMatchedTemplateParamLists > 0) {
+  if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
     NewVD->setTemplateParameterListsInfo(Context,
                                          NumMatchedTemplateParamLists,
                         (TemplateParameterList**)TemplateParamLists.release());
@@ -2639,7 +2804,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+    NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), 
+                                                Context, SE->getString()));
   }
 
   // Diagnose shadowed variables before filtering for scope.
@@ -2679,6 +2845,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     NewVD->setInvalidDecl();
 
   // attributes declared post-definition are currently ignored
+  // FIXME: This should be handled in attribute merging, not
+  // here.
   if (Previous.isSingleResult()) {
     VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
     if (Def && (Def = Def->getDefinition()) &&
@@ -2694,6 +2862,13 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
       !NewVD->isInvalidDecl())
     RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
 
+  // If there's a #pragma GCC visibility in scope, and this isn't a class
+  // member, set the visibility of this variable.
+  if (NewVD->getLinkage() == ExternalLinkage && !DC->isRecord())
+    AddPushedVisibilityAttribute(NewVD);
+
+  MarkUnusedFileScopedDecl(NewVD);
+
   return NewVD;
 }
 
@@ -2807,19 +2982,16 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
 
   bool isVM = T->isVariablyModifiedType();
   if (isVM || NewVD->hasAttr<CleanupAttr>() ||
-      NewVD->hasAttr<BlocksAttr>() ||
-      // FIXME: We need to diagnose jumps passed initialized variables in C++.
-      // However, this turns on the scope checker for everything with a variable
-      // which may impact compile time.  See if we can find a better solution
-      // to this, perhaps only checking functions that contain gotos in C++?
-      (LangOpts.CPlusPlus && NewVD->hasLocalStorage()))
-    FunctionNeedsScopeChecking() = true;
+      NewVD->hasAttr<BlocksAttr>())
+    getCurFunction()->setHasBranchProtectedScope();
 
   if ((isVM && NewVD->hasLinkage()) ||
       (T->isVariableArrayType() && NewVD->hasGlobalStorage())) {
     bool SizeIsNegative;
+    llvm::APSInt Oversized;
     QualType FixedTy =
-        TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
+        TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative,
+                                            Oversized);
 
     if (FixedTy.isNull() && T->isVariableArrayType()) {
       const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
@@ -2830,7 +3002,7 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD,
       if (NewVD->isFileVarDecl())
         Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
         << SizeRange;
-      else if (NewVD->getStorageClass() == VarDecl::Static)
+      else if (NewVD->getStorageClass() == SC_Static)
         Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
         << SizeRange;
       else
@@ -2970,8 +3142,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
                               bool IsFunctionDefinition, bool &Redeclaration) {
   assert(R.getTypePtr()->isFunctionType());
 
-  DeclarationName Name = GetNameForDeclarator(D);
-  FunctionDecl::StorageClass SC = FunctionDecl::None;
+  // TODO: consider using NameInfo for diagnostic.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
+  FunctionDecl::StorageClass SC = SC_None;
   switch (D.getDeclSpec().getStorageClassSpec()) {
   default: assert(0 && "Unknown storage class!");
   case DeclSpec::SCS_auto:
@@ -2981,10 +3155,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
          diag::err_typecheck_sclass_func);
     D.setInvalidType();
     break;
-  case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
-  case DeclSpec::SCS_extern:      SC = FunctionDecl::Extern; break;
+  case DeclSpec::SCS_unspecified: SC = SC_None; break;
+  case DeclSpec::SCS_extern:      SC = SC_Extern; break;
   case DeclSpec::SCS_static: {
-    if (CurContext->getLookupContext()->isFunctionOrMethod()) {
+    if (CurContext->getRedeclContext()->isFunctionOrMethod()) {
       // C99 6.7.1p5:
       //   The declaration of an identifier for a function that has
       //   block scope shall have no explicit storage-class specifier
@@ -2992,12 +3166,12 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
       // See also (C++ [dcl.stc]p4).
       Diag(D.getDeclSpec().getStorageClassSpecLoc(),
            diag::err_static_block_func);
-      SC = FunctionDecl::None;
+      SC = SC_None;
     } else
-      SC = FunctionDecl::Static;
+      SC = SC_Static;
     break;
   }
-  case DeclSpec::SCS_private_extern: SC = FunctionDecl::PrivateExtern;break;
+  case DeclSpec::SCS_private_extern: SC = SC_PrivateExtern;break;
   }
 
   if (D.getDeclSpec().isThreadSpecified())
@@ -3010,7 +3184,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
 
   DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten();
   FunctionDecl::StorageClass SCAsWritten
-    = StorageClassSpecToFunctionDeclStorageClass(SCSpec, DC);
+    = StorageClassSpecToFunctionDeclStorageClass(SCSpec);
 
   // Check that the return type is not an abstract class type.
   // For record types, this is done by the AbstractClassUsageDiagnoser once
@@ -3050,7 +3224,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     // Create the new declaration
     NewFD = CXXConstructorDecl::Create(Context,
                                        cast<CXXRecordDecl>(DC),
-                                       D.getIdentifierLoc(), Name, R, TInfo,
+                                       NameInfo, R, TInfo,
                                        isExplicit, isInline,
                                        /*isImplicitlyDeclared=*/false);
   } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
@@ -3060,7 +3234,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
 
       NewFD = CXXDestructorDecl::Create(Context,
                                         cast<CXXRecordDecl>(DC),
-                                        D.getIdentifierLoc(), Name, R,
+                                        NameInfo, R,
                                         isInline,
                                         /*isImplicitlyDeclared=*/false);
       NewFD->setTypeSourceInfo(TInfo);
@@ -3085,7 +3259,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
 
     CheckConversionDeclarator(D, R, SC);
     NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
-                                      D.getIdentifierLoc(), Name, R, TInfo,
+                                      NameInfo, R, TInfo,
                                       isInline, isExplicit);
 
     isVirtualOkay = true;
@@ -3103,7 +3277,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
       return 0;
     }
 
-    bool isStatic = SC == FunctionDecl::Static;
+    bool isStatic = SC == SC_Static;
     
     // [class.free]p1:
     // Any allocation function for a class T is a static member
@@ -3120,7 +3294,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     
     // This is a C++ method declaration.
     NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(DC),
-                                  D.getIdentifierLoc(), Name, R, TInfo,
+                                  NameInfo, R, TInfo,
                                   isStatic, SCAsWritten, isInline);
 
     isVirtualOkay = !isStatic;
@@ -3137,8 +3311,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
        (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
 
     NewFD = FunctionDecl::Create(Context, DC,
-                                 D.getIdentifierLoc(),
-                                 Name, R, TInfo, SC, SCAsWritten, isInline,
+                                 NameInfo, R, TInfo, SC, SCAsWritten, isInline,
                                  HasPrototype);
   }
 
@@ -3212,7 +3385,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     }
   }
 
-  if (NumMatchedTemplateParamLists > 0) {
+  if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
     NewFD->setTemplateParameterListsInfo(Context,
                                          NumMatchedTemplateParamLists,
                         (TemplateParameterList**)TemplateParamLists.release());
@@ -3244,6 +3417,17 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     }
   }
 
+  // C++ [dcl.fct.spec]p3:
+  //  The inline specifier shall not appear on a block scope function declaration.
+  if (isInline && !NewFD->isInvalidDecl() && getLangOptions().CPlusPlus) {
+    if (CurContext->isFunctionOrMethod()) {
+      // 'inline' is not allowed on block scope function declaration.
+      Diag(D.getDeclSpec().getInlineSpecLoc(), 
+           diag::err_inline_declaration_block_scope) << Name
+        << FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
+    }
+  }
+ 
   // C++ [dcl.fct.spec]p6:
   //  The explicit specifier shall be used only in the declaration of a
   //  constructor or conversion function within its class definition; see 12.3.1
@@ -3282,7 +3466,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     NewFD->setAccess(AS_public);
   }
 
-  if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
+  if (SC == SC_Static && isa<CXXMethodDecl>(NewFD) &&
       !CurContext->isRecord()) {
     // C++ [class.static]p1:
     //   A data or function member of a class may be declared static
@@ -3300,7 +3484,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   if (Expr *E = (Expr*) D.getAsmLabel()) {
     // The parser guarantees this is a string.
     StringLiteral *SE = cast<StringLiteral>(E);
-    NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+    NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
+                                                SE->getString()));
   }
 
   // Copy the parameter declarations from the declarator D to the function
@@ -3316,9 +3501,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     // already checks for that case.
     if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
         FTI.ArgInfo[0].Param &&
-        FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType()) {
+        cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) {
       // Empty arg list, don't push any params.
-      ParmVarDecl *Param = FTI.ArgInfo[0].Param.getAs<ParmVarDecl>();
+      ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[0].Param);
 
       // In C++, the empty parameter-type-list must be spelled "void"; a
       // typedef of void is not permitted.
@@ -3328,7 +3513,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
       // FIXME: Leaks decl?
     } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) {
       for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
-        ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
         assert(Param->getDeclContext() != NewFD && "Was set before ?");
         Param->setDeclContext(NewFD);
         Params.push_back(Param);
@@ -3479,14 +3664,14 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     // definition (C++ [dcl.meaning]p1).
     // Note that this is not the case for explicit specializations of
     // function templates or member functions of class templates, per
-    // C++ [temp.expl.spec]p2.
+    // C++ [temp.expl.spec]p2. We also allow these declarations as an extension
+    // for compatibility with old SWIG code which likes to generate them.
     if (!IsFunctionDefinition && !isFriend &&
         !isFunctionTemplateSpecialization && !isExplicitSpecialization) {
-      Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
+      Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration)
         << D.getCXXScopeSpec().getRange();
-      NewFD->setInvalidDecl();
-    } else if (!Redeclaration && 
-               !(isFriend && CurContext->isDependentContext())) {
+    }
+    if (!Redeclaration && !(isFriend && CurContext->isDependentContext())) {
       // The user tried to provide an out-of-line definition for a
       // function that is a member of a class or namespace, but there
       // was no such member function declared (C++ [class.mfct]p2,
@@ -3526,6 +3711,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   ProcessDeclAttributes(S, NewFD, D);
 
   // attributes declared post-definition are currently ignored
+  // FIXME: This should happen during attribute merging
   if (Redeclaration && Previous.isSingleResult()) {
     const FunctionDecl *Def;
     FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
@@ -3537,7 +3723,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
 
   AddKnownFunctionAttributes(NewFD);
 
-  if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+  if (OverloadableAttrRequired && !NewFD->hasAttr<OverloadableAttr>()) {
     // If a function name is overloadable in C, then every function
     // with that name must be marked "overloadable".
     Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -3545,9 +3731,28 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     if (!Previous.empty())
       Diag(Previous.getRepresentativeDecl()->getLocation(),
            diag::note_attribute_overloadable_prev_overload);
-    NewFD->addAttr(::new (Context) OverloadableAttr());
+    NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
+  }
+
+  if (NewFD->hasAttr<OverloadableAttr>() && 
+      !NewFD->getType()->getAs<FunctionProtoType>()) {
+    Diag(NewFD->getLocation(),
+         diag::err_attribute_overloadable_no_prototype)
+      << NewFD;
+
+    // Turn this into a variadic function with no parameters.
+    const FunctionType *FT = NewFD->getType()->getAs<FunctionType>();
+    QualType R = Context.getFunctionType(FT->getResultType(),
+                                         0, 0, true, 0, false, false, 0, 0,
+                                         FT->getExtInfo());
+    NewFD->setType(R);
   }
 
+  // If there's a #pragma GCC visibility in scope, and this isn't a class
+  // member, set the visibility of this function.
+  if (NewFD->getLinkage() == ExternalLinkage && !DC->isRecord())
+    AddPushedVisibilityAttribute(NewFD);
+
   // If this is a locally-scoped extern C function, update the
   // map of such names.
   if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
@@ -3563,17 +3768,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
   if (FunctionTemplate)
     return FunctionTemplate;
 
-  
-  // Keep track of static, non-inlined function definitions that
-  // have not been used. We will warn later.
-  // FIXME: Also include static functions declared but not defined.
-  if (!NewFD->isInvalidDecl() && IsFunctionDefinition 
-      && !NewFD->isInlined() && NewFD->getLinkage() == InternalLinkage
-      && !NewFD->isUsed() && !NewFD->hasAttr<UnusedAttr>()
-      && !NewFD->hasAttr<ConstructorAttr>()
-      && !NewFD->hasAttr<DestructorAttr>())
-    UnusedStaticFuncs.push_back(NewFD);
-  
+  MarkUnusedFileScopedDecl(NewFD);
+
   return NewFD;
 }
 
@@ -3597,8 +3793,14 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
                                     bool &Redeclaration,
                                     bool &OverloadableAttrRequired) {
   // If NewFD is already known erroneous, don't do any of this checking.
-  if (NewFD->isInvalidDecl())
+  if (NewFD->isInvalidDecl()) {
+    // If this is a class member, mark the class invalid immediately.
+    // This avoids some consistency errors later.
+    if (isa<CXXMethodDecl>(NewFD))
+      cast<CXXMethodDecl>(NewFD)->getParent()->setInvalidDecl();
+
     return;
+  }
 
   if (NewFD->getResultType()->isVariablyModifiedType()) {
     // Functions returning a variably modified type violate C99 6.7.5.2p2
@@ -3634,27 +3836,9 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
       Redeclaration = true;
       OldDecl = Previous.getFoundDecl();
     } else {
-      if (!getLangOptions().CPlusPlus) {
+      if (!getLangOptions().CPlusPlus)
         OverloadableAttrRequired = true;
 
-        // Functions marked "overloadable" must have a prototype (that
-        // we can't get through declaration merging).
-        if (!NewFD->getType()->getAs<FunctionProtoType>()) {
-          Diag(NewFD->getLocation(),
-               diag::err_attribute_overloadable_no_prototype)
-            << NewFD;
-          Redeclaration = true;
-
-          // Turn this into a variadic function with no parameters.
-          QualType R = Context.getFunctionType(
-                     NewFD->getType()->getAs<FunctionType>()->getResultType(),
-                     0, 0, true, 0, false, false, 0, 0,
-                     FunctionType::ExtInfo());
-          NewFD->setType(R);
-          return NewFD->setInvalidDecl();
-        }
-      }
-
       switch (CheckOverload(S, NewFD, Previous, OldDecl,
                             /*NewIsUsingDecl*/ false)) {
       case Ovl_Match:
@@ -3723,6 +3907,8 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
         DeclarationName Name
           = Context.DeclarationNames.getCXXDestructorName(
                                         Context.getCanonicalType(ClassType));
+//         NewFD->getDeclName().dump();
+//         Name.dump();
         if (NewFD->getDeclName() != Name) {
           Diag(NewFD->getLocation(), diag::err_destructor_name);
           return NewFD->setInvalidDecl();
@@ -3750,12 +3936,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
         AddOverriddenMethods(Method->getParent(), Method);
     }
 
-    // Additional checks for the destructor; make sure we do this after we
-    // figure out whether the destructor is virtual.
-    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(NewFD))
-      if (!Destructor->getParent()->isDependentType())
-        CheckDestructor(Destructor);
-
     // Extra checking for C++ overloaded operators (C++ [over.oper]).
     if (NewFD->isOverloadedOperator() &&
         CheckOverloadedOperatorDeclaration(NewFD))
@@ -3781,7 +3961,7 @@ void Sema::CheckMain(FunctionDecl* FD) {
   //   shall not appear in a declaration of main.
   // static main is not an error under C99, but we should warn about it.
   bool isInline = FD->isInlineSpecified();
-  bool isStatic = FD->getStorageClass() == FunctionDecl::Static;
+  bool isStatic = FD->getStorageClass() == SC_Static;
   if (isInline || isStatic) {
     unsigned diagID = diag::warn_unusual_main_decl;
     if (isInline || getLangOptions().CPlusPlus)
@@ -3874,22 +4054,21 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
   // "may accept other forms of constant expressions" exception.
   // (We never end up here for C++, so the constant expression
   // rules there don't matter.)
-  if (Init->isConstantInitializer(Context))
+  if (Init->isConstantInitializer(Context, false))
     return false;
   Diag(Init->getExprLoc(), diag::err_init_element_not_constant)
     << Init->getSourceRange();
   return true;
 }
 
-void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init) {
-  AddInitializerToDecl(dcl, move(init), /*DirectInit=*/false);
+void Sema::AddInitializerToDecl(Decl *dcl, Expr *init) {
+  AddInitializerToDecl(dcl, init, /*DirectInit=*/false);
 }
 
 /// AddInitializerToDecl - Adds the initializer Init to the
 /// declaration dcl. If DirectInit is true, this is C++ direct
 /// initialization rather than copy initialization.
-void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
-  Decl *RealDecl = dcl.getAs<Decl>();
+void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
   if (RealDecl == 0)
@@ -3900,7 +4079,6 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
     // distinguish between a normal initializer and a pure-specifier.
     // Thus this grotesque test.
     IntegerLiteral *IL;
-    Expr *Init = static_cast<Expr *>(init.get());
     if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
         Context.getCanonicalType(IL->getType()) == Context.IntTy)
       CheckPureMethod(Method, Init->getSourceRange());
@@ -3925,6 +4103,8 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
     return;
   }
 
+  
+
   // A definition must end up with a complete type, which means it must be
   // complete with the restriction that an array type might be completed by the
   // initializer; note that later code assumes this restriction.
@@ -3951,11 +4131,28 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
     VDecl->setInvalidDecl();
     return;
   }
+  
+  // C++ [class.static.data]p4
+  //   If a static data member is of const integral or const
+  //   enumeration type, its declaration in the class definition can
+  //   specify a constant-initializer which shall be an integral
+  //   constant expression (5.19). In that case, the member can appear
+  //   in integral constant expressions. The member shall still be
+  //   defined in a namespace scope if it is used in the program and the
+  //   namespace scope definition shall not contain an initializer.
+  //
+  // We already performed a redefinition check above, but for static
+  // data members we also need to check whether there was an in-class
+  // declaration with an initializer.
+  const VarDecl* PrevInit = 0;
+  if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
+    Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
+    Diag(PrevInit->getLocation(), diag::note_previous_definition);
+    return;
+  }  
 
-  // Take ownership of the expression, now that we're sure we have somewhere
-  // to put it.
-  Expr *Init = init.takeAs<Expr>();
-  assert(Init && "missing initializer");
+  if (getLangOptions().CPlusPlus && VDecl->hasLocalStorage())
+    getCurFunction()->setHasBranchProtectedScope();
 
   // Capture the variable that is being initialized and the style of
   // initialization.
@@ -3978,8 +4175,8 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
       VDecl->setInvalidDecl();
     } else if (!VDecl->isInvalidDecl()) {
       InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
-      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                          MultiExprArg(*this, (void**)&Init, 1),
+      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                                MultiExprArg(*this, &Init, 1),
                                                 &DclT);
       if (Result.isInvalid()) {
         VDecl->setInvalidDecl();
@@ -3991,7 +4188,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
       // C++ 3.6.2p2, allow dynamic initialization of static initializers.
       // Don't check invalid declarations to avoid emitting useless diagnostics.
       if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) {
-        if (VDecl->getStorageClass() == VarDecl::Static) // C99 6.7.8p4.
+        if (VDecl->getStorageClass() == SC_Static) // C99 6.7.8p4.
           CheckForConstantInitializer(Init, DclT);
       }
     }
@@ -4039,18 +4236,18 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
             << Init->getSourceRange();
           VDecl->setInvalidDecl();
         } else if (!VDecl->getType()->isDependentType())
-          ImpCastExprToType(Init, VDecl->getType(), CastExpr::CK_IntegralCast);
+          ImpCastExprToType(Init, VDecl->getType(), CK_IntegralCast);
       }
     }
   } else if (VDecl->isFileVarDecl()) {
-    if (VDecl->getStorageClass() == VarDecl::Extern && 
+    if (VDecl->getStorageClass() == SC_Extern && 
         (!getLangOptions().CPlusPlus || 
          !Context.getBaseElementType(VDecl->getType()).isConstQualified()))
       Diag(VDecl->getLocation(), diag::warn_extern_init);
     if (!VDecl->isInvalidDecl()) {
       InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
-      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                          MultiExprArg(*this, (void**)&Init, 1),
+      ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                                MultiExprArg(*this, &Init, 1),
                                                 &DclT);
       if (Result.isInvalid()) {
         VDecl->setInvalidDecl();
@@ -4081,6 +4278,14 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
   VDecl->setInit(Init);
 
   if (getLangOptions().CPlusPlus) {
+    if (!VDecl->isInvalidDecl() &&
+        !VDecl->getDeclContext()->isDependentContext() &&
+        VDecl->hasGlobalStorage() && !VDecl->isStaticLocal() &&
+        !Init->isConstantInitializer(Context,
+                                     VDecl->getType()->isReferenceType()))
+      Diag(VDecl->getLocation(), diag::warn_global_constructor)
+        << Init->getSourceRange();
+
     // Make sure we mark the destructor as used if necessary.
     QualType InitType = VDecl->getType();
     while (const ArrayType *Array = Context.getAsArrayType(InitType))
@@ -4095,10 +4300,9 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) {
 /// ActOnInitializerError - Given that there was an error parsing an
 /// initializer for the given declaration, try to return to some form
 /// of sanity.
-void Sema::ActOnInitializerError(DeclPtrTy dcl) {
+void Sema::ActOnInitializerError(Decl *D) {
   // Our main concern here is re-establishing invariants like "a
   // variable's type is either dependent or complete".
-  Decl *D = dcl.getAs<Decl>();
   if (!D || D->isInvalidDecl()) return;
 
   VarDecl *VD = dyn_cast<VarDecl>(D);
@@ -4127,10 +4331,8 @@ void Sema::ActOnInitializerError(DeclPtrTy dcl) {
   // though.
 }
 
-void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
+void Sema::ActOnUninitializedDecl(Decl *RealDecl,
                                   bool TypeContainsUndeducedAuto) {
-  Decl *RealDecl = dcl.getAs<Decl>();
-
   // If there is no declaration, there was an error parsing it. Just ignore it.
   if (RealDecl == 0)
     return;
@@ -4190,7 +4392,7 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
                                   ArrayT->getElementType(),
                                   diag::err_illegal_decl_array_incomplete_type))
             Var->setInvalidDecl();
-        } else if (Var->getStorageClass() == VarDecl::Static) {
+        } else if (Var->getStorageClass() == SC_Static) {
           // C99 6.9.2p3: If the declaration of an identifier for an object is
           // a tentative definition and has internal linkage (C99 6.2.2p3), the
           // declared type shall not be an incomplete type.
@@ -4221,15 +4423,15 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
       return;
     }
 
-   // Provide a specific diagnostic for uninitialized variable
-   // definitions with reference type.
-   if (Type->isReferenceType()) {
-     Diag(Var->getLocation(), diag::err_reference_var_requires_init)
-       << Var->getDeclName()
-       << SourceRange(Var->getLocation(), Var->getLocation());
-     Var->setInvalidDecl();
-     return;
-   }
+    // Provide a specific diagnostic for uninitialized variable
+    // definitions with reference type.
+    if (Type->isReferenceType()) {
+      Diag(Var->getLocation(), diag::err_reference_var_requires_init)
+        << Var->getDeclName()
+        << SourceRange(Var->getLocation(), Var->getLocation());
+      Var->setInvalidDecl();
+      return;
+    }
 
     // Do not attempt to type-check the default initializer for a
     // variable with dependent type.
@@ -4271,17 +4473,30 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
       //   program is ill-formed.
       // FIXME: DPG thinks it is very fishy that C++0x disables this.
     } else {
+      // Check for jumps past the implicit initializer.  C++0x
+      // clarifies that this applies to a "variable with automatic
+      // storage duration", not a "local variable".
+      if (getLangOptions().CPlusPlus && Var->hasLocalStorage())
+        getCurFunction()->setHasBranchProtectedScope();
+
       InitializedEntity Entity = InitializedEntity::InitializeVariable(Var);
       InitializationKind Kind
         = InitializationKind::CreateDefault(Var->getLocation());
     
       InitializationSequence InitSeq(*this, Entity, Kind, 0, 0);
-      OwningExprResult Init = InitSeq.Perform(*this, Entity, Kind,
-                                              MultiExprArg(*this, 0, 0));
+      ExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+                                        MultiExprArg(*this, 0, 0));
       if (Init.isInvalid())
         Var->setInvalidDecl();
-      else if (Init.get())
+      else if (Init.get()) {
         Var->setInit(MaybeCreateCXXExprWithTemporaries(Init.takeAs<Expr>()));
+
+        if (getLangOptions().CPlusPlus && !Var->isInvalidDecl() && 
+            Var->hasGlobalStorage() && !Var->isStaticLocal() &&
+            !Var->getDeclContext()->isDependentContext() &&
+            !Var->getInit()->isConstantInitializer(Context, false))
+          Diag(Var->getLocation(), diag::warn_global_constructor);
+      }
     }
 
     if (!Var->isInvalidDecl() && getLangOptions().CPlusPlus && Record)
@@ -4289,16 +4504,16 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl,
   }
 }
 
-Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
-                                                   DeclPtrTy *Group,
-                                                   unsigned NumDecls) {
+Sema::DeclGroupPtrTy
+Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
+                              Decl **Group, unsigned NumDecls) {
   llvm::SmallVector<Decl*, 8> Decls;
 
   if (DS.isTypeSpecOwned())
-    Decls.push_back((Decl*)DS.getTypeRep());
+    Decls.push_back(DS.getRepAsDecl());
 
   for (unsigned i = 0; i != NumDecls; ++i)
-    if (Decl *D = Group[i].getAs<Decl>())
+    if (Decl *D = Group[i])
       Decls.push_back(D);
 
   return DeclGroupPtrTy::make(DeclGroupRef::Create(Context,
@@ -4308,16 +4523,15 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
 
 /// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator()
 /// to introduce parameters into function prototype scope.
-Sema::DeclPtrTy
-Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
+Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
   const DeclSpec &DS = D.getDeclSpec();
 
   // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'.
-  VarDecl::StorageClass StorageClass = VarDecl::None;
-  VarDecl::StorageClass StorageClassAsWritten = VarDecl::None;
+  VarDecl::StorageClass StorageClass = SC_None;
+  VarDecl::StorageClass StorageClassAsWritten = SC_None;
   if (DS.getStorageClassSpec() == DeclSpec::SCS_register) {
-    StorageClass = VarDecl::Register;
-    StorageClassAsWritten = VarDecl::Register;
+    StorageClass = SC_Register;
+    StorageClassAsWritten = SC_Register;
   } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) {
     Diag(DS.getStorageClassSpecLoc(),
          diag::err_invalid_storage_class_in_func_decl);
@@ -4358,7 +4572,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
         DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
         // Just pretend that we didn't see the previous declaration.
         PrevDecl = 0;
-      } else if (S->isDeclScope(DeclPtrTy::make(PrevDecl))) {
+      } else if (S->isDeclScope(PrevDecl)) {
         Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II;
         Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
 
@@ -4389,7 +4603,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
   }
 
   // Add the parameter declaration into this scope.
-  S->AddDecl(DeclPtrTy::make(New));
+  S->AddDecl(New);
   if (II)
     IdResolver.AddDecl(New);
 
@@ -4398,7 +4612,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
   if (New->hasAttr<BlocksAttr>()) {
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
   }
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 /// \brief Synthesizes a variable for a parameter arising from a
@@ -4408,11 +4622,31 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC,
                                               QualType T) {
   ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, 0,
                                 T, Context.getTrivialTypeSourceInfo(T, Loc),
-                                           VarDecl::None, VarDecl::None, 0);
+                                           SC_None, SC_None, 0);
   Param->setImplicit();
   return Param;
 }
 
+void Sema::DiagnoseUnusedParameters(ParmVarDecl * const *Param,
+                                    ParmVarDecl * const *ParamEnd) {
+  if (Diags.getDiagnosticLevel(diag::warn_unused_parameter) ==
+        Diagnostic::Ignored)
+    return;
+
+  // Don't diagnose unused-parameter errors in template instantiations; we
+  // will already have done so in the template itself.
+  if (!ActiveTemplateInstantiations.empty())
+    return;
+
+  for (; Param != ParamEnd; ++Param) {
+    if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
+        !(*Param)->hasAttr<UnusedAttr>()) {
+      Diag((*Param)->getLocation(), diag::warn_unused_parameter)
+        << (*Param)->getDeclName();
+    }
+  }
+}
+
 ParmVarDecl *Sema::CheckParameter(DeclContext *DC, 
                                   TypeSourceInfo *TSInfo, QualType T,
                                   IdentifierInfo *Name,
@@ -4487,8 +4721,8 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,
   }
 }
 
-Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
-                                              Declarator &D) {
+Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
+                                         Declarator &D) {
   assert(getCurFunctionDecl() == 0 && "Function parsing confused");
   assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "Not a function declarator!");
@@ -4500,9 +4734,9 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
 
   Scope *ParentScope = FnBodyScope->getParent();
 
-  DeclPtrTy DP = HandleDeclarator(ParentScope, D,
-                                  MultiTemplateParamsArg(*this),
-                                  /*IsFunctionDefinition=*/true);
+  Decl *DP = HandleDeclarator(ParentScope, D,
+                              MultiTemplateParamsArg(*this),
+                              /*IsFunctionDefinition=*/true);
   return ActOnStartOfFunctionDef(FnBodyScope, DP);
 }
 
@@ -4550,7 +4784,7 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD) {
   return MissingPrototype;
 }
 
-Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
+Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) {
   // Clear the last template instantiation error context.
   LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
   
@@ -4558,11 +4792,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
     return D;
   FunctionDecl *FD = 0;
 
-  if (FunctionTemplateDecl *FunTmpl
-        = dyn_cast<FunctionTemplateDecl>(D.getAs<Decl>()))
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
     FD = FunTmpl->getTemplatedDecl();
   else
-    FD = cast<FunctionDecl>(D.getAs<Decl>());
+    FD = cast<FunctionDecl>(D);
 
   // Enter a new function scope
   PushFunctionScope();
@@ -4627,15 +4860,15 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
 
   // Checking attributes of current function definition
   // dllimport attribute.
-  if (FD->getAttr<DLLImportAttr>() &&
-      (!FD->getAttr<DLLExportAttr>())) {
-    // dllimport attribute cannot be applied to definition.
-    if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+  DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
+  if (DA && (!FD->getAttr<DLLExportAttr>())) {
+    // dllimport attribute cannot be directly applied to definition.
+    if (!DA->isInherited()) {
       Diag(FD->getLocation(),
            diag::err_attribute_can_be_applied_only_to_symbol_declaration)
         << "dllimport";
       FD->setInvalidDecl();
-      return DeclPtrTy::make(FD);
+      return FD;
     }
 
     // Visual C++ appears to not think this is an issue, so only issue
@@ -4646,10 +4879,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
       // emitted.
       Diag(FD->getLocation(),
            diag::warn_redeclaration_without_attribute_prev_attribute_ignored)
-        << FD->getNameAsCString() << "dllimport";
+        << FD->getName() << "dllimport";
     }
   }
-  return DeclPtrTy::make(FD);
+  return FD;
 }
 
 /// \brief Given the set of return statements within a function body,
@@ -4668,9 +4901,11 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
 /// FIXME: Employ a smarter algorithm that accounts for multiple return 
 /// statements and the lifetimes of the NRVO candidates. We should be able to
 /// find a maximal set of NRVO variables.
-static void ComputeNRVO(Stmt *Body, ReturnStmt **Returns, unsigned NumReturns) {
+static void ComputeNRVO(Stmt *Body, FunctionScopeInfo *Scope) {
+  ReturnStmt **Returns = Scope->Returns.data();
+
   const VarDecl *NRVOCandidate = 0;
-  for (unsigned I = 0; I != NumReturns; ++I) {
+  for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) {
     if (!Returns[I]->getNRVOCandidate())
       return;
     
@@ -4684,15 +4919,12 @@ static void ComputeNRVO(Stmt *Body, ReturnStmt **Returns, unsigned NumReturns) {
     const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true);
 }
 
-Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg) {
+Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) {
   return ActOnFinishFunctionBody(D, move(BodyArg), false);
 }
 
-Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
-                                              bool IsInstantiation) {
-  Decl *dcl = D.getAs<Decl>();
-  Stmt *Body = BodyArg.takeAs<Stmt>();
-
+Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
+                                    bool IsInstantiation) {
   FunctionDecl *FD = 0;
   FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl);
   if (FunTmpl)
@@ -4718,8 +4950,7 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD))
         MarkVTableUsed(FD->getLocation(), Constructor->getParent());
       
-      ComputeNRVO(Body, FunctionScopes.back()->Returns.data(),
-                  FunctionScopes.back()->Returns.size());
+      ComputeNRVO(Body, getCurFunction());
     }
     
     assert(FD == getCurFunctionDecl() && "Function parsing confused");
@@ -4730,15 +4961,15 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
     if (!MD->isInvalidDecl())
       DiagnoseUnusedParameters(MD->param_begin(), MD->param_end());
   } else {
-    Body->Destroy(Context);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Verify and clean out per-function state.
 
   // Check goto/label use.
+  FunctionScopeInfo *CurFn = getCurFunction();
   for (llvm::DenseMap<IdentifierInfo*, LabelStmt*>::iterator
-       I = getLabelMap().begin(), E = getLabelMap().end(); I != E; ++I) {
+         I = CurFn->LabelMap.begin(), E = CurFn->LabelMap.end(); I != E; ++I) {
     LabelStmt *L = I->second;
 
     // Verify that we have no forward references left.  If so, there was a goto
@@ -4754,8 +4985,7 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
     // the function body so that they aren't leaked and that the AST is well
     // formed.
     if (Body == 0) {
-      // The whole function wasn't parsed correctly, just delete this.
-      L->Destroy(Context);
+      // The whole function wasn't parsed correctly.
       continue;
     }
 
@@ -4785,14 +5015,18 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
     
     // Verify that that gotos and switch cases don't jump into scopes illegally.
     // Verify that that gotos and switch cases don't jump into scopes illegally.
-    if (FunctionNeedsScopeChecking() &&
+    if (getCurFunction()->NeedsScopeChecking() &&
         !dcl->isInvalidDecl() &&
         !hasAnyErrorsInThisFunction())
       DiagnoseInvalidJumps(Body);
 
-    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl))
+    if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(dcl)) {
+      if (!Destructor->getParent()->isDependentType())
+        CheckDestructor(Destructor);
+
       MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
                                              Destructor->getParent());
+    }
     
     // If any errors have occurred, clear out any temporaries that may have
     // been leftover. This ensures that these temporaries won't be picked up for
@@ -4804,13 +5038,11 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
       // enabled.
       QualType ResultType;
       if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(dcl)) {
-        ResultType = FD->getResultType();
-      }
-      else {
+        AnalysisWarnings.IssueWarnings(WP, FD);
+      } else {
         ObjCMethodDecl *MD = cast<ObjCMethodDecl>(dcl);
-        ResultType = MD->getResultType();
+        AnalysisWarnings.IssueWarnings(WP, MD);
       }
-      AnalysisWarnings.IssueWarnings(WP, dcl);
     }
 
     assert(ExprTemporaries.empty() && "Leftover temporaries in function");
@@ -4826,8 +5058,8 @@ Sema::DeclPtrTy Sema::ActOnFinishFunctionBody(DeclPtrTy D, StmtArg BodyArg,
   // deletion in some later function.
   if (getDiagnostics().hasErrorOccurred())
     ExprTemporaries.clear();
-  
-  return D;
+
+  return dcl;
 }
 
 /// ImplicitlyDefineFunction - An undeclared identifier was used in a function
@@ -4873,8 +5105,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
   DeclContext *PrevDC = CurContext;
   CurContext = Context.getTranslationUnitDecl();
 
-  FunctionDecl *FD =
- dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+  FunctionDecl *FD = dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D));
   FD->setImplicit();
 
   CurContext = PrevDC;
@@ -4902,9 +5133,17 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
     bool HasVAListArg;
     if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
       if (!FD->getAttr<FormatAttr>())
-        FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+        FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                                "printf", FormatIdx+1,
                                                HasVAListArg ? 0 : FormatIdx+2));
     }
+    if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
+                                             HasVAListArg)) {
+     if (!FD->getAttr<FormatAttr>())
+       FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                              "scanf", FormatIdx+1,
+                                              HasVAListArg ? 0 : FormatIdx+2));
+    }
 
     // Mark const if we don't care about errno and that is the only
     // thing preventing the function from being const. This allows
@@ -4912,15 +5151,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
     if (!getLangOptions().MathErrno &&
         Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
       if (!FD->getAttr<ConstAttr>())
-        FD->addAttr(::new (Context) ConstAttr());
+        FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
     }
 
     if (Context.BuiltinInfo.isNoReturn(BuiltinID))
       FD->setType(Context.getNoReturnType(FD->getType()));
     if (Context.BuiltinInfo.isNoThrow(BuiltinID))
-      FD->addAttr(::new (Context) NoThrowAttr());
+      FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
     if (Context.BuiltinInfo.isConst(BuiltinID))
-      FD->addAttr(::new (Context) ConstAttr());
+      FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
   }
 
   IdentifierInfo *Name = FD->getIdentifier();
@@ -4942,13 +5181,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
       // FIXME: We known better than our headers.
       const_cast<FormatAttr *>(Format)->setType(Context, "printf");
     } else
-      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                             "printf", 1,
                                              Name->isStr("NSLogv") ? 0 : 2));
   } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
     // FIXME: asprintf and vasprintf aren't C99 functions. Should they be
     // target-specific builtins, perhaps?
     if (!FD->getAttr<FormatAttr>())
-      FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
+      FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+                                             "printf", 2,
                                              Name->isStr("vasprintf") ? 0 : 3));
   }
 }
@@ -5031,7 +5272,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
 /// former case, Name will be non-null.  In the later case, Name will be null.
 /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a
 /// reference/declaration/definition of a tag.
-Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
+Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
                                SourceLocation KWLoc, CXXScopeSpec &SS,
                                IdentifierInfo *Name, SourceLocation NameLoc,
                                AttributeList *Attr, AccessSpecifier AS,
@@ -5063,7 +5304,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
         // This is a declaration or definition of a class template (which may
         // be a member of another template).
         if (Invalid)
-          return DeclPtrTy();
+          return 0;
         
         OwnedDecl = false;
         DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
@@ -5106,26 +5347,26 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
       DC = computeDeclContext(SS, false);
       if (!DC) {
         IsDependent = true;
-        return DeclPtrTy();
+        return 0;
       }
     } else {
       DC = computeDeclContext(SS, true);
       if (!DC) {
         Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec)
           << SS.getRange();
-        return DeclPtrTy();
+        return 0;
       }
     }
 
     if (RequireCompleteDeclContext(SS, DC))
-      return DeclPtrTy::make((Decl *)0);
+      return 0;
 
     SearchDC = DC;
     // Look-up name inside 'foo::'.
     LookupQualifiedName(Previous, DC);
 
     if (Previous.isAmbiguous())
-      return DeclPtrTy();
+      return 0;
 
     if (Previous.empty()) {
       // Name lookup did not find anything. However, if the
@@ -5135,7 +5376,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
       // this as a dependent elaborated-type-specifier.
       if (Previous.wasNotFoundInCurrentInstantiation()) {
         IsDependent = true;
-        return DeclPtrTy();
+        return 0;
       }
 
       // A tag 'foo::bar' must already exist.
@@ -5155,7 +5396,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
 
     // Note:  there used to be some attempt at recovery here.
     if (Previous.isAmbiguous())
-      return DeclPtrTy();
+      return 0;
 
     if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
       // FIXME: This makes sure that we ignore the contexts associated
@@ -5176,7 +5417,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
   }
 
   if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
-      DC->Equals(StdNamespace) && Name->isStr("bad_alloc")) {
+      DC->Equals(getStdNamespace()) && Name->isStr("bad_alloc")) {
     // This is a declaration of or a reference to "std::bad_alloc".
     isStdBadAlloc = true;
     
@@ -5184,7 +5425,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
       // std::bad_alloc has been implicitly declared (but made invisible to
       // name lookup). Fill in this implicit declaration as the previous 
       // declaration, so that the declarations get chained appropriately.
-      Previous.addDecl(StdBadAlloc);
+      Previous.addDecl(getStdBadAlloc());
     }
   }
 
@@ -5271,11 +5512,12 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
         if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
           TagDecl *Tag = TT->getDecl();
           if (Tag->getDeclName() == Name &&
-              Tag->getDeclContext()->getLookupContext()
-                          ->Equals(TD->getDeclContext()->getLookupContext())) {
+              Tag->getDeclContext()->getRedeclContext()
+                          ->Equals(TD->getDeclContext()->getRedeclContext())) {
             PrevDecl = Tag;
             Previous.clear();
             Previous.addDecl(Tag);
+            Previous.resolveKind();
           }
         }
       }
@@ -5321,7 +5563,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
           // need to be changed with DeclGroups.
           if ((TUK == TUK_Reference && !PrevTagDecl->getFriendObjectKind()) ||
               TUK == TUK_Friend)
-            return DeclPtrTy::make(PrevTagDecl);
+            return PrevTagDecl;
 
           // Diagnose attempts to redefine a tag.
           if (TUK == TUK_Definition) {
@@ -5475,7 +5717,7 @@ CreateNewDecl:
       New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
                                   cast_or_null<CXXRecordDecl>(PrevDecl));
       
-      if (isStdBadAlloc && (!StdBadAlloc || StdBadAlloc->isImplicit()))
+      if (isStdBadAlloc && (!StdBadAlloc || getStdBadAlloc()->isImplicit()))
         StdBadAlloc = cast<CXXRecordDecl>(New);
     } else
       New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, KWLoc,
@@ -5549,7 +5791,7 @@ CreateNewDecl:
     if (PrevDecl)
       New->setAccess(PrevDecl->getAccess());
 
-    DeclContext *DC = New->getDeclContext()->getLookupContext();
+    DeclContext *DC = New->getDeclContext()->getRedeclContext();
     DC->makeDeclVisibleInContext(New, /* Recoverable = */ false);
     if (Name) // can be null along some error paths
       if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
@@ -5564,26 +5806,26 @@ CreateNewDecl:
   // If this is the C FILE type, notify the AST context.
   if (IdentifierInfo *II = New->getIdentifier())
     if (!New->isInvalidDecl() &&
-        New->getDeclContext()->getLookupContext()->isTranslationUnit() &&
+        New->getDeclContext()->getRedeclContext()->isTranslationUnit() &&
         II->isStr("FILE"))
       Context.setFILEDecl(New);
 
   OwnedDecl = true;
-  return DeclPtrTy::make(New);
+  return New;
 }
 
-void Sema::ActOnTagStartDefinition(Scope *S, DeclPtrTy TagD) {
+void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) {
   AdjustDeclIfTemplate(TagD);
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   
   // Enter the tag context.
   PushDeclContext(S, Tag);
 }
 
-void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD,
+void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
                                            SourceLocation LBraceLoc) {
   AdjustDeclIfTemplate(TagD);
-  CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD.getAs<Decl>());
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD);
 
   FieldCollector->StartClass();
 
@@ -5610,10 +5852,10 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, DeclPtrTy TagD,
          "Broken injected-class-name");
 }
 
-void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
+void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
                                     SourceLocation RBraceLoc) {
   AdjustDeclIfTemplate(TagD);
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   Tag->setRBraceLoc(RBraceLoc);
 
   if (isa<CXXRecordDecl>(Tag))
@@ -5626,9 +5868,9 @@ void Sema::ActOnTagFinishDefinition(Scope *S, DeclPtrTy TagD,
   Consumer.HandleTagDeclDefinition(Tag);
 }
 
-void Sema::ActOnTagDefinitionError(Scope *S, DeclPtrTy TagD) {
+void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) {
   AdjustDeclIfTemplate(TagD);
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   Tag->setInvalidDecl();
 
   // We're undoing ActOnTagStartDefinition here, not
@@ -5711,13 +5953,13 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName,
 
 /// ActOnField - Each field of a struct/union/class is passed into this in order
 /// to create a FieldDecl object for it.
-Sema::DeclPtrTy Sema::ActOnField(Scope *S, DeclPtrTy TagD,
+Decl *Sema::ActOnField(Scope *S, Decl *TagD,
                                  SourceLocation DeclStart,
                                  Declarator &D, ExprTy *BitfieldWidth) {
-  FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD.getAs<Decl>()),
+  FieldDecl *Res = HandleField(S, cast_or_null<RecordDecl>(TagD),
                                DeclStart, D, static_cast<Expr*>(BitfieldWidth),
                                AS_public);
-  return DeclPtrTy::make(Res);
+  return Res;
 }
 
 /// HandleField - Analyze a field of a C struct or a C++ data member.
@@ -5739,9 +5981,17 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
 
   if (D.getDeclSpec().isThreadSpecified())
     Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread);
+  
+  // Check to see if this name was declared as a member previously
+  LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration);
+  LookupName(Previous, S);
+  assert((Previous.empty() || Previous.isOverloadedResult() || 
+          Previous.isSingleResult()) 
+    && "Lookup of member name should be either overloaded, single or null");
 
-  NamedDecl *PrevDecl = LookupSingleName(S, II, Loc, LookupMemberName,
-                                         ForRedeclaration);
+  // If the name is overloaded then get any declaration else get the single result
+  NamedDecl *PrevDecl = Previous.isOverloadedResult() ?
+    Previous.getRepresentativeDecl() : Previous.getAsSingle<NamedDecl>();
 
   if (PrevDecl && PrevDecl->isTemplateParameter()) {
     // Maybe we will complain about the shadowed template parameter.
@@ -5804,21 +6054,29 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
 
   QualType EltTy = Context.getBaseElementType(T);
   if (!EltTy->isDependentType() &&
-      RequireCompleteType(Loc, EltTy, diag::err_field_incomplete))
+      RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) {
+    // Fields of incomplete type force their record to be invalid.
+    Record->setInvalidDecl();
     InvalidDecl = true;
+  }
 
   // C99 6.7.2.1p8: A member of a structure or union may have any type other
   // than a variably modified type.
   if (!InvalidDecl && T->isVariablyModifiedType()) {
     bool SizeIsNegative;
+    llvm::APSInt Oversized;
     QualType FixedTy = TryToFixInvalidVariablyModifiedType(T, Context,
-                                                           SizeIsNegative);
+                                                           SizeIsNegative,
+                                                           Oversized);
     if (!FixedTy.isNull()) {
       Diag(Loc, diag::warn_illegal_constant_array_size);
       T = FixedTy;
     } else {
       if (SizeIsNegative)
         Diag(Loc, diag::err_typecheck_negative_array_size);
+      else if (Oversized.getBoolValue())
+        Diag(Loc, diag::err_array_too_large)
+          << Oversized.toString(10);
       else
         Diag(Loc, diag::err_typecheck_field_variable_size);
       InvalidDecl = true;
@@ -5836,7 +6094,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
   if (!InvalidDecl && BitWidth &&
       VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth)) {
     InvalidDecl = true;
-    DeleteExpr(BitWidth);
     BitWidth = 0;
     ZeroWidth = false;
   }
@@ -5877,6 +6134,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
       CXXRecord->setPOD(false);
     if (!ZeroWidth)
       CXXRecord->setEmpty(false);
+    if (T->isReferenceType())
+      CXXRecord->setHasTrivialConstructor(false);
 
     if (const RecordType *RT = EltTy->getAs<RecordType>()) {
       CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
@@ -5896,27 +6155,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
         // cannot be a member of a union, nor can an array of such
         // objects.
         // TODO: C++0x alters this restriction significantly.
-        if (Record->isUnion()) {
-          // We check for copy constructors before constructors
-          // because otherwise we'll never get complaints about
-          // copy constructors.
-
-          CXXSpecialMember member = CXXInvalid;
-          if (!RDecl->hasTrivialCopyConstructor())
-            member = CXXCopyConstructor;
-          else if (!RDecl->hasTrivialConstructor())
-            member = CXXConstructor;
-          else if (!RDecl->hasTrivialCopyAssignment())
-            member = CXXCopyAssignment;
-          else if (!RDecl->hasTrivialDestructor())
-            member = CXXDestructor;
-
-          if (member != CXXInvalid) {
-            Diag(Loc, diag::err_illegal_union_member) << Name << member;
-            DiagnoseNontrivial(RT, member);
-            NewFD->setInvalidDecl();
-          }
-        }
+        if (Record->isUnion() && CheckNontrivialField(NewFD))
+          NewFD->setInvalidDecl();
       }
     }
   }
@@ -5946,6 +6186,43 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
   return NewFD;
 }
 
+bool Sema::CheckNontrivialField(FieldDecl *FD) {
+  assert(FD);
+  assert(getLangOptions().CPlusPlus && "valid check only for C++");
+
+  if (FD->isInvalidDecl())
+    return true;
+
+  QualType EltTy = Context.getBaseElementType(FD->getType());
+  if (const RecordType *RT = EltTy->getAs<RecordType>()) {
+    CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
+    if (RDecl->getDefinition()) {
+      // We check for copy constructors before constructors
+      // because otherwise we'll never get complaints about
+      // copy constructors.
+
+      CXXSpecialMember member = CXXInvalid;
+      if (!RDecl->hasTrivialCopyConstructor())
+        member = CXXCopyConstructor;
+      else if (!RDecl->hasTrivialConstructor())
+        member = CXXConstructor;
+      else if (!RDecl->hasTrivialCopyAssignment())
+        member = CXXCopyAssignment;
+      else if (!RDecl->hasTrivialDestructor())
+        member = CXXDestructor;
+
+      if (member != CXXInvalid) {
+        Diag(FD->getLocation(), diag::err_illegal_union_or_anon_struct_member)
+              << (int)FD->getParent()->isUnion() << FD->getDeclName() << member;
+        DiagnoseNontrivial(RT, member);
+        return true;
+      }
+    }
+  }
+  
+  return false;
+}
+
 /// DiagnoseNontrivial - Given that a class has a non-trivial
 /// special member, figure out why.
 void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) {
@@ -6091,9 +6368,9 @@ TranslateIvarVisibility(tok::ObjCKeywordKind ivarVisibility) {
 
 /// ActOnIvar - Each ivar field of an objective-c class is passed into this
 /// in order to create an IvarDecl object for it.
-Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
+Decl *Sema::ActOnIvar(Scope *S,
                                 SourceLocation DeclStart,
-                                DeclPtrTy IntfDecl,
+                                Decl *IntfDecl,
                                 Declarator &D, ExprTy *BitfieldWidth,
                                 tok::ObjCKeywordKind Visibility) {
 
@@ -6112,7 +6389,6 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
     // 6.7.2.1p3, 6.7.2.1p4
     if (VerifyBitField(Loc, II, T, BitWidth)) {
       D.setInvalidType();
-      DeleteExpr(BitWidth);
       BitWidth = 0;
     }
   } else {
@@ -6137,19 +6413,23 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
     Visibility != tok::objc_not_keyword ? TranslateIvarVisibility(Visibility)
                                         : ObjCIvarDecl::None;
   // Must set ivar's DeclContext to its enclosing interface.
-  ObjCContainerDecl *EnclosingDecl = IntfDecl.getAs<ObjCContainerDecl>();
+  ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(IntfDecl);
   ObjCContainerDecl *EnclosingContext;
   if (ObjCImplementationDecl *IMPDecl =
       dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
+    if (!LangOpts.ObjCNonFragileABI2) {
     // Case of ivar declared in an implementation. Context is that of its class.
-    EnclosingContext = IMPDecl->getClassInterface();
-    assert(EnclosingContext && "Implementation has no class interface!");
+      EnclosingContext = IMPDecl->getClassInterface();
+      assert(EnclosingContext && "Implementation has no class interface!");
+    }
+    else
+      EnclosingContext = EnclosingDecl;
   } else {
     if (ObjCCategoryDecl *CDecl = 
         dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
       if (!LangOpts.ObjCNonFragileABI2 || !CDecl->IsClassExtension()) {
         Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension();
-        return DeclPtrTy();
+        return 0;
       }
     }
     EnclosingContext = EnclosingDecl;
@@ -6180,19 +6460,59 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
   if (II) {
     // FIXME: When interfaces are DeclContexts, we'll need to add
     // these to the interface.
-    S->AddDecl(DeclPtrTy::make(NewID));
+    S->AddDecl(NewID);
     IdResolver.AddDecl(NewID);
   }
 
-  return DeclPtrTy::make(NewID);
+  return NewID;
+}
+
+/// ActOnLastBitfield - This routine handles synthesized bitfields rules for 
+/// class and class extensions. For every class @interface and class 
+/// extension @interface, if the last ivar is a bitfield of any type, 
+/// then add an implicit `char :0` ivar to the end of that interface.
+void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Decl *EnclosingDecl,
+                             llvm::SmallVectorImpl<Decl *> &AllIvarDecls) {
+  if (!LangOpts.ObjCNonFragileABI2 || AllIvarDecls.empty())
+    return;
+  
+  Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];
+  ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl);
+  
+  if (!Ivar->isBitField())
+    return;
+  uint64_t BitFieldSize =
+    Ivar->getBitWidth()->EvaluateAsInt(Context).getZExtValue();
+  if (BitFieldSize == 0)
+    return;
+  ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl);
+  if (!ID) {
+    if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) {
+      if (!CD->IsClassExtension())
+        return;
+    }
+    // No need to add this to end of @implementation.
+    else
+      return;
+  }
+  // All conditions are met. Add a new bitfield to the tail end of ivars.
+  llvm::APInt Zero(Context.getTypeSize(Context.CharTy), 0);
+  Expr * BW = IntegerLiteral::Create(Context, Zero, Context.CharTy, DeclLoc);
+
+  Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(EnclosingDecl),
+                              DeclLoc, 0,
+                              Context.CharTy, 
+                              Context.CreateTypeSourceInfo(Context.CharTy),
+                              ObjCIvarDecl::Private, BW,
+                              true);
+  AllIvarDecls.push_back(Ivar);
 }
 
 void Sema::ActOnFields(Scope* S,
-                       SourceLocation RecLoc, DeclPtrTy RecDecl,
-                       DeclPtrTy *Fields, unsigned NumFields,
+                       SourceLocation RecLoc, Decl *EnclosingDecl,
+                       Decl **Fields, unsigned NumFields,
                        SourceLocation LBrac, SourceLocation RBrac,
                        AttributeList *Attr) {
-  Decl *EnclosingDecl = RecDecl.getAs<Decl>();
   assert(EnclosingDecl && "missing record or interface decl");
 
   // If the decl this is being inserted into is invalid, then it may be a
@@ -6209,7 +6529,7 @@ void Sema::ActOnFields(Scope* S,
 
   RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl);
   for (unsigned i = 0; i != NumFields; ++i) {
-    FieldDecl *FD = cast<FieldDecl>(Fields[i].getAs<Decl>());
+    FieldDecl *FD = cast<FieldDecl>(Fields[i]);
 
     // Get the type for the field.
     Type *FDTy = FD->getType().getTypePtr();
@@ -6244,7 +6564,7 @@ void Sema::ActOnFields(Scope* S,
       EnclosingDecl->setInvalidDecl();
       continue;
     } else if (FDTy->isIncompleteArrayType() && i == NumFields - 1 &&
-               Record && Record->isStruct()) {
+               Record && !Record->isUnion()) {
       // Flexible array member.
       if (NumNamedMembers < 1) {
         Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
@@ -6360,6 +6680,11 @@ void Sema::ActOnFields(Scope* S,
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+
+  // If there's a #pragma GCC visibility in scope, and this isn't a subclass,
+  // set the visibility of this record.
+  if (Record && !Record->getDeclContext()->isRecord())
+    AddPushedVisibilityAttribute(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within
@@ -6405,9 +6730,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
                                           EnumConstantDecl *LastEnumConst,
                                           SourceLocation IdLoc,
                                           IdentifierInfo *Id,
-                                          ExprArg val) {
-  Expr *Val = (Expr *)val.get();
-
+                                          Expr *Val) {
   unsigned IntWidth = Context.Target.getIntWidth();
   llvm::APSInt EnumVal(IntWidth);
   QualType EltTy;
@@ -6434,12 +6757,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
               << (EnumVal.isUnsigned() || EnumVal.isNonNegative());
           else if (!Context.hasSameType(Val->getType(), Context.IntTy)) {
             // Force the type of the expression to 'int'.
-            ImpCastExprToType(Val, Context.IntTy, CastExpr::CK_IntegralCast);
-            
-            if (Val != val.get()) {
-              val.release();
-              val = Val;
-            }
+            ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast);
           }
         }
         
@@ -6527,20 +6845,19 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
     EnumVal.setIsSigned(EltTy->isSignedIntegerType());
   }
   
-  val.release();
   return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy,
                                   Val, EnumVal);
 }
 
 
-Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
-                                        DeclPtrTy lastEnumConst,
+Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl,
+                                        Decl *lastEnumConst,
                                         SourceLocation IdLoc,
                                         IdentifierInfo *Id,
                                         SourceLocation EqualLoc, ExprTy *val) {
-  EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl.getAs<Decl>());
+  EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl);
   EnumConstantDecl *LastEnumConst =
-    cast_or_null<EnumConstantDecl>(lastEnumConst.getAs<Decl>());
+    cast_or_null<EnumConstantDecl>(lastEnumConst);
   Expr *Val = static_cast<Expr*>(val);
 
   // The scope passed in may not be a decl scope.  Zip up the scope tree until
@@ -6569,13 +6886,12 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
       else
         Diag(IdLoc, diag::err_redefinition) << Id;
       Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-      if (Val) Val->Destroy(Context);
-      return DeclPtrTy();
+      return 0;
     }
   }
 
   EnumConstantDecl *New = CheckEnumConstant(TheEnumDecl, LastEnumConst,
-                                            IdLoc, Id, Owned(Val));
+                                            IdLoc, Id, Val);
 
   // Register this decl in the current scope stack.
   if (New) {
@@ -6583,14 +6899,14 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl,
     PushOnScopeChains(New, S);
   }
 
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
-                         SourceLocation RBraceLoc, DeclPtrTy EnumDeclX,
-                         DeclPtrTy *Elements, unsigned NumElements,
+                         SourceLocation RBraceLoc, Decl *EnumDeclX,
+                         Decl **Elements, unsigned NumElements,
                          Scope *S, AttributeList *Attr) {
-  EnumDecl *Enum = cast<EnumDecl>(EnumDeclX.getAs<Decl>());
+  EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
   QualType EnumType = Context.getTypeDeclType(Enum);
 
   if (Attr)
@@ -6599,7 +6915,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
   if (Enum->isDependentType()) {
     for (unsigned i = 0; i != NumElements; ++i) {
       EnumConstantDecl *ECD =
-        cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+        cast_or_null<EnumConstantDecl>(Elements[i]);
       if (!ECD) continue;
 
       ECD->setType(EnumType);
@@ -6626,7 +6942,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
 
   for (unsigned i = 0; i != NumElements; ++i) {
     EnumConstantDecl *ECD =
-      cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+      cast_or_null<EnumConstantDecl>(Elements[i]);
     if (!ECD) continue;  // Already issued a diagnostic.
 
     const llvm::APSInt &InitVal = ECD->getInitVal();
@@ -6728,8 +7044,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
   // Loop over all of the enumerator constants, changing their types to match
   // the type of the enum if needed.
   for (unsigned i = 0; i != NumElements; ++i) {
-    EnumConstantDecl *ECD =
-      cast_or_null<EnumConstantDecl>(Elements[i].getAs<Decl>());
+    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]);
     if (!ECD) continue;  // Already issued a diagnostic.
 
     // Standard C says the enumerators have int type, but we allow, as an
@@ -6772,11 +7087,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
 
     // Adjust the Expr initializer and type.
     if (ECD->getInitExpr())
-      ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy,
-                                                      CastExpr::CK_IntegralCast,
-                                                      ECD->getInitExpr(),
-                                                      CXXBaseSpecifierArray(),
-                                                      /*isLvalue=*/false));
+      ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy,
+                                                CK_IntegralCast,
+                                                ECD->getInitExpr(),
+                                                /*base paths*/ 0,
+                                                VK_RValue));
     if (getLangOptions().CPlusPlus)
       // C++ [dcl.enum]p4: Following the closing brace of an
       // enum-specifier, each enumerator has the type of its
@@ -6790,14 +7105,13 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
                            NumPositiveBits, NumNegativeBits);
 }
 
-Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
-                                            ExprArg expr) {
-  StringLiteral *AsmString = cast<StringLiteral>(expr.takeAs<Expr>());
+Decl *Sema::ActOnFileScopeAsmDecl(SourceLocation Loc, Expr *expr) {
+  StringLiteral *AsmString = cast<StringLiteral>(expr);
 
   FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext,
                                                    Loc, AsmString);
   CurContext->addDecl(New);
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
@@ -6806,7 +7120,7 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
   Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
 
   if (PrevDecl) {
-    PrevDecl->addAttr(::new (Context) WeakAttr());
+    PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
   } else {
     (void)WeakUndeclaredIdentifiers.insert(
       std::pair<IdentifierInfo*,WeakInfo>
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 3b82f58..25af73a 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -11,15 +11,18 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "TargetAttributesSema.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/DelayedDiagnostic.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace clang;
+using namespace sema;
 
 //===----------------------------------------------------------------------===//
 //  Helper functions
@@ -193,7 +196,7 @@ static void HandleExtVectorTypeAttr(Scope *scope, Decl *d,
 
   // Instantiate/Install the vector type, and let Sema build the type for us.
   // This will run the reguired checks.
-  QualType T = S.BuildExtVectorType(curType, S.Owned(sizeExpr), Attr.getLoc());
+  QualType T = S.BuildExtVectorType(curType, sizeExpr, Attr.getLoc());
   if (!T.isNull()) {
     // FIXME: preserve the old source info.
     tDecl->setTypeSourceInfo(S.Context.getTrivialTypeSourceInfo(T));
@@ -211,7 +214,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   }
 
   if (TagDecl *TD = dyn_cast<TagDecl>(d))
-    TD->addAttr(::new (S.Context) PackedAttr);
+    TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
   else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
     // If the alignment is less than or equal to 8 bits, the packed attribute
     // has no effect.
@@ -220,7 +223,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(::new (S.Context) PackedAttr);
+      FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
@@ -235,7 +238,7 @@ static void HandleIBAction(Decl *d, const AttributeList &Attr, Sema &S) {
   // The IBAction attributes only apply to instance methods.
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
     if (MD->isInstanceMethod()) {
-      d->addAttr(::new (S.Context) IBActionAttr());
+      d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
       return;
     }
 
@@ -252,7 +255,7 @@ static void HandleIBOutlet(Decl *d, const AttributeList &Attr, Sema &S) {
   // The IBOutlet attributes only apply to instance variables of
   // Objective-C classes.
   if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
-    d->addAttr(::new (S.Context) IBOutletAttr());
+    d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -263,7 +266,7 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
                                      Sema &S) {
 
   // The iboutletcollection attribute can have zero or one arguments.
-  if (Attr.getNumArgs() > 1) {
+  if (Attr.getParameterName() && Attr.getNumArgs() > 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
     return;
   }
@@ -274,9 +277,41 @@ static void HandleIBOutletCollection(Decl *d, const AttributeList &Attr,
     S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet) << Attr.getName();
     return;
   }
-
-  // FIXME: Eventually accept the type argument.
-  d->addAttr(::new (S.Context) IBOutletCollectionAttr());
+  if (const ValueDecl *VD = dyn_cast<ValueDecl>(d))
+    if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
+      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 
+        << VD->getType() << 0;
+      return;
+    }
+  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(d))
+    if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
+      S.Diag(Attr.getLoc(), diag::err_iboutletcollection_object_type) 
+        << PD->getType() << 1;
+      return;
+    }
+  
+  IdentifierInfo *II = Attr.getParameterName();
+  if (!II)
+    II = &S.Context.Idents.get("id");
+  
+  ParsedType TypeRep = S.getTypeName(*II, Attr.getLoc(), 
+                        S.getScopeForContext(d->getDeclContext()->getParent()));
+  if (!TypeRep) {
+    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
+    return;
+  }
+  QualType QT = TypeRep.get();
+  // Diagnose use of non-object type in iboutletcollection attribute.
+  // FIXME. Gnu attribute extension ignores use of builtin types in
+  // attributes. So, __attribute__((iboutletcollection(char))) will be
+  // treated as __attribute__((iboutletcollection())).
+  if (!QT->isObjCIdType() && !QT->isObjCClassType() &&
+      !QT->isObjCObjectType()) {
+    S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
+    return;
+  }
+  d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+                                                      QT));
 }
 
 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -321,7 +356,7 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     QualType T = getFunctionOrMethodArgType(d, x);
     if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
       // FIXME: Should also highlight argument in decl.
-      S.Diag(Attr.getLoc(), diag::err_nonnull_pointers_only)
+      S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
         << "nonnull" << Ex->getSourceRange();
       continue;
     }
@@ -346,15 +381,162 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
   unsigned* start = &NonNullArgs[0];
   unsigned size = NonNullArgs.size();
-  std::sort(start, start + size);
-  d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+  llvm::array_pod_sort(start, start + size);
+  d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+                                           size));
+}
+
+static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
+  // This attribute must be applied to a function declaration.
+  // The first argument to the attribute must be a string,
+  // the name of the resource, for example "malloc".
+  // The following arguments must be argument indexes, the arguments must be
+  // of integer type for Returns, otherwise of pointer type.
+  // The difference between Holds and Takes is that a pointer may still be used
+  // after being held.  free() should be __attribute((ownership_takes)), whereas
+  // a list append function may well be __attribute((ownership_holds)).
+
+  if (!AL.getParameterName()) {
+    S.Diag(AL.getLoc(), diag::err_attribute_argument_n_not_string)
+        << AL.getName()->getName() << 1;
+    return;
+  }
+  // Figure out our Kind, and check arguments while we're at it.
+  OwnershipAttr::OwnershipKind K;
+  switch (AL.getKind()) {
+  case AttributeList::AT_ownership_takes:
+    K = OwnershipAttr::Takes;
+    if (AL.getNumArgs() < 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+      return;
+    }
+    break;
+  case AttributeList::AT_ownership_holds:
+    K = OwnershipAttr::Holds;
+    if (AL.getNumArgs() < 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+      return;
+    }
+    break;
+  case AttributeList::AT_ownership_returns:
+    K = OwnershipAttr::Returns;
+    if (AL.getNumArgs() > 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
+          << AL.getNumArgs() + 1;
+      return;
+    }
+    break;
+  default:
+    // This should never happen given how we are called.
+    llvm_unreachable("Unknown ownership attribute");
+  }
+
+  if (!isFunction(d) || !hasFunctionProto(d)) {
+    S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL.getName()
+        << 0 /*function*/;
+    return;
+  }
+
+  unsigned NumArgs = getFunctionOrMethodNumArgs(d);
+
+  llvm::StringRef Module = AL.getParameterName()->getName();
+
+  // Normalize the argument, __foo__ becomes foo.
+  if (Module.startswith("__") && Module.endswith("__"))
+    Module = Module.substr(2, Module.size() - 4);
+
+  llvm::SmallVector<unsigned, 10> OwnershipArgs;
+
+  for (AttributeList::arg_iterator I = AL.arg_begin(), E = AL.arg_end(); I != E;
+       ++I) {
+
+    Expr *IdxExpr = static_cast<Expr *>(*I);
+    llvm::APSInt ArgNum(32);
+    if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
+        || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
+      S.Diag(AL.getLoc(), diag::err_attribute_argument_not_int)
+          << AL.getName()->getName() << IdxExpr->getSourceRange();
+      continue;
+    }
+
+    unsigned x = (unsigned) ArgNum.getZExtValue();
+
+    if (x > NumArgs || x < 1) {
+      S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
+          << AL.getName()->getName() << x << IdxExpr->getSourceRange();
+      continue;
+    }
+    --x;
+    switch (K) {
+    case OwnershipAttr::Takes:
+    case OwnershipAttr::Holds: {
+      // Is the function argument a pointer type?
+      QualType T = getFunctionOrMethodArgType(d, x);
+      if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
+        // FIXME: Should also highlight argument in decl.
+        S.Diag(AL.getLoc(), diag::err_ownership_type)
+            << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
+            << "pointer"
+            << IdxExpr->getSourceRange();
+        continue;
+      }
+      break;
+    }
+    case OwnershipAttr::Returns: {
+      if (AL.getNumArgs() > 1) {
+          // Is the function argument an integer type?
+          Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
+          llvm::APSInt ArgNum(32);
+          if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent()
+              || !IdxExpr->isIntegerConstantExpr(ArgNum, S.Context)) {
+            S.Diag(AL.getLoc(), diag::err_ownership_type)
+                << "ownership_returns" << "integer"
+                << IdxExpr->getSourceRange();
+            return;
+          }
+      }
+      break;
+    }
+    default:
+      llvm_unreachable("Unknown ownership attribute");
+    } // switch
+
+    // Check we don't have a conflict with another ownership attribute.
+    for (specific_attr_iterator<OwnershipAttr>
+          i = d->specific_attr_begin<OwnershipAttr>(),
+          e = d->specific_attr_end<OwnershipAttr>();
+        i != e; ++i) {
+      if ((*i)->getOwnKind() != K) {
+        for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
+             I!=E; ++I) {
+          if (x == *I) {
+            S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+                << AL.getName()->getName() << "ownership_*";
+          }
+        }
+      }
+    }
+    OwnershipArgs.push_back(x);
+  }
+
+  unsigned* start = OwnershipArgs.data();
+  unsigned size = OwnershipArgs.size();
+  llvm::array_pod_sort(start, start + size);
+
+  if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+    S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+    return;
+  }
+
+  d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+                                             start, size));
 }
 
 static bool isStaticVarOrStaticFunciton(Decl *D) {
   if (VarDecl *VD = dyn_cast<VarDecl>(D))
-    return VD->getStorageClass() == VarDecl::Static;
+    return VD->getStorageClass() == SC_Static;
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
-    return FD->getStorageClass() == FunctionDecl::Static;
+    return FD->getStorageClass() == SC_Static;
   return false;
 }
 
@@ -375,13 +557,11 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   //   static int a __attribute__((weakref ("v2")));
   // }
   // we reject them
-  if (const DeclContext *Ctx = d->getDeclContext()) {
-    Ctx = Ctx->getLookupContext();
-    if (!isa<TranslationUnitDecl>(Ctx) && !isa<NamespaceDecl>(Ctx) ) {
-      S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
-	dyn_cast<NamedDecl>(d)->getNameAsString();
-      return;
-    }
+  const DeclContext *Ctx = d->getDeclContext()->getRedeclContext();
+  if (!Ctx->isFileContext()) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_weakref_not_global_context) <<
+        dyn_cast<NamedDecl>(d)->getNameAsString();
+    return;
   }
 
   // The GCC manual says
@@ -424,10 +604,10 @@ static void HandleWeakRefAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     }
     // GCC will accept anything as the argument of weakref. Should we
     // check for an existing decl?
-    d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+    d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
   }
 
-  d->addAttr(::new (S.Context) WeakRefAttr());
+  d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -449,7 +629,7 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
   // FIXME: check if target symbol exists in current file
 
-  d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+  d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
 }
 
 static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -466,7 +646,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
     return;
   }
 
-  d->addAttr(::new (S.Context) AlwaysInlineAttr());
+  d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -479,7 +659,7 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
     QualType RetTy = FD->getResultType();
     if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
-      d->addAttr(::new (S.Context) MallocAttr());
+      d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
       return;
     }
   }
@@ -487,39 +667,75 @@ static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   S.Diag(Attr.getLoc(), diag::warn_attribute_malloc_pointer_only);
 }
 
-static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
-                                     Sema &S) {
-  // check the attribute arguments.
+static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
+  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
+  assert(Attr.isInvalid() == false);
+  d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
+}
+
+static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+                                       Sema &S) {
+  
+  // The checking path for 'noreturn' and 'analyzer_noreturn' are different
+  // because 'analyzer_noreturn' does not impact the type.
+  
   if (Attr.getNumArgs() != 0) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
-    return false;
+    return;
   }
-
+  
   if (!isFunctionOrMethod(d) && !isa<BlockDecl>(d)) {
     ValueDecl *VD = dyn_cast<ValueDecl>(d);
     if (VD == 0 || (!VD->getType()->isBlockPointerType()
                     && !VD->getType()->isFunctionPointerType())) {
       S.Diag(Attr.getLoc(),
              Attr.isCXX0XAttribute() ? diag::err_attribute_wrong_decl_type
-                                     : diag::warn_attribute_wrong_decl_type)
-        << Attr.getName() << 0 /*function*/;
-      return false;
+             : diag::warn_attribute_wrong_decl_type)
+      << Attr.getName() << 0 /*function*/;
+      return;
     }
   }
-
-  return true;
-}
-
-static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
-  /* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
-  assert(Attr.isInvalid() == false);
-  d->addAttr(::new (S.Context) NoReturnAttr());
+  
+  d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
 }
 
-static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
+// PS3 PPU-specific.
+static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
                                        Sema &S) {
-  if (HandleCommonNoReturnAttr(d, Attr, S))
-    d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+/*
+  Returning a Vector Class in Registers
+  
+  According to the PPU ABI specifications, a class with a single member of vector type is returned in
+  memory when used as the return value of a function. This results in inefficient code when implementing
+  vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
+  definition. This attribute is also applicable to struct types.
+  
+  Example:
+  
+  struct Vector
+  {
+    __vector float xyzw;
+  } __attribute__((vecreturn));
+  
+  Vector Add(Vector lhs, Vector rhs)
+  {
+    Vector result;
+    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
+    return result; // This will be returned in a register
+  }
+*/
+  if (!isa<CXXRecordDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << 9 /*class*/;
+    return;
+  }
+
+  if (d->getAttr<VecReturnAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
+    return;
+  }
+
+  d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -545,7 +761,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) UnusedAttr());
+  d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -566,7 +782,7 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) UsedAttr());
+  d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -596,7 +812,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstructorAttr(priority));
+  d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
 }
 
 static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -626,7 +842,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) DestructorAttr(priority));
+  d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
 }
 
 static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -636,7 +852,7 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) DeprecatedAttr());
+  d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -646,7 +862,7 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) UnavailableAttr());
+  d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -667,22 +883,22 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   }
 
   llvm::StringRef TypeStr = Str->getString();
-  VisibilityAttr::VisibilityTypes type;
+  VisibilityAttr::VisibilityType type;
 
   if (TypeStr == "default")
-    type = VisibilityAttr::DefaultVisibility;
+    type = VisibilityAttr::Default;
   else if (TypeStr == "hidden")
-    type = VisibilityAttr::HiddenVisibility;
+    type = VisibilityAttr::Hidden;
   else if (TypeStr == "internal")
-    type = VisibilityAttr::HiddenVisibility; // FIXME
+    type = VisibilityAttr::Hidden; // FIXME
   else if (TypeStr == "protected")
-    type = VisibilityAttr::ProtectedVisibility;
+    type = VisibilityAttr::Protected;
   else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
     return;
   }
 
-  d->addAttr(::new (S.Context) VisibilityAttr(type));
+  d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
 }
 
 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -698,7 +914,7 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
     return;
   }
 
-  D->addAttr(::new (S.Context) ObjCExceptionAttr());
+  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -714,7 +930,7 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
       return;
     }
   }
-  D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
 }
 
 static void
@@ -729,7 +945,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  D->addAttr(::new (S.Context) OverloadableAttr());
+  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -744,7 +960,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  BlocksAttr::BlocksAttrTypes type;
+  BlocksAttr::BlockType type;
   if (Attr.getParameterName()->isStr("byref"))
     type = BlocksAttr::ByRef;
   else {
@@ -753,7 +969,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) BlocksAttr(type));
+  d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
 }
 
 static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -846,7 +1062,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
       << Attr.getName() << 6 /*function, method or block */;
     return;
   }
-  d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+  d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
 }
 
 static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -874,7 +1090,7 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S)
       return;
     }
   
-  D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -898,7 +1114,7 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakAttr());
+  D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -934,7 +1150,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakImportAttr());
+  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -957,7 +1173,8 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
     }
     WGSize[i] = (unsigned) ArgNum.getZExtValue();
   }
-  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+  D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
+                                                     WGSize[0], WGSize[1],
                                                      WGSize[2]));
 }
 
@@ -991,7 +1208,7 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
     return;
   }
   
-  D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+  D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
 }
 
 
@@ -1002,7 +1219,7 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) NoThrowAttr());
+  d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1012,7 +1229,7 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) ConstAttr());
+  d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1022,7 +1239,7 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) PureAttr());
+  d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1080,7 +1297,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) CleanupAttr(FD));
+  d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
 }
 
 /// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -1143,7 +1360,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+  d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
 }
 
 enum FormatAttrKind {
@@ -1225,7 +1442,7 @@ static void HandleInitPriorityAttr(Decl *d, const AttributeList &Attr,
     Attr.setInvalid();
     return;
   }
-  d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
+  d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
 }
 
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -1369,7 +1586,8 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+  d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+                                          Idx.getZExtValue(),
                                           FirstArg.getZExtValue()));
 }
 
@@ -1438,7 +1656,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
     }
   }
 
-  RD->addAttr(::new (S.Context) TransparentUnionAttr());
+  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1456,7 +1674,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
     return;
   }
-  d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+  d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
 }
 
 static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1471,9 +1689,7 @@ static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
   //       weaker alignment, rather than being silently ignored.
 
   if (Attr.getNumArgs() == 0) {
-    // FIXME: This should be the target specific maximum alignment.
-    // (For now we just use 128 bits which is the maximum on X86).
-    D->addAttr(::new (S.Context) AlignedAttr(128));
+    D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
     return;
   }
 
@@ -1483,10 +1699,11 @@ static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
 void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
   if (E->isTypeDependent() || E->isValueDependent()) {
     // Save dependent expressions in the AST to be instantiated.
-    D->addAttr(::new (Context) AlignedAttr(E));
+    D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
     return;
   }
 
+  // FIXME: Cache the number on the Attr object?
   llvm::APSInt Alignment(32);
   if (!E->isIntegerConstantExpr(Alignment, Context)) {
     Diag(AttrLoc, diag::err_attribute_argument_not_int)
@@ -1499,7 +1716,14 @@ void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
     return;
   }
 
-  D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8));
+  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
+  // FIXME: Cache the number on the Attr object if non-dependent?
+  // FIXME: Perform checking of type validity
+  D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
+  return;
 }
 
 /// HandleModeAttr - This attribute modifies the width of a decl with primitive
@@ -1686,7 +1910,7 @@ static void HandleNoDebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) NoDebugAttr());
+  d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1702,7 +1926,7 @@ static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) NoInlineAttr());
+  d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
@@ -1719,7 +1943,7 @@ static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
     return;
   }
 
-  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr());
+  d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1741,7 +1965,7 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) GNUInlineAttr());
+  d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1751,15 +1975,19 @@ static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
 
   switch (Attr.getKind()) {
   case AttributeList::AT_fastcall:
-    d->addAttr(::new (S.Context) FastCallAttr());
+    d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
     return;
   case AttributeList::AT_stdcall:
-    d->addAttr(::new (S.Context) StdCallAttr());
+    d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
     return;
   case AttributeList::AT_thiscall:
-    d->addAttr(::new (S.Context) ThisCallAttr());
+    d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
+    return;
   case AttributeList::AT_cdecl:
-    d->addAttr(::new (S.Context) CDeclAttr());
+    d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
+    return;
+  case AttributeList::AT_pascal:
+    d->addAttr(::new (S.Context) PascalAttr(Attr.getLoc(), S.Context));
     return;
   default:
     llvm_unreachable("unexpected attribute kind");
@@ -1801,7 +2029,8 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+  d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
+                                           NumParams.getZExtValue()));
 }
 
 static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1827,7 +2056,7 @@ static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) FinalAttr());
+  d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1853,7 +2082,7 @@ static void HandleBaseCheckAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
   
-  d->addAttr(::new (S.Context) BaseCheckAttr());
+  d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1878,7 +2107,7 @@ static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) HidingAttr());
+  d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1903,7 +2132,7 @@ static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  d->addAttr(::new (S.Context) OverrideAttr());
+  d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1939,16 +2168,16 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
       assert(0 && "invalid ownership attribute");
       return;
     case AttributeList::AT_cf_returns_not_retained:
-      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+      d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_ns_returns_not_retained:
-      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+      d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_cf_returns_retained:
-      d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+      d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
       return;
     case AttributeList::AT_ns_returns_retained:
-      d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+      d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
       return;
   };
 }
@@ -2009,9 +2238,14 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_mode:        HandleModeAttr        (D, Attr, S); break;
   case AttributeList::AT_malloc:      HandleMallocAttr      (D, Attr, S); break;
   case AttributeList::AT_nonnull:     HandleNonNullAttr     (D, Attr, S); break;
+  case AttributeList::AT_ownership_returns:
+  case AttributeList::AT_ownership_takes:
+  case AttributeList::AT_ownership_holds:
+      HandleOwnershipAttr     (D, Attr, S); break;
   case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
   case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
   case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
+  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
 
   // Checker-specific.
   case AttributeList::AT_ns_returns_not_retained:
@@ -2063,6 +2297,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_cdecl:
   case AttributeList::AT_fastcall:
   case AttributeList::AT_thiscall:
+  case AttributeList::AT_pascal:
     HandleCallConvAttr(D, Attr, S);
     break;
   default:
@@ -2087,7 +2322,7 @@ void Sema::ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *Attr
   // but that looks really pointless. We reject it.
   if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
     Diag(AttrList->getLoc(), diag::err_attribute_weakref_without_alias) <<
-	dyn_cast<NamedDecl>(D)->getNameAsString();
+    dyn_cast<NamedDecl>(D)->getNameAsString();
     return;
   }
 }
@@ -2127,8 +2362,9 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
   if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
     IdentifierInfo *NDId = ND->getIdentifier();
     NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
-    NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
-    NewD->addAttr(::new (Context) WeakAttr());
+    NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
+                                            NDId->getName()));
+    NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
     WeakTopLevelDecl.push_back(NewD);
     // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
     // to insert Decl at TU scope, sorry.
@@ -2137,7 +2373,7 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) {
     PushOnScopeChains(NewD, S);
     CurContext = SavedContext;
   } else { // just add weak to existing
-    ND->addAttr(::new (Context) WeakAttr());
+    ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
   }
 }
 
@@ -2179,12 +2415,12 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
 ///
 /// The state token we use is the start index of this scope
 /// on the warning stack.
-Action::ParsingDeclStackState Sema::PushParsingDeclaration() {
+Sema::ParsingDeclStackState Sema::PushParsingDeclaration() {
   ParsingDeclDepth++;
   return (ParsingDeclStackState) DelayedDiagnostics.size();
 }
 
-void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
+void Sema::PopParsingDeclaration(ParsingDeclStackState S, Decl *D) {
   assert(ParsingDeclDepth > 0 && "empty ParsingDeclaration stack");
   ParsingDeclDepth--;
 
@@ -2199,7 +2435,6 @@ void Sema::PopParsingDeclaration(ParsingDeclStackState S, DeclPtrTy Ctx) {
 
   // We only want to actually emit delayed diagnostics when we
   // successfully parsed a decl.
-  Decl *D = Ctx ? Ctx.getAs<Decl>() : 0;
   if (D) {
     // We really do want to start with 0 here.  We get one push for a
     // decl spec and another for each declarator;  in a decl group like:
@@ -2238,7 +2473,7 @@ static bool isDeclDeprecated(Decl *D) {
   return false;
 }
 
-void Sema::HandleDelayedDeprecationCheck(Sema::DelayedDiagnostic &DD,
+void Sema::HandleDelayedDeprecationCheck(DelayedDiagnostic &DD,
                                          Decl *Ctx) {
   if (isDeclDeprecated(Ctx))
     return;
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index bd97df2..63acdb5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -11,9 +11,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/CXXFieldCollector.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -23,10 +25,11 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include <map>
 #include <set>
@@ -108,7 +111,7 @@ namespace {
 }
 
 bool
-Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
+Sema::SetParamDefaultArgument(ParmVarDecl *Param, Expr *Arg,
                               SourceLocation EqualLoc) {
   if (RequireCompleteType(Param->getLocation(), Param->getType(),
                           diag::err_typecheck_decl_incomplete_type)) {
@@ -116,8 +119,6 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
     return true;
   }
 
-  Expr *Arg = (Expr *)DefaultArg.get();
-
   // C++ [dcl.fct.default]p5
   //   A default argument expression is implicitly converted (clause
   //   4) to the parameter type. The default argument expression has
@@ -128,8 +129,8 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
   InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(),
                                                            EqualLoc);
   InitializationSequence InitSeq(*this, Entity, Kind, &Arg, 1);
-  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                          MultiExprArg(*this, (void**)&Arg, 1));
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                            MultiExprArg(*this, &Arg, 1));
   if (Result.isInvalid())
     return true;
   Arg = Result.takeAs<Expr>();
@@ -139,8 +140,6 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
   // Okay: add the default argument to the parameter
   Param->setDefaultArg(Arg);
 
-  DefaultArg.release();
-
   return false;
 }
 
@@ -148,16 +147,14 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
 /// provided for a function parameter is well-formed. If so, attach it
 /// to the parameter declaration.
 void
-Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
-                                ExprArg defarg) {
-  if (!param || !defarg.get())
+Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc,
+                                Expr *DefaultArg) {
+  if (!param || !DefaultArg)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(param);
   UnparsedDefaultArgLocs.erase(Param);
 
-  ExprOwningPtr<Expr> DefaultArg(this, defarg.takeAs<Expr>());
-
   // Default arguments are only permitted in C++
   if (!getLangOptions().CPlusPlus) {
     Diag(EqualLoc, diag::err_param_default_argument)
@@ -167,26 +164,26 @@ Sema::ActOnParamDefaultArgument(DeclPtrTy param, SourceLocation EqualLoc,
   }
 
   // Check that the default argument is well-formed
-  CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
-  if (DefaultArgChecker.Visit(DefaultArg.get())) {
+  CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg, this);
+  if (DefaultArgChecker.Visit(DefaultArg)) {
     Param->setInvalidDecl();
     return;
   }
 
-  SetParamDefaultArgument(Param, move(DefaultArg), EqualLoc);
+  SetParamDefaultArgument(Param, DefaultArg, EqualLoc);
 }
 
 /// ActOnParamUnparsedDefaultArgument - We've seen a default
 /// argument for a function parameter, but we can't parse it yet
 /// because we're inside a class definition. Note that this default
 /// argument will be parsed later.
-void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
+void Sema::ActOnParamUnparsedDefaultArgument(Decl *param,
                                              SourceLocation EqualLoc,
                                              SourceLocation ArgLoc) {
   if (!param)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(param);
   if (Param)
     Param->setUnparsedDefaultArg();
 
@@ -195,11 +192,11 @@ void Sema::ActOnParamUnparsedDefaultArgument(DeclPtrTy param,
 
 /// ActOnParamDefaultArgumentError - Parsing or semantic analysis of
 /// the default argument for the parameter param failed.
-void Sema::ActOnParamDefaultArgumentError(DeclPtrTy param) {
+void Sema::ActOnParamDefaultArgumentError(Decl *param) {
   if (!param)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(param.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(param);
 
   Param->setInvalidDecl();
 
@@ -224,7 +221,7 @@ void Sema::CheckExtraCXXDefaultArguments(Declarator &D) {
     if (chunk.Kind == DeclaratorChunk::Function) {
       for (unsigned argIdx = 0, e = chunk.Fun.NumArgs; argIdx != e; ++argIdx) {
         ParmVarDecl *Param =
-          cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param.getAs<Decl>());
+          cast<ParmVarDecl>(chunk.Fun.ArgInfo[argIdx].Param);
         if (Param->hasUnparsedDefaultArg()) {
           CachedTokens *Toks = chunk.Fun.ArgInfo[argIdx].DefaultArgTokens;
           Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
@@ -412,8 +409,6 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) {
     for (p = 0; p <= LastMissingDefaultArg; ++p) {
       ParmVarDecl *Param = FD->getParamDecl(p);
       if (Param->hasDefaultArg()) {
-        if (!Param->hasUnparsedDefaultArg())
-          Param->getDefaultArg()->Destroy(Context);
         Param->setDefaultArg(0);
       }
     }
@@ -449,8 +444,9 @@ CXXBaseSpecifier *
 Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
                          SourceRange SpecifierRange,
                          bool Virtual, AccessSpecifier Access,
-                         QualType BaseType,
-                         SourceLocation BaseLoc) {
+                         TypeSourceInfo *TInfo) {
+  QualType BaseType = TInfo->getType();
+
   // C++ [class.union]p1:
   //   A union shall not have base classes.
   if (Class->isUnion()) {
@@ -461,8 +457,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
 
   if (BaseType->isDependentType())
     return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                                Class->getTagKind() == TTK_Class,
-                                Access, BaseType);
+                                          Class->getTagKind() == TTK_Class,
+                                          Access, TInfo);
+
+  SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
 
   // Base specifiers must be record types.
   if (!BaseType->isRecordType()) {
@@ -482,8 +480,10 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   //   defined class.
   if (RequireCompleteType(BaseLoc, BaseType,
                           PDiag(diag::err_incomplete_base_class)
-                            << SpecifierRange))
+                            << SpecifierRange)) {
+    Class->setInvalidDecl();
     return 0;
+  }
 
   // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
   RecordDecl *BaseDecl = BaseType->getAs<RecordType>()->getDecl();
@@ -502,11 +502,14 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
   }
 
   SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual);
+
+  if (BaseDecl->isInvalidDecl())
+    Class->setInvalidDecl();
   
   // Create the base specifier.
   return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual,
-                              Class->getTagKind() == TTK_Class,
-                              Access, BaseType);
+                                        Class->getTagKind() == TTK_Class,
+                                        Access, TInfo);
 }
 
 void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
@@ -581,22 +584,22 @@ void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,
 /// example:
 ///    class foo : public bar, virtual private baz {
 /// 'public bar' and 'virtual private baz' are each base-specifiers.
-Sema::BaseResult
-Sema::ActOnBaseSpecifier(DeclPtrTy classdecl, SourceRange SpecifierRange,
+BaseResult
+Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
                          bool Virtual, AccessSpecifier Access,
-                         TypeTy *basetype, SourceLocation BaseLoc) {
+                         ParsedType basetype, SourceLocation BaseLoc) {
   if (!classdecl)
     return true;
 
   AdjustDeclIfTemplate(classdecl);
-  CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl.getAs<Decl>());
+  CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(classdecl);
   if (!Class)
     return true;
 
-  QualType BaseType = GetTypeFromParser(basetype);
+  TypeSourceInfo *TInfo = 0;
+  GetTypeFromParser(basetype, &TInfo);
   if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
-                                                      Virtual, Access,
-                                                      BaseType, BaseLoc))
+                                                      Virtual, Access, TInfo))
     return BaseSpec;
 
   return true;
@@ -664,13 +667,13 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
 /// ActOnBaseSpecifiers - Attach the given base specifiers to the
 /// class, after checking whether there are any duplicate base
 /// classes.
-void Sema::ActOnBaseSpecifiers(DeclPtrTy ClassDecl, BaseTy **Bases,
+void Sema::ActOnBaseSpecifiers(Decl *ClassDecl, BaseTy **Bases,
                                unsigned NumBases) {
   if (!ClassDecl || !Bases || !NumBases)
     return;
 
   AdjustDeclIfTemplate(ClassDecl);
-  AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl.getAs<Decl>()),
+  AttachBaseSpecifiers(cast<CXXRecordDecl>(ClassDecl),
                        (CXXBaseSpecifier**)(Bases), NumBases);
 }
 
@@ -719,7 +722,7 @@ bool Sema::IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths) {
 }
 
 void Sema::BuildBasePathArray(const CXXBasePaths &Paths, 
-                              CXXBaseSpecifierArray &BasePathArray) {
+                              CXXCastPath &BasePathArray) {
   assert(BasePathArray.empty() && "Base path array must be empty!");
   assert(Paths.isRecordingPaths() && "Must record paths!");
   
@@ -738,14 +741,14 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths,
 
   // Now add all bases.
   for (unsigned I = Start, E = Path.size(); I != E; ++I)
-    BasePathArray.push_back(Path[I].Base);
+    BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base));
 }
 
 /// \brief Determine whether the given base path includes a virtual
 /// base class.
-bool Sema::BasePathInvolvesVirtualBase(const CXXBaseSpecifierArray &BasePath) {
-  for (CXXBaseSpecifierArray::iterator B = BasePath.begin(), 
-                                    BEnd = BasePath.end();
+bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) {
+  for (CXXCastPath::const_iterator B = BasePath.begin(), 
+                                BEnd = BasePath.end();
        B != BEnd; ++B)
     if ((*B)->isVirtual())
       return true;
@@ -767,7 +770,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                    unsigned AmbigiousBaseConvID,
                                    SourceLocation Loc, SourceRange Range,
                                    DeclarationName Name,
-                                   CXXBaseSpecifierArray *BasePath) {
+                                   CXXCastPath *BasePath) {
   // First, determine whether the path from Derived to Base is
   // ambiguous. This is slightly more expensive than checking whether
   // the Derived to Base conversion exists, because here we need to
@@ -825,7 +828,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
 bool
 Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base,
                                    SourceLocation Loc, SourceRange Range,
-                                   CXXBaseSpecifierArray *BasePath,
+                                   CXXCastPath *BasePath,
                                    bool IgnoreAccess) {
   return CheckDerivedToBaseConversion(Derived, Base,
                                       IgnoreAccess ? 0
@@ -872,30 +875,31 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) {
 //===----------------------------------------------------------------------===//
 
 /// ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
-Sema::DeclPtrTy
-Sema::ActOnAccessSpecifier(AccessSpecifier Access,
-                           SourceLocation ASLoc, SourceLocation ColonLoc) {
+Decl *Sema::ActOnAccessSpecifier(AccessSpecifier Access,
+                                 SourceLocation ASLoc,
+                                 SourceLocation ColonLoc) {
   assert(Access != AS_none && "Invalid kind for syntactic access specifier!");
-  AccessSpecDecl* ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
+  AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
                                                   ASLoc, ColonLoc);
   CurContext->addHiddenDecl(ASDecl);
-  return DeclPtrTy::make(ASDecl);
+  return ASDecl;
 }
 
 /// ActOnCXXMemberDeclarator - This is invoked when a C++ class member
 /// declarator is parsed. 'AS' is the access specifier, 'BW' specifies the
 /// bitfield width if there is one and 'InitExpr' specifies the initializer if
 /// any.
-Sema::DeclPtrTy
+Decl *
 Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
                                MultiTemplateParamsArg TemplateParameterLists,
                                ExprTy *BW, ExprTy *InitExpr, bool IsDefinition,
                                bool Deleted) {
   const DeclSpec &DS = D.getDeclSpec();
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
+  SourceLocation Loc = NameInfo.getLoc();
   Expr *BitWidth = static_cast<Expr*>(BW);
   Expr *Init = static_cast<Expr*>(InitExpr);
-  SourceLocation Loc = D.getIdentifierLoc();
 
   assert(isa<CXXRecordDecl>(CurContext));
   assert(!DS.isFriendSpecified());
@@ -905,7 +909,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
     isFunc = true;
   else if (D.getNumTypeObjects() == 0 &&
            D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_typename) {
-    QualType TDType = GetTypeFromParser(DS.getTypeRep());
+    QualType TDType = GetTypeFromParser(DS.getRepAsType());
     isFunc = TDType->isFunctionType();
   }
 
@@ -952,11 +956,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
                          AS);
     assert(Member && "HandleField never returns null");
   } else {
-    Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition)
-               .getAs<Decl>();
+    Member = HandleDeclarator(S, D, move(TemplateParameterLists), IsDefinition);
     if (!Member) {
-      if (BitWidth) DeleteExpr(BitWidth);
-      return DeclPtrTy();
+      return 0;
     }
 
     // Non-instance-fields can't have a bitfield.
@@ -980,7 +982,6 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
           << BitWidth->getSourceRange();
       }
 
-      DeleteExpr(BitWidth);
       BitWidth = 0;
       Member->setInvalidDecl();
     }
@@ -996,15 +997,15 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
   assert((Name || isInstField) && "No identifier for non-field ?");
 
   if (Init)
-    AddInitializerToDecl(DeclPtrTy::make(Member), ExprArg(*this, Init), false);
+    AddInitializerToDecl(Member, Init, false);
   if (Deleted) // FIXME: Source location is not very good.
-    SetDeclDeleted(DeclPtrTy::make(Member), D.getSourceRange().getBegin());
+    SetDeclDeleted(Member, D.getSourceRange().getBegin());
 
   if (isInstField) {
     FieldCollector->Add(cast<FieldDecl>(Member));
-    return DeclPtrTy();
+    return 0;
   }
-  return DeclPtrTy::make(Member);
+  return Member;
 }
 
 /// \brief Find the direct and/or virtual base specifiers that
@@ -1053,12 +1054,12 @@ static bool FindBaseInitializer(Sema &SemaRef,
 }
 
 /// ActOnMemInitializer - Handle a C++ member initializer.
-Sema::MemInitResult
-Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
+MemInitResult
+Sema::ActOnMemInitializer(Decl *ConstructorD,
                           Scope *S,
                           CXXScopeSpec &SS,
                           IdentifierInfo *MemberOrBase,
-                          TypeTy *TemplateTypeTy,
+                          ParsedType TemplateTypeTy,
                           SourceLocation IdLoc,
                           SourceLocation LParenLoc,
                           ExprTy **Args, unsigned NumArgs,
@@ -1070,7 +1071,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
   AdjustDeclIfTemplate(ConstructorD);
 
   CXXConstructorDecl *Constructor
-    = dyn_cast<CXXConstructorDecl>(ConstructorD.getAs<Decl>());
+    = dyn_cast<CXXConstructorDecl>(ConstructorD);
   if (!Constructor) {
     // The user wrote a constructor initializer on a function that is
     // not a C++ constructor. Ignore the error for now, because we may
@@ -1148,7 +1149,7 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
           CorrectTypo(R, S, &SS, ClassDecl, 0, CTC_NoKeywords) && 
           R.isSingleResult()) {
         if (FieldDecl *Member = R.getAsSingle<FieldDecl>()) {
-          if (Member->getDeclContext()->getLookupContext()->Equals(ClassDecl)) {
+          if (Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl)) {
             // We have found a non-static data member with a similar
             // name to what was typed; complain and initialize that
             // member.
@@ -1259,7 +1260,7 @@ static bool InitExprContainsUninitializedFields(const Stmt *S,
   return false;
 }
 
-Sema::MemInitResult
+MemInitResult
 Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
                              unsigned NumArgs, SourceLocation IdLoc,
                              SourceLocation LParenLoc,
@@ -1285,15 +1286,12 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
   for (unsigned i = 0; i < NumArgs; i++)
     HasDependentArg |= Args[i]->isTypeDependent();
 
-  QualType FieldType = Member->getType();
-  if (const ArrayType *Array = Context.getAsArrayType(FieldType))
-    FieldType = Array->getElementType();
-  if (FieldType->isDependentType() || HasDependentArg) {
+  if (Member->getType()->isDependentType() || HasDependentArg) {
     // Can't check initialization for a member of dependent type or when
     // any of the arguments are type-dependent expressions.
-    OwningExprResult Init
-      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
-                                          RParenLoc));
+    Expr *Init
+      = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                    RParenLoc);
 
     // Erase any temporaries within this evaluation context; we're not
     // going to track them in the AST, since we'll be rebuilding the
@@ -1304,7 +1302,7 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
     
     return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
                                                     LParenLoc, 
-                                                    Init.takeAs<Expr>(),
+                                                    Init,
                                                     RParenLoc);
     
   }
@@ -1320,16 +1318,16 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
   
   InitializationSequence InitSeq(*this, MemberEntity, Kind, Args, NumArgs);
   
-  OwningExprResult MemberInit =
+  ExprResult MemberInit =
     InitSeq.Perform(*this, MemberEntity, Kind, 
-                    MultiExprArg(*this, (void**)Args, NumArgs), 0);
+                    MultiExprArg(*this, Args, NumArgs), 0);
   if (MemberInit.isInvalid())
     return true;
   
   // C++0x [class.base.init]p7:
   //   The initialization of each base and member constitutes a 
   //   full-expression.
-  MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+  MemberInit = MaybeCreateCXXExprWithTemporaries(MemberInit.get());
   if (MemberInit.isInvalid())
     return true;
   
@@ -1345,22 +1343,21 @@ Sema::BuildMemberInitializer(FieldDecl *Member, Expr **Args,
     for (unsigned I = 0; I != NumArgs; ++I)
       Args[I]->Retain();
 
-    OwningExprResult Init
-      = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
-                                          RParenLoc));
+    Expr *Init = new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
+                                             RParenLoc);
     return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
                                                     LParenLoc, 
-                                                    Init.takeAs<Expr>(),
+                                                    Init,
                                                     RParenLoc);
   }
 
   return new (Context) CXXBaseOrMemberInitializer(Context, Member, IdLoc,
                                                   LParenLoc, 
-                                                  MemberInit.takeAs<Expr>(),
+                                                  MemberInit.get(),
                                                   RParenLoc);
 }
 
-Sema::MemInitResult
+MemInitResult
 Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
                            Expr **Args, unsigned NumArgs, 
                            SourceLocation LParenLoc, SourceLocation RParenLoc, 
@@ -1413,7 +1410,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
   if (Dependent) {
     // Can't check initialization for a base of dependent type or when
     // any of the arguments are type-dependent expressions.
-    OwningExprResult BaseInit
+    ExprResult BaseInit
       = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
                                           RParenLoc));
 
@@ -1452,16 +1449,16 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
   
   InitializationSequence InitSeq(*this, BaseEntity, Kind, Args, NumArgs);
   
-  OwningExprResult BaseInit =
+  ExprResult BaseInit =
     InitSeq.Perform(*this, BaseEntity, Kind, 
-                    MultiExprArg(*this, (void**)Args, NumArgs), 0);
+                    MultiExprArg(*this, Args, NumArgs), 0);
   if (BaseInit.isInvalid())
     return true;
   
   // C++0x [class.base.init]p7:
   //   The initialization of each base and member constitutes a 
   //   full-expression.
-  BaseInit = MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+  BaseInit = MaybeCreateCXXExprWithTemporaries(BaseInit.get());
   if (BaseInit.isInvalid())
     return true;
 
@@ -1477,7 +1474,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
     for (unsigned I = 0; I != NumArgs; ++I)
       Args[I]->Retain();
 
-    OwningExprResult Init
+    ExprResult Init
       = Owned(new (Context) ParenListExpr(Context, LParenLoc, Args, NumArgs,
                                           RParenLoc));
     return new (Context) CXXBaseOrMemberInitializer(Context, BaseTInfo,
@@ -1512,7 +1509,7 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
     = InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec,
                                         IsInheritedVirtualBase);
 
-  Sema::OwningExprResult BaseInit(SemaRef);
+  ExprResult BaseInit;
   
   switch (ImplicitInitKind) {
   case IIK_Default: {
@@ -1520,7 +1517,7 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
       = InitializationKind::CreateDefault(Constructor->getLocation());
     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
     BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
-                               Sema::MultiExprArg(SemaRef, 0, 0));
+                               MultiExprArg(SemaRef, 0, 0));
     break;
   }
 
@@ -1536,10 +1533,12 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
     QualType ArgTy = 
       SemaRef.Context.getQualifiedType(BaseSpec->getType().getUnqualifiedType(), 
                                        ParamType.getQualifiers());
-    SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy, 
-                              CastExpr::CK_UncheckedDerivedToBase,
-                              /*isLvalue=*/true, 
-                              CXXBaseSpecifierArray(BaseSpec));
+
+    CXXCastPath BasePath;
+    BasePath.push_back(BaseSpec);
+    SemaRef.ImpCastExprToType(CopyCtorArg, ArgTy,
+                              CK_UncheckedDerivedToBase,
+                              VK_LValue, &BasePath);
 
     InitializationKind InitKind
       = InitializationKind::CreateDirect(Constructor->getLocation(),
@@ -1547,16 +1546,18 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 
                                    &CopyCtorArg, 1);
     BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
-                               Sema::MultiExprArg(SemaRef, 
-                                                  (void**)&CopyCtorArg, 1));
+                               MultiExprArg(&CopyCtorArg, 1));
     break;
   }
 
   case IIK_Move:
     assert(false && "Unhandled initializer kind!");
   }
+
+  if (BaseInit.isInvalid())
+    return true;
       
-  BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(BaseInit));
+  BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(BaseInit.get());
   if (BaseInit.isInvalid())
     return true;
         
@@ -1596,8 +1597,8 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
                               Sema::LookupMemberName);
     MemberLookup.addDecl(Field, AS_public);
     MemberLookup.resolveKind();
-    Sema::OwningExprResult CopyCtorArg 
-      = SemaRef.BuildMemberReferenceExpr(SemaRef.Owned(MemberExprBase),
+    ExprResult CopyCtorArg 
+      = SemaRef.BuildMemberReferenceExpr(MemberExprBase,
                                          ParamType, Loc,
                                          /*IsArrow=*/false,
                                          SS,
@@ -1628,19 +1629,19 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
         = VarDecl::Create(SemaRef.Context, SemaRef.CurContext, Loc,
                           IterationVarName, SizeType,
                         SemaRef.Context.getTrivialTypeSourceInfo(SizeType, Loc),
-                          VarDecl::None, VarDecl::None);
+                          SC_None, SC_None);
       IndexVariables.push_back(IterationVar);
       
       // Create a reference to the iteration variable.
-      Sema::OwningExprResult IterationVarRef
+      ExprResult IterationVarRef
         = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, Loc);
       assert(!IterationVarRef.isInvalid() &&
              "Reference to invented variable cannot fail!");
       
       // Subscript the array with this iteration variable.
-      CopyCtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(move(CopyCtorArg),
+      CopyCtorArg = SemaRef.CreateBuiltinArraySubscriptExpr(CopyCtorArg.take(),
                                                             Loc,
-                                                          move(IterationVarRef),
+                                                        IterationVarRef.take(),
                                                             Loc);
       if (CopyCtorArg.isInvalid())
         return true;
@@ -1667,10 +1668,10 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
     InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind,
                                    &CopyCtorArgE, 1);
     
-    Sema::OwningExprResult MemberInit
+    ExprResult MemberInit
       = InitSeq.Perform(SemaRef, Entities.back(), InitKind, 
-                        Sema::MultiExprArg(SemaRef, (void**)&CopyCtorArgE, 1));
-    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+                        MultiExprArg(&CopyCtorArgE, 1));
+    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(MemberInit.get());
     if (MemberInit.isInvalid())
       return true;
 
@@ -1693,17 +1694,19 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
       InitializationKind::CreateDefault(Loc);
     
     InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
-    Sema::OwningExprResult MemberInit = 
-      InitSeq.Perform(SemaRef, InitEntity, InitKind, 
-                      Sema::MultiExprArg(SemaRef, 0, 0));
-    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+    ExprResult MemberInit = 
+      InitSeq.Perform(SemaRef, InitEntity, InitKind, MultiExprArg());
+    if (MemberInit.isInvalid())
+      return true;
+
+    MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(MemberInit.get());
     if (MemberInit.isInvalid())
       return true;
     
     CXXMemberInit =
       new (SemaRef.Context) CXXBaseOrMemberInitializer(SemaRef.Context,
                                                        Field, Loc, Loc,
-                                                      MemberInit.takeAs<Expr>(),
+                                                       MemberInit.get(),
                                                        Loc);
     return false;
   }
@@ -1797,6 +1800,9 @@ static bool CollectFieldInitializer(BaseAndFieldInfo &Info,
           // Once we've initialized a field of an anonymous union, the union
           // field in the class is also initialized, so exit immediately.
           return false;
+        } else if ((*FA)->isAnonymousStructOrUnion()) {
+          if (CollectFieldInitializer(Info, Top, *FA))
+            return true;
         }
       }
 
@@ -2147,7 +2153,7 @@ bool CheckRedundantUnionInit(Sema &S,
 }
 
 /// ActOnMemInitializers - Handle the member initializers for a constructor.
-void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
+void Sema::ActOnMemInitializers(Decl *ConstructorDecl,
                                 SourceLocation ColonLoc,
                                 MemInitTy **meminits, unsigned NumMemInits,
                                 bool AnyErrors) {
@@ -2157,7 +2163,7 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
   AdjustDeclIfTemplate(ConstructorDecl);
 
   CXXConstructorDecl *Constructor
-    = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>());
+    = dyn_cast<CXXConstructorDecl>(ConstructorDecl);
 
   if (!Constructor) {
     Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
@@ -2292,35 +2298,30 @@ Sema::MarkBaseAndMemberDestructorsReferenced(SourceLocation Location,
   }
 }
 
-void Sema::ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl) {
+void Sema::ActOnDefaultCtorInitializers(Decl *CDtorDecl) {
   if (!CDtorDecl)
     return;
 
   if (CXXConstructorDecl *Constructor
-      = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
+      = dyn_cast<CXXConstructorDecl>(CDtorDecl))
     SetBaseOrMemberInitializers(Constructor, 0, 0, /*AnyErrors=*/false);
 }
 
 bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
-                                  unsigned DiagID, AbstractDiagSelID SelID,
-                                  const CXXRecordDecl *CurrentRD) {
+                                  unsigned DiagID, AbstractDiagSelID SelID) {
   if (SelID == -1)
-    return RequireNonAbstractType(Loc, T,
-                                  PDiag(DiagID), CurrentRD);
+    return RequireNonAbstractType(Loc, T, PDiag(DiagID));
   else
-    return RequireNonAbstractType(Loc, T,
-                                  PDiag(DiagID) << SelID, CurrentRD);
+    return RequireNonAbstractType(Loc, T, PDiag(DiagID) << SelID);
 }
 
 bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
-                                  const PartialDiagnostic &PD,
-                                  const CXXRecordDecl *CurrentRD) {
+                                  const PartialDiagnostic &PD) {
   if (!getLangOptions().CPlusPlus)
     return false;
 
   if (const ArrayType *AT = Context.getAsArrayType(T))
-    return RequireNonAbstractType(Loc, AT->getElementType(), PD,
-                                  CurrentRD);
+    return RequireNonAbstractType(Loc, AT->getElementType(), PD);
 
   if (const PointerType *PT = T->getAs<PointerType>()) {
     // Find the innermost pointer type.
@@ -2328,7 +2329,7 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
       PT = T;
 
     if (const ArrayType *AT = Context.getAsArrayType(PT->getPointeeType()))
-      return RequireNonAbstractType(Loc, AT->getElementType(), PD, CurrentRD);
+      return RequireNonAbstractType(Loc, AT->getElementType(), PD);
   }
 
   const RecordType *RT = T->getAs<RecordType>();
@@ -2337,22 +2338,27 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
 
   const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
 
-  if (CurrentRD && CurrentRD != RD)
-    return false;
-
-  // FIXME: is this reasonable?  It matches current behavior, but....
-  if (!RD->getDefinition())
+  // We can't answer whether something is abstract until it has a
+  // definition.  If it's currently being defined, we'll walk back
+  // over all the declarations when we have a full definition.
+  const CXXRecordDecl *Def = RD->getDefinition();
+  if (!Def || Def->isBeingDefined())
     return false;
 
   if (!RD->isAbstract())
     return false;
 
   Diag(Loc, PD) << RD->getDeclName();
+  DiagnoseAbstractType(RD);
 
-  // Check if we've already emitted the list of pure virtual functions for this
-  // class.
+  return true;
+}
+
+void Sema::DiagnoseAbstractType(const CXXRecordDecl *RD) {
+  // Check if we've already emitted the list of pure virtual functions
+  // for this class.
   if (PureVirtualClassDiagSet && PureVirtualClassDiagSet->count(RD))
-    return true;
+    return;
 
   CXXFinalOverriderMap FinalOverriders;
   RD->getFinalOverriders(FinalOverriders);
@@ -2392,69 +2398,168 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
   if (!PureVirtualClassDiagSet)
     PureVirtualClassDiagSet.reset(new RecordDeclSetTy);
   PureVirtualClassDiagSet->insert(RD);
-
-  return true;
 }
 
 namespace {
-  class AbstractClassUsageDiagnoser
-    : public DeclVisitor<AbstractClassUsageDiagnoser, bool> {
-    Sema &SemaRef;
-    CXXRecordDecl *AbstractClass;
+struct AbstractUsageInfo {
+  Sema &S;
+  CXXRecordDecl *Record;
+  CanQualType AbstractType;
+  bool Invalid;
+
+  AbstractUsageInfo(Sema &S, CXXRecordDecl *Record)
+    : S(S), Record(Record),
+      AbstractType(S.Context.getCanonicalType(
+                   S.Context.getTypeDeclType(Record))),
+      Invalid(false) {}
+
+  void DiagnoseAbstractType() {
+    if (Invalid) return;
+    S.DiagnoseAbstractType(Record);
+    Invalid = true;
+  }
 
-    bool VisitDeclContext(const DeclContext *DC) {
-      bool Invalid = false;
+  void CheckType(const NamedDecl *D, TypeLoc TL, Sema::AbstractDiagSelID Sel);
+};
 
-      for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
-           E = DC->decls_end(); I != E; ++I)
-        Invalid |= Visit(*I);
+struct CheckAbstractUsage {
+  AbstractUsageInfo &Info;
+  const NamedDecl *Ctx;
 
-      return Invalid;
+  CheckAbstractUsage(AbstractUsageInfo &Info, const NamedDecl *Ctx)
+    : Info(Info), Ctx(Ctx) {}
+
+  void Visit(TypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, PARENT)
+#define TYPELOC(CLASS, PARENT) \
+    case TypeLoc::CLASS: Check(cast<CLASS##TypeLoc>(TL), Sel); break;
+#include "clang/AST/TypeLocNodes.def"
     }
+  }
 
-  public:
-    AbstractClassUsageDiagnoser(Sema& SemaRef, CXXRecordDecl *ac)
-      : SemaRef(SemaRef), AbstractClass(ac) {
-        Visit(SemaRef.Context.getTranslationUnitDecl());
+  void Check(FunctionProtoTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    Visit(TL.getResultLoc(), Sema::AbstractReturnType);
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TypeSourceInfo *TSI = TL.getArg(I)->getTypeSourceInfo();
+      if (TSI) Visit(TSI->getTypeLoc(), Sema::AbstractParamType);
     }
+  }
 
-    bool VisitFunctionDecl(const FunctionDecl *FD) {
-      if (FD->isThisDeclarationADefinition()) {
-        // No need to do the check if we're in a definition, because it requires
-        // that the return/param types are complete.
-        // because that requires
-        return VisitDeclContext(FD);
-      }
+  void Check(ArrayTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    Visit(TL.getElementLoc(), Sema::AbstractArrayType);
+  }
 
-      // Check the return type.
-      QualType RTy = FD->getType()->getAs<FunctionType>()->getResultType();
-      bool Invalid =
-        SemaRef.RequireNonAbstractType(FD->getLocation(), RTy,
-                                       diag::err_abstract_type_in_decl,
-                                       Sema::AbstractReturnType,
-                                       AbstractClass);
-
-      for (FunctionDecl::param_const_iterator I = FD->param_begin(),
-           E = FD->param_end(); I != E; ++I) {
-        const ParmVarDecl *VD = *I;
-        Invalid |=
-          SemaRef.RequireNonAbstractType(VD->getLocation(),
-                                         VD->getOriginalType(),
-                                         diag::err_abstract_type_in_decl,
-                                         Sema::AbstractParamType,
-                                         AbstractClass);
-      }
+  void Check(TemplateSpecializationTypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    // Visit the type parameters from a permissive context.
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+      TemplateArgumentLoc TAL = TL.getArgLoc(I);
+      if (TAL.getArgument().getKind() == TemplateArgument::Type)
+        if (TypeSourceInfo *TSI = TAL.getTypeSourceInfo())
+          Visit(TSI->getTypeLoc(), Sema::AbstractNone);
+      // TODO: other template argument types?
+    }
+  }
 
-      return Invalid;
+  // Visit pointee types from a permissive context.
+#define CheckPolymorphic(Type) \
+  void Check(Type TL, Sema::AbstractDiagSelID Sel) { \
+    Visit(TL.getNextTypeLoc(), Sema::AbstractNone); \
+  }
+  CheckPolymorphic(PointerTypeLoc)
+  CheckPolymorphic(ReferenceTypeLoc)
+  CheckPolymorphic(MemberPointerTypeLoc)
+  CheckPolymorphic(BlockPointerTypeLoc)
+
+  /// Handle all the types we haven't given a more specific
+  /// implementation for above.
+  void Check(TypeLoc TL, Sema::AbstractDiagSelID Sel) {
+    // Every other kind of type that we haven't called out already
+    // that has an inner type is either (1) sugar or (2) contains that
+    // inner type in some way as a subobject.
+    if (TypeLoc Next = TL.getNextTypeLoc())
+      return Visit(Next, Sel);
+
+    // If there's no inner type and we're in a permissive context,
+    // don't diagnose.
+    if (Sel == Sema::AbstractNone) return;
+
+    // Check whether the type matches the abstract type.
+    QualType T = TL.getType();
+    if (T->isArrayType()) {
+      Sel = Sema::AbstractArrayType;
+      T = Info.S.Context.getBaseElementType(T);
     }
+    CanQualType CT = T->getCanonicalTypeUnqualified().getUnqualifiedType();
+    if (CT != Info.AbstractType) return;
 
-    bool VisitDecl(const Decl* D) {
-      if (const DeclContext *DC = dyn_cast<DeclContext>(D))
-        return VisitDeclContext(DC);
+    // It matched; do some magic.
+    if (Sel == Sema::AbstractArrayType) {
+      Info.S.Diag(Ctx->getLocation(), diag::err_array_of_abstract_type)
+        << T << TL.getSourceRange();
+    } else {
+      Info.S.Diag(Ctx->getLocation(), diag::err_abstract_type_in_decl)
+        << Sel << T << TL.getSourceRange();
+    }
+    Info.DiagnoseAbstractType();
+  }
+};
 
-      return false;
+void AbstractUsageInfo::CheckType(const NamedDecl *D, TypeLoc TL,
+                                  Sema::AbstractDiagSelID Sel) {
+  CheckAbstractUsage(*this, D).Visit(TL, Sel);
+}
+
+}
+
+/// Check for invalid uses of an abstract type in a method declaration.
+static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
+                                    CXXMethodDecl *MD) {
+  // No need to do the check on definitions, which require that
+  // the return/param types be complete.
+  if (MD->isThisDeclarationADefinition())
+    return;
+
+  // For safety's sake, just ignore it if we don't have type source
+  // information.  This should never happen for non-implicit methods,
+  // but...
+  if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
+    Info.CheckType(MD, TSI->getTypeLoc(), Sema::AbstractNone);
+}
+
+/// Check for invalid uses of an abstract type within a class definition.
+static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
+                                    CXXRecordDecl *RD) {
+  for (CXXRecordDecl::decl_iterator
+         I = RD->decls_begin(), E = RD->decls_end(); I != E; ++I) {
+    Decl *D = *I;
+    if (D->isImplicit()) continue;
+
+    // Methods and method templates.
+    if (isa<CXXMethodDecl>(D)) {
+      CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(D));
+    } else if (isa<FunctionTemplateDecl>(D)) {
+      FunctionDecl *FD = cast<FunctionTemplateDecl>(D)->getTemplatedDecl();
+      CheckAbstractClassUsage(Info, cast<CXXMethodDecl>(FD));
+
+    // Fields and static variables.
+    } else if (isa<FieldDecl>(D)) {
+      FieldDecl *FD = cast<FieldDecl>(D);
+      if (TypeSourceInfo *TSI = FD->getTypeSourceInfo())
+        Info.CheckType(FD, TSI->getTypeLoc(), Sema::AbstractFieldType);
+    } else if (isa<VarDecl>(D)) {
+      VarDecl *VD = cast<VarDecl>(D);
+      if (TypeSourceInfo *TSI = VD->getTypeSourceInfo())
+        Info.CheckType(VD, TSI->getTypeLoc(), Sema::AbstractVariableType);
+
+    // Nested classes and class templates.
+    } else if (isa<CXXRecordDecl>(D)) {
+      CheckAbstractClassUsage(Info, cast<CXXRecordDecl>(D));
+    } else if (isa<ClassTemplateDecl>(D)) {
+      CheckAbstractClassUsage(Info,
+                             cast<ClassTemplateDecl>(D)->getTemplatedDecl());
     }
-  };
+  }
 }
 
 /// \brief Perform semantic checks on a class definition that has been
@@ -2539,8 +2644,10 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
     }
   }
 
-  if (Record->isAbstract() && !Record->isInvalidDecl())
-    (void)AbstractClassUsageDiagnoser(*this, Record);
+  if (Record->isAbstract() && !Record->isInvalidDecl()) {
+    AbstractUsageInfo Info(*this, Record);
+    CheckAbstractClassUsage(Info, Record);
+  }
   
   // If this is not an aggregate type and has no user-declared constructor,
   // complain about any non-static data members of reference or const scalar
@@ -2571,7 +2678,7 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
 }
 
 void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
-                                             DeclPtrTy TagDecl,
+                                             Decl *TagDecl,
                                              SourceLocation LBrac,
                                              SourceLocation RBrac,
                                              AttributeList *AttrList) {
@@ -2581,11 +2688,12 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
   AdjustDeclIfTemplate(TagDecl);
 
   ActOnFields(S, RLoc, TagDecl,
-              (DeclPtrTy*)FieldCollector->getCurFields(),
+              // strict aliasing violation!
+              reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
               FieldCollector->getCurNumFields(), LBrac, RBrac, AttrList);
 
   CheckCompletedCXXClass(
-                        dyn_cast_or_null<CXXRecordDecl>(TagDecl.getAs<Decl>()));
+                        dyn_cast_or_null<CXXRecordDecl>(TagDecl));
 }
 
 namespace {
@@ -2682,8 +2790,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
   }
 }
 
-void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
-  Decl *D = TemplateD.getAs<Decl>();
+void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
   if (!D)
     return;
   
@@ -2701,20 +2808,20 @@ void Sema::ActOnReenterTemplateScope(Scope *S, DeclPtrTy TemplateD) {
        Param != ParamEnd; ++Param) {
     NamedDecl *Named = cast<NamedDecl>(*Param);
     if (Named->getDeclName()) {
-      S->AddDecl(DeclPtrTy::make(Named));
+      S->AddDecl(Named);
       IdResolver.AddDecl(Named);
     }
   }
 }
 
-void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+void Sema::ActOnStartDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
   if (!RecordD) return;
   AdjustDeclIfTemplate(RecordD);
-  CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD.getAs<Decl>());
+  CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordD);
   PushDeclContext(S, Record);
 }
 
-void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
+void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *RecordD) {
   if (!RecordD) return;
   PopDeclContext();
 }
@@ -2727,7 +2834,7 @@ void Sema::ActOnFinishDelayedMemberDeclarations(Scope *S, DeclPtrTy RecordD) {
 /// Method declaration as if we had just parsed the qualified method
 /// name. However, it should not bring the parameters into scope;
 /// that will be performed by ActOnDelayedCXXMethodParameter.
-void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
+void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) {
 }
 
 /// ActOnDelayedCXXMethodParameter - We've already started a delayed
@@ -2735,18 +2842,18 @@ void Sema::ActOnStartDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
 /// function parameter into scope for use in parsing later parts of
 /// the method declaration. For example, we could see an
 /// ActOnParamDefaultArgument event for this parameter.
-void Sema::ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy ParamD) {
+void Sema::ActOnDelayedCXXMethodParameter(Scope *S, Decl *ParamD) {
   if (!ParamD)
     return;
 
-  ParmVarDecl *Param = cast<ParmVarDecl>(ParamD.getAs<Decl>());
+  ParmVarDecl *Param = cast<ParmVarDecl>(ParamD);
 
   // If this parameter has an unparsed default argument, clear it out
   // to make way for the parsed default argument.
   if (Param->hasUnparsedDefaultArg())
     Param->setDefaultArg(0);
 
-  S->AddDecl(DeclPtrTy::make(Param));
+  S->AddDecl(Param);
   if (Param->getDeclName())
     IdResolver.AddDecl(Param);
 }
@@ -2757,13 +2864,13 @@ void Sema::ActOnDelayedCXXMethodParameter(Scope *S, DeclPtrTy ParamD) {
 /// ActOnStartOfFunctionDef action later (not necessarily
 /// immediately!) for this method, if it was also defined inside the
 /// class body.
-void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
+void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *MethodD) {
   if (!MethodD)
     return;
 
   AdjustDeclIfTemplate(MethodD);
 
-  FunctionDecl *Method = cast<FunctionDecl>(MethodD.getAs<Decl>());
+  FunctionDecl *Method = cast<FunctionDecl>(MethodD);
 
   // Now that we have our default arguments, check the constructor
   // again. It could produce additional diagnostics or affect whether
@@ -2784,7 +2891,7 @@ void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) {
 /// will be updated to reflect a well-formed type for the constructor and
 /// returned.
 QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
-                                          FunctionDecl::StorageClass &SC) {
+                                          StorageClass &SC) {
   bool isVirtual = D.getDeclSpec().isVirtualSpecified();
 
   // C++ [class.ctor]p3:
@@ -2799,13 +2906,13 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
         << SourceRange(D.getIdentifierLoc());
     D.setInvalidType();
   }
-  if (SC == FunctionDecl::Static) {
+  if (SC == SC_Static) {
     if (!D.isInvalidType())
       Diag(D.getIdentifierLoc(), diag::err_constructor_cannot_be)
         << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
         << SourceRange(D.getIdentifierLoc());
     D.setInvalidType();
-    SC = FunctionDecl::None;
+    SC = SC_None;
   }
 
   DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun;
@@ -2879,8 +2986,9 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
     ClassDecl->addedConstructor(Context, Constructor);
 }
 
-/// CheckDestructor - Checks a fully-formed destructor for well-formedness, 
-/// issuing any diagnostics required. Returns true on error.
+/// CheckDestructor - Checks a fully-formed destructor definition for
+/// well-formedness, issuing any diagnostics required.  Returns true
+/// on error.
 bool Sema::CheckDestructor(CXXDestructorDecl *Destructor) {
   CXXRecordDecl *RD = Destructor->getParent();
   
@@ -2911,7 +3019,7 @@ static inline bool
 FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
   return (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 &&
           FTI.ArgInfo[0].Param &&
-          FTI.ArgInfo[0].Param.getAs<ParmVarDecl>()->getType()->isVoidType());
+          cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType());
 }
 
 /// CheckDestructorDeclarator - Called by ActOnDeclarator to check
@@ -2921,7 +3029,7 @@ FTIHasSingleVoidArgument(DeclaratorChunk::FunctionTypeInfo &FTI) {
 /// will be updated to reflect a well-formed type for the destructor and
 /// returned.
 QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
-                                         FunctionDecl::StorageClass& SC) {
+                                         StorageClass& SC) {
   // C++ [class.dtor]p1:
   //   [...] A typedef-name that names a class is a class-name
   //   (7.1.3); however, a typedef-name that names a class shall not
@@ -2940,14 +3048,14 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
   //   destructor can be invoked for a const, volatile or const
   //   volatile object. A destructor shall not be declared const,
   //   volatile or const volatile (9.3.2).
-  if (SC == FunctionDecl::Static) {
+  if (SC == SC_Static) {
     if (!D.isInvalidType())
       Diag(D.getIdentifierLoc(), diag::err_destructor_cannot_be)
         << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
         << SourceRange(D.getIdentifierLoc())
         << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
     
-    SC = FunctionDecl::None;
+    SC = SC_None;
   }
   if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
     // Destructors don't have return types, but the parser will
@@ -3015,18 +3123,18 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
 /// false. Either way, the type @p R will be updated to reflect a
 /// well-formed type for the conversion operator.
 void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
-                                     FunctionDecl::StorageClass& SC) {
+                                     StorageClass& SC) {
   // C++ [class.conv.fct]p1:
   //   Neither parameter types nor return type can be specified. The
   //   type of a conversion function (8.3.5) is "function taking no
   //   parameter returning conversion-type-id."
-  if (SC == FunctionDecl::Static) {
+  if (SC == SC_Static) {
     if (!D.isInvalidType())
       Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member)
         << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc())
         << SourceRange(D.getIdentifierLoc());
     D.setInvalidType();
-    SC = FunctionDecl::None;
+    SC = SC_None;
   }
 
   QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId);
@@ -3106,7 +3214,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
 /// the declaration of the given C++ conversion function. This routine
 /// is responsible for recording the conversion function in the C++
 /// class, if possible.
-Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
+Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
   assert(Conversion && "Expected to receive a conversion function declaration");
 
   CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Conversion->getDeclContext());
@@ -3147,10 +3255,10 @@ Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
       if (ClassDecl->replaceConversion(
                                    ConversionTemplate->getPreviousDeclaration(),
                                        ConversionTemplate))
-        return DeclPtrTy::make(ConversionTemplate);
+        return ConversionTemplate;
     } else if (ClassDecl->replaceConversion(Conversion->getPreviousDeclaration(),
                                             Conversion))
-      return DeclPtrTy::make(Conversion);
+      return Conversion;
     assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
   } else if (FunctionTemplateDecl *ConversionTemplate
                = Conversion->getDescribedFunctionTemplate())
@@ -3158,28 +3266,36 @@ Sema::DeclPtrTy Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
   else 
     ClassDecl->addConversionFunction(Conversion);
 
-  return DeclPtrTy::make(Conversion);
+  return Conversion;
 }
 
 //===----------------------------------------------------------------------===//
 // Namespace Handling
 //===----------------------------------------------------------------------===//
 
+
+
 /// ActOnStartNamespaceDef - This is called at the start of a namespace
 /// definition.
-Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
-                                             SourceLocation IdentLoc,
-                                             IdentifierInfo *II,
-                                             SourceLocation LBrace,
-                                             AttributeList *AttrList) {
-  NamespaceDecl *Namespc =
-      NamespaceDecl::Create(Context, CurContext, IdentLoc, II);
+Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
+                                   SourceLocation InlineLoc,
+                                   SourceLocation IdentLoc,
+                                   IdentifierInfo *II,
+                                   SourceLocation LBrace,
+                                   AttributeList *AttrList) {
+  // anonymous namespace starts at its left brace
+  NamespaceDecl *Namespc = NamespaceDecl::Create(Context, CurContext,
+    (II ? IdentLoc : LBrace) , II);
   Namespc->setLBracLoc(LBrace);
+  Namespc->setInline(InlineLoc.isValid());
 
   Scope *DeclRegionScope = NamespcScope->getParent();
 
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
 
+  if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
+    PushVisibilityAttr(attr);
+
   if (II) {
     // C++ [namespace.def]p2:
     // The identifier in an original-namespace-definition shall not have been
@@ -3194,15 +3310,25 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
 
     if (NamespaceDecl *OrigNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl)) {
       // This is an extended namespace definition.
+      if (Namespc->isInline() != OrigNS->isInline()) {
+        // inline-ness must match
+        Diag(Namespc->getLocation(), diag::err_inline_namespace_mismatch)
+          << Namespc->isInline();
+        Diag(OrigNS->getLocation(), diag::note_previous_definition);
+        Namespc->setInvalidDecl();
+        // Recover by ignoring the new namespace's inline status.
+        Namespc->setInline(OrigNS->isInline());
+      }
+
       // Attach this namespace decl to the chain of extended namespace
       // definitions.
       OrigNS->setNextNamespace(Namespc);
       Namespc->setOriginalNamespace(OrigNS->getOriginalNamespace());
 
       // Remove the previous declaration from the scope.
-      if (DeclRegionScope->isDeclScope(DeclPtrTy::make(OrigNS))) {
+      if (DeclRegionScope->isDeclScope(OrigNS)) {
         IdResolver.RemoveDecl(OrigNS);
-        DeclRegionScope->RemoveDecl(DeclPtrTy::make(OrigNS));
+        DeclRegionScope->RemoveDecl(OrigNS);
       }
     } else if (PrevDecl) {
       // This is an invalid name redefinition.
@@ -3212,15 +3338,15 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
       Namespc->setInvalidDecl();
       // Continue on to push Namespc as current DeclContext and return it.
     } else if (II->isStr("std") && 
-               CurContext->getLookupContext()->isTranslationUnit()) {
+               CurContext->getRedeclContext()->isTranslationUnit()) {
       // This is the first "real" definition of the namespace "std", so update
       // our cache of the "std" namespace to point at this definition.
-      if (StdNamespace) {
+      if (NamespaceDecl *StdNS = getStdNamespace()) {
         // We had already defined a dummy namespace "std". Link this new 
         // namespace definition to the dummy namespace "std".
-        StdNamespace->setNextNamespace(Namespc);
-        StdNamespace->setLocation(IdentLoc);
-        Namespc->setOriginalNamespace(StdNamespace->getOriginalNamespace());
+        StdNS->setNextNamespace(Namespc);
+        StdNS->setLocation(IdentLoc);
+        Namespc->setOriginalNamespace(StdNS->getOriginalNamespace());
       }
       
       // Make our StdNamespace cache point at the first real definition of the
@@ -3235,7 +3361,7 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
 
     // Link the anonymous namespace into its parent.
     NamespaceDecl *PrevDecl;
-    DeclContext *Parent = CurContext->getLookupContext();
+    DeclContext *Parent = CurContext->getRedeclContext();
     if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(Parent)) {
       PrevDecl = TU->getAnonymousNamespace();
       TU->setAnonymousNamespace(Namespc);
@@ -3251,6 +3377,16 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
       assert(!PrevDecl->getNextNamespace());
       Namespc->setOriginalNamespace(PrevDecl->getOriginalNamespace());
       PrevDecl->setNextNamespace(Namespc);
+
+      if (Namespc->isInline() != PrevDecl->isInline()) {
+        // inline-ness must match
+        Diag(Namespc->getLocation(), diag::err_inline_namespace_mismatch)
+          << Namespc->isInline();
+        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+        Namespc->setInvalidDecl();
+        // Recover by ignoring the new namespace's inline status.
+        Namespc->setInline(PrevDecl->isInline());
+      }
     }
 
     CurContext->addDecl(Namespc);
@@ -3292,7 +3428,7 @@ Sema::DeclPtrTy Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
   // for the namespace has the declarations that showed up in that particular
   // namespace definition.
   PushDeclContext(NamespcScope, Namespc);
-  return DeclPtrTy::make(Namespc);
+  return Namespc;
 }
 
 /// getNamespaceDecl - Returns the namespace a decl represents. If the decl
@@ -3305,30 +3441,41 @@ static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
 
 /// ActOnFinishNamespaceDef - This callback is called after a namespace is
 /// exited. Decl is the DeclTy returned by ActOnStartNamespaceDef.
-void Sema::ActOnFinishNamespaceDef(DeclPtrTy D, SourceLocation RBrace) {
-  Decl *Dcl = D.getAs<Decl>();
+void Sema::ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace) {
   NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl);
   assert(Namespc && "Invalid parameter, expected NamespaceDecl");
   Namespc->setRBracLoc(RBrace);
   PopDeclContext();
+  if (Namespc->hasAttr<VisibilityAttr>())
+    PopPragmaVisibility();
+}
+
+CXXRecordDecl *Sema::getStdBadAlloc() const {
+  return cast_or_null<CXXRecordDecl>(
+                                  StdBadAlloc.get(Context.getExternalSource()));
+}
+
+NamespaceDecl *Sema::getStdNamespace() const {
+  return cast_or_null<NamespaceDecl>(
+                                 StdNamespace.get(Context.getExternalSource()));
 }
 
 /// \brief Retrieve the special "std" namespace, which may require us to 
 /// implicitly define the namespace.
-NamespaceDecl *Sema::getStdNamespace() {
+NamespaceDecl *Sema::getOrCreateStdNamespace() {
   if (!StdNamespace) {
     // The "std" namespace has not yet been defined, so build one implicitly.
     StdNamespace = NamespaceDecl::Create(Context, 
                                          Context.getTranslationUnitDecl(),
                                          SourceLocation(),
                                          &PP.getIdentifierTable().get("std"));
-    StdNamespace->setImplicit(true);
+    getStdNamespace()->setImplicit(true);
   }
   
-  return StdNamespace;
+  return getStdNamespace();
 }
 
-Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
+Decl *Sema::ActOnUsingDirective(Scope *S,
                                           SourceLocation UsingLoc,
                                           SourceLocation NamespcLoc,
                                           CXXScopeSpec &SS,
@@ -3349,7 +3496,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
   LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
   LookupParsedName(R, S, &SS);
   if (R.isAmbiguous())
-    return DeclPtrTy();
+    return 0;
 
   if (R.empty()) {
     // Allow "using namespace std;" or "using namespace ::std;" even if 
@@ -3357,7 +3504,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
     if ((!Qualifier || Qualifier->getKind() == NestedNameSpecifier::Global) &&
         NamespcName->isStr("std")) {
       Diag(IdentLoc, diag::ext_using_undefined_std);
-      R.addDecl(getStdNamespace());
+      R.addDecl(getOrCreateStdNamespace());
       R.resolveKind();
     } 
     // Otherwise, attempt typo correction.
@@ -3416,7 +3563,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDirective(Scope *S,
 
   // FIXME: We ignore attributes for now.
   delete AttrList;
-  return DeclPtrTy::make(UDir);
+  return UDir;
 }
 
 void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
@@ -3428,11 +3575,11 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
   else
     // Otherwise it is block-sope. using-directives will affect lookup
     // only to the end of scope.
-    S->PushUsingDirective(DeclPtrTy::make(UDir));
+    S->PushUsingDirective(UDir);
 }
 
 
-Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
+Decl *Sema::ActOnUsingDeclaration(Scope *S,
                                             AccessSpecifier AS,
                                             bool HasUsingKeyword,
                                             SourceLocation UsingLoc,
@@ -3457,22 +3604,23 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
 
     Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_constructor)
       << SS.getRange();
-    return DeclPtrTy();
+    return 0;
       
   case UnqualifiedId::IK_DestructorName:
     Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_destructor)
       << SS.getRange();
-    return DeclPtrTy();
+    return 0;
       
   case UnqualifiedId::IK_TemplateId:
     Diag(Name.getSourceRange().getBegin(), diag::err_using_decl_template_id)
       << SourceRange(Name.TemplateId->LAngleLoc, Name.TemplateId->RAngleLoc);
-    return DeclPtrTy();
+    return 0;
   }
-  
-  DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
+
+  DeclarationNameInfo TargetNameInfo = GetNameFromUnqualifiedId(Name);
+  DeclarationName TargetName = TargetNameInfo.getName();
   if (!TargetName)
-    return DeclPtrTy();
+    return 0;
 
   // Warn about using declarations.
   // TODO: store that the declaration was written without 'using' and
@@ -3486,14 +3634,13 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
   }
 
   NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
-                                        Name.getSourceRange().getBegin(),
-                                        TargetName, AttrList,
+                                        TargetNameInfo, AttrList,
                                         /* IsInstantiation */ false,
                                         IsTypeName, TypenameLoc);
   if (UD)
     PushOnScopeChains(UD, S, /*AddToContext*/ false);
 
-  return DeclPtrTy::make(UD);
+  return UD;
 }
 
 /// \brief Determine whether a using declaration considers the given
@@ -3717,7 +3864,7 @@ void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) {
 
   // ...and the scope, if applicable...
   if (S) {
-    S->RemoveDecl(DeclPtrTy::make(static_cast<Decl*>(Shadow)));
+    S->RemoveDecl(Shadow);
     IdResolver.RemoveDecl(Shadow);
   }
 
@@ -3736,13 +3883,13 @@ void Sema::HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow) {
 NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
                                        SourceLocation UsingLoc,
                                        CXXScopeSpec &SS,
-                                       SourceLocation IdentLoc,
-                                       DeclarationName Name,
+                                       const DeclarationNameInfo &NameInfo,
                                        AttributeList *AttrList,
                                        bool IsInstantiation,
                                        bool IsTypeName,
                                        SourceLocation TypenameLoc) {
   assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
+  SourceLocation IdentLoc = NameInfo.getLoc();
   assert(IdentLoc.isValid() && "Invalid TargetName location.");
 
   // FIXME: We ignore attributes for now.
@@ -3754,7 +3901,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
   }
 
   // Do the redeclaration lookup in the current scope.
-  LookupResult Previous(*this, Name, IdentLoc, LookupUsingDeclName,
+  LookupResult Previous(*this, NameInfo, LookupUsingDeclName,
                         ForRedeclaration);
   Previous.setHideTags(false);
   if (S) {
@@ -3793,15 +3940,15 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
       D = UnresolvedUsingTypenameDecl::Create(Context, CurContext,
                                               UsingLoc, TypenameLoc,
                                               SS.getRange(), NNS,
-                                              IdentLoc, Name);
+                                              IdentLoc, NameInfo.getName());
     } else {
       D = UnresolvedUsingValueDecl::Create(Context, CurContext,
-                                           UsingLoc, SS.getRange(), NNS,
-                                           IdentLoc, Name);
+                                           UsingLoc, SS.getRange(),
+                                           NNS, NameInfo);
     }
   } else {
-    D = UsingDecl::Create(Context, CurContext, IdentLoc,
-                          SS.getRange(), UsingLoc, NNS, Name,
+    D = UsingDecl::Create(Context, CurContext,
+                          SS.getRange(), UsingLoc, NNS, NameInfo,
                           IsTypeName);
   }
   D->setAccess(AS);
@@ -3817,7 +3964,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
 
   // Look up the target name.
 
-  LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
 
   // Unlike most lookups, we don't always want to hide tag
   // declarations: tag names are visible through the using declaration
@@ -3830,7 +3977,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
 
   if (R.empty()) {
     Diag(IdentLoc, diag::err_no_member) 
-      << Name << LookupContext << SS.getRange();
+      << NameInfo.getName() << LookupContext << SS.getRange();
     UD->setInvalidDecl();
     return UD;
   }
@@ -3894,7 +4041,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
   //   allowed.
   //
   // That's in non-member contexts.
-  if (!CurContext->getLookupContext()->isRecord())
+  if (!CurContext->getRedeclContext()->isRecord())
     return false;
 
   NestedNameSpecifier *Qual
@@ -4069,7 +4216,7 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc,
   return true;
 }
 
-Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
+Decl *Sema::ActOnNamespaceAliasDef(Scope *S,
                                              SourceLocation NamespaceLoc,
                                              SourceLocation AliasLoc,
                                              IdentifierInfo *Alias,
@@ -4096,18 +4243,18 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
       // declaration to maintain better source information.
       if (!R.isAmbiguous() && !R.empty() &&
           AD->getNamespace()->Equals(getNamespaceDecl(R.getFoundDecl())))
-        return DeclPtrTy();
+        return 0;
     }
 
     unsigned DiagID = isa<NamespaceDecl>(PrevDecl) ? diag::err_redefinition :
       diag::err_redefinition_different_kind;
     Diag(AliasLoc, DiagID) << Alias;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
-    return DeclPtrTy();
+    return 0;
   }
 
   if (R.isAmbiguous())
-    return DeclPtrTy();
+    return 0;
 
   if (R.empty()) {
     if (DeclarationName Corrected = CorrectTypo(R, S, &SS, 0, false, 
@@ -4135,7 +4282,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
     
     if (R.empty()) {
       Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
-      return DeclPtrTy();
+      return 0;
     }
   }
 
@@ -4146,7 +4293,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
                                IdentLoc, R.getFoundDecl());
 
   PushOnScopeChains(AliasDecl, S);
-  return DeclPtrTy::make(AliasDecl);
+  return AliasDecl;
 }
 
 namespace {
@@ -4242,9 +4389,9 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   DeclarationName Name
     = Context.DeclarationNames.getCXXConstructorName(ClassType);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXConstructorDecl *DefaultCon
-    = CXXConstructorDecl::Create(Context, ClassDecl,
-                                 ClassDecl->getLocation(), Name,
+    = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
                                  Context.getFunctionType(Context.VoidTy,
                                                          0, 0, false, 0,
                                        ExceptSpec.hasExceptionSpecification(),
@@ -4348,9 +4495,9 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
     = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
   DeclarationName Name
     = Context.DeclarationNames.getCXXDestructorName(ClassType);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXDestructorDecl *Destructor
-    = CXXDestructorDecl::Create(Context, ClassDecl,
-                                ClassDecl->getLocation(), Name, Ty,
+    = CXXDestructorDecl::Create(Context, ClassDecl, NameInfo, Ty,
                                 /*isInline=*/true,
                                 /*isImplicitlyDeclared=*/true);
   Destructor->setAccess(AS_public);
@@ -4426,13 +4573,10 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
 /// \param Depth Internal parameter recording the depth of the recursion.
 ///
 /// \returns A statement or a loop that copies the expressions.
-static Sema::OwningStmtResult
+static StmtResult
 BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, 
-                      Sema::OwningExprResult To, Sema::OwningExprResult From,
+                      Expr *To, Expr *From,
                       bool CopyingBaseSubobject, unsigned Depth = 0) {
-  typedef Sema::OwningStmtResult OwningStmtResult;
-  typedef Sema::OwningExprResult OwningExprResult;
-  
   // C++0x [class.copy]p30:
   //   Each subobject is assigned in the manner appropriate to its type:
   //
@@ -4489,21 +4633,21 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
                                                T.getTypePtr()));
     
     // Create the reference to operator=.
-    OwningExprResult OpEqualRef
-      = S.BuildMemberReferenceExpr(move(To), T, Loc, /*isArrow=*/false, SS, 
+    ExprResult OpEqualRef
+      = S.BuildMemberReferenceExpr(To, T, Loc, /*isArrow=*/false, SS, 
                                    /*FirstQualifierInScope=*/0, OpLookup, 
                                    /*TemplateArgs=*/0,
                                    /*SuppressQualifierCheck=*/true);
     if (OpEqualRef.isInvalid())
-      return S.StmtError();
+      return StmtError();
     
     // Build the call to the assignment operator.
-    Expr *FromE = From.takeAs<Expr>();
-    OwningExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0, 
+
+    ExprResult Call = S.BuildCallToMemberFunction(/*Scope=*/0, 
                                                       OpEqualRef.takeAs<Expr>(),
-                                                        Loc, &FromE, 1, 0, Loc);
+                                                        Loc, &From, 1, 0, Loc);
     if (Call.isInvalid())
-      return S.StmtError();
+      return StmtError();
     
     return S.Owned(Call.takeAs<Stmt>());
   }
@@ -4512,12 +4656,9 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
   //       operator is used.
   const ConstantArrayType *ArrayTy = S.Context.getAsConstantArrayType(T);  
   if (!ArrayTy) {
-    OwningExprResult Assignment = S.CreateBuiltinBinOp(Loc, 
-                                                       BinaryOperator::Assign,
-                                                       To.takeAs<Expr>(),
-                                                       From.takeAs<Expr>());
+    ExprResult Assignment = S.CreateBuiltinBinOp(Loc, BO_Assign, To, From);
     if (Assignment.isInvalid())
-      return S.StmtError();
+      return StmtError();
     
     return S.Owned(Assignment.takeAs<Stmt>());
   }
@@ -4543,11 +4684,11 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
   VarDecl *IterationVar = VarDecl::Create(S.Context, S.CurContext, Loc,
                                           IterationVarName, SizeType,
                             S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
-                                          VarDecl::None, VarDecl::None);
+                                          SC_None, SC_None);
   
   // Initialize the iteration variable to zero.
   llvm::APInt Zero(S.Context.getTypeSize(SizeType), 0);
-  IterationVar->setInit(new (S.Context) IntegerLiteral(Zero, SizeType, Loc));
+  IterationVar->setInit(IntegerLiteral::Create(S.Context, Zero, SizeType, Loc));
 
   // Create a reference to the iteration variable; we'll use this several
   // times throughout.
@@ -4561,43 +4702,37 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T,
   // Create the comparison against the array bound.
   llvm::APInt Upper = ArrayTy->getSize();
   Upper.zextOrTrunc(S.Context.getTypeSize(SizeType));
-  OwningExprResult Comparison
-    = S.Owned(new (S.Context) BinaryOperator(IterationVarRef->Retain(),
-                           new (S.Context) IntegerLiteral(Upper, SizeType, Loc),
-                                    BinaryOperator::NE, S.Context.BoolTy, Loc));
+  Expr *Comparison
+    = new (S.Context) BinaryOperator(IterationVarRef->Retain(),
+                           IntegerLiteral::Create(S.Context,
+                                                  Upper, SizeType, Loc),
+                                                  BO_NE, S.Context.BoolTy, Loc);
   
   // Create the pre-increment of the iteration variable.
-  OwningExprResult Increment
-    = S.Owned(new (S.Context) UnaryOperator(IterationVarRef->Retain(),
-                                            UnaryOperator::PreInc,
-                                            SizeType, Loc));
+  Expr *Increment
+    = new (S.Context) UnaryOperator(IterationVarRef->Retain(),
+                                    UO_PreInc,
+                                    SizeType, Loc);
   
   // Subscript the "from" and "to" expressions with the iteration variable.
-  From = S.CreateBuiltinArraySubscriptExpr(move(From), Loc,
-                                           S.Owned(IterationVarRef->Retain()),
-                                           Loc);
-  To = S.CreateBuiltinArraySubscriptExpr(move(To), Loc,
-                                         S.Owned(IterationVarRef->Retain()),
-                                         Loc);
-  assert(!From.isInvalid() && "Builtin subscripting can't fail!");
-  assert(!To.isInvalid() && "Builtin subscripting can't fail!");
+  From = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(From, Loc,
+                                                         IterationVarRef, Loc));
+  To = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(To, Loc,
+                                                       IterationVarRef, Loc));
   
   // Build the copy for an individual element of the array.
-  OwningStmtResult Copy = BuildSingleCopyAssign(S, Loc, 
+  StmtResult Copy = BuildSingleCopyAssign(S, Loc, 
                                                 ArrayTy->getElementType(),
-                                                move(To), move(From), 
+                                                To, From, 
                                                 CopyingBaseSubobject, Depth+1);
-  if (Copy.isInvalid()) {
-    InitStmt->Destroy(S.Context);
-    return S.StmtError();
-  }
+  if (Copy.isInvalid())
+    return StmtError();
   
   // Construct the loop that copies all elements of this array.
-  return S.ActOnForStmt(Loc, Loc, S.Owned(InitStmt), 
+  return S.ActOnForStmt(Loc, Loc, InitStmt, 
                         S.MakeFullExpr(Comparison),
-                        Sema::DeclPtrTy(), 
-                        S.MakeFullExpr(Increment),
-                        Loc, move(Copy));
+                        0, S.MakeFullExpr(Increment),
+                        Loc, Copy.take());
 }
 
 /// \brief Determine whether the given class has a copy assignment operator 
@@ -4747,8 +4882,9 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
   //   An implicitly-declared copy assignment operator is an inline public
   //   member of its class.
   DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXMethodDecl *CopyAssignment
-    = CXXMethodDecl::Create(Context, ClassDecl, ClassDecl->getLocation(), Name,
+    = CXXMethodDecl::Create(Context, ClassDecl, NameInfo,
                             Context.getFunctionType(RetType, &ArgType, 1,
                                                     false, 0,
                                          ExceptSpec.hasExceptionSpecification(),
@@ -4757,7 +4893,7 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
                                                     ExceptSpec.data(),
                                                     FunctionType::ExtInfo()),
                             /*TInfo=*/0, /*isStatic=*/false,
-                            /*StorageClassAsWritten=*/FunctionDecl::None,
+                            /*StorageClassAsWritten=*/SC_None,
                             /*isInline=*/true);
   CopyAssignment->setAccess(AS_public);
   CopyAssignment->setImplicit();
@@ -4769,8 +4905,8 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
                                                ClassDecl->getLocation(),
                                                /*Id=*/0,
                                                ArgType, /*TInfo=*/0,
-                                               VarDecl::None,
-                                               VarDecl::None, 0);
+                                               SC_None,
+                                               SC_None, 0);
   CopyAssignment->setParams(&FromParam, 1);
   
   // Note that we have added this copy-assignment operator.
@@ -4814,7 +4950,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
   //   which they were declared in the class definition.
   
   // The statements that form the synthesized function body.
-  ASTOwningVector<&ActionBase::DeleteStmt> Statements(*this);
+  ASTOwningVector<Stmt*> Statements(*this);
   
   // The parameter for the "other" object, which we are copying from.
   ParmVarDecl *Other = CopyAssignOperator->getParamDecl(0);
@@ -4854,30 +4990,32 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
       continue;
     }
 
+    CXXCastPath BasePath;
+    BasePath.push_back(Base);
+
     // Construct the "from" expression, which is an implicit cast to the
     // appropriately-qualified base type.
     Expr *From = OtherRef->Retain();
     ImpCastExprToType(From, Context.getQualifiedType(BaseType, OtherQuals),
-                      CastExpr::CK_UncheckedDerivedToBase, /*isLvalue=*/true, 
-                      CXXBaseSpecifierArray(Base));
+                      CK_UncheckedDerivedToBase,
+                      VK_LValue, &BasePath);
 
     // Dereference "this".
-    OwningExprResult To = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref,
-                                               Owned(This->Retain()));
+    ExprResult To = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
     
     // Implicitly cast "this" to the appropriately-qualified base type.
     Expr *ToE = To.takeAs<Expr>();
     ImpCastExprToType(ToE, 
                       Context.getCVRQualifiedType(BaseType,
                                       CopyAssignOperator->getTypeQualifiers()),
-                      CastExpr::CK_UncheckedDerivedToBase, 
-                      /*isLvalue=*/true, CXXBaseSpecifierArray(Base));
+                      CK_UncheckedDerivedToBase, 
+                      VK_LValue, &BasePath);
     To = Owned(ToE);
 
     // Build the copy.
-    OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,
-                                                  move(To), Owned(From),
-                                                /*CopyingBaseSubobject=*/true);
+    StmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType,
+                                            To.get(), From,
+                                            /*CopyingBaseSubobject=*/true);
     if (Copy.isInvalid()) {
       Diag(CurrentLocation, diag::note_member_synthesized_at) 
         << CXXCopyAssignment << Context.getTagDeclType(ClassDecl);
@@ -4934,12 +5072,10 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
                               LookupMemberName);
     MemberLookup.addDecl(*Field);
     MemberLookup.resolveKind();
-    OwningExprResult From = BuildMemberReferenceExpr(Owned(OtherRef->Retain()),
-                                                     OtherRefType,
+    ExprResult From = BuildMemberReferenceExpr(OtherRef, OtherRefType,
                                                      Loc, /*IsArrow=*/false,
                                                      SS, 0, MemberLookup, 0);
-    OwningExprResult To = BuildMemberReferenceExpr(Owned(This->Retain()),
-                                                   This->getType(),
+    ExprResult To = BuildMemberReferenceExpr(This, This->getType(),
                                                    Loc, /*IsArrow=*/true,
                                                    SS, 0, MemberLookup, 0);
     assert(!From.isInvalid() && "Implicit field reference cannot fail");
@@ -4967,8 +5103,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
       }
           
       // Take the address of the field references for "from" and "to".
-      From = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(From));
-      To = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(To));
+      From = CreateBuiltinUnaryOp(Loc, UO_AddrOf, From.get());
+      To = CreateBuiltinUnaryOp(Loc, UO_AddrOf, To.get());
           
       bool NeedsCollectableMemCpy = 
           (BaseType->isRecordType() && 
@@ -5016,22 +5152,22 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
         assert(BuiltinMemCpyRef && "Builtin reference cannot fail");
       }
           
-      ASTOwningVector<&ActionBase::DeleteExpr> CallArgs(*this);
+      ASTOwningVector<Expr*> CallArgs(*this);
       CallArgs.push_back(To.takeAs<Expr>());
       CallArgs.push_back(From.takeAs<Expr>());
-      CallArgs.push_back(new (Context) IntegerLiteral(Size, SizeType, Loc));
+      CallArgs.push_back(IntegerLiteral::Create(Context, Size, SizeType, Loc));
       llvm::SmallVector<SourceLocation, 4> Commas; // FIXME: Silly
       Commas.push_back(Loc);
       Commas.push_back(Loc);
-      OwningExprResult Call = ExprError();
+      ExprResult Call = ExprError();
       if (NeedsCollectableMemCpy)
         Call = ActOnCallExpr(/*Scope=*/0,
-                             Owned(CollectableMemCpyRef->Retain()),
+                             CollectableMemCpyRef,
                              Loc, move_arg(CallArgs), 
                              Commas.data(), Loc);
       else
         Call = ActOnCallExpr(/*Scope=*/0,
-                             Owned(BuiltinMemCpyRef->Retain()),
+                             BuiltinMemCpyRef,
                              Loc, move_arg(CallArgs), 
                              Commas.data(), Loc);
           
@@ -5041,8 +5177,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
     }
     
     // Build the copy of this field.
-    OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType, 
-                                                  move(To), move(From),
+    StmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType, 
+                                                  To.get(), From.get(),
                                               /*CopyingBaseSubobject=*/false);
     if (Copy.isInvalid()) {
       Diag(CurrentLocation, diag::note_member_synthesized_at) 
@@ -5057,10 +5193,9 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
 
   if (!Invalid) {
     // Add a "return *this;"
-    OwningExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UnaryOperator::Deref,
-                                                    Owned(This->Retain()));
+    ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This);
     
-    OwningStmtResult Return = ActOnReturnStmt(Loc, move(ThisObj));
+    StmtResult Return = ActOnReturnStmt(Loc, ThisObj.get());
     if (Return.isInvalid())
       Invalid = true;
     else {
@@ -5079,7 +5214,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
     return;
   }
   
-  OwningStmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
+  StmtResult Body = ActOnCompoundStmt(Loc, Loc, move_arg(Statements),
                                             /*isStmtExpr=*/false);
   assert(!Body.isInvalid() && "Compound statement creation cannot fail");
   CopyAssignOperator->setBody(Body.takeAs<Stmt>());
@@ -5220,9 +5355,9 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
   DeclarationName Name
     = Context.DeclarationNames.getCXXConstructorName(
                                            Context.getCanonicalType(ClassType));
+  DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
   CXXConstructorDecl *CopyConstructor
-    = CXXConstructorDecl::Create(Context, ClassDecl,
-                                 ClassDecl->getLocation(), Name,
+    = CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
                                  Context.getFunctionType(Context.VoidTy,
                                                          &ArgType, 1,
                                                          false, 0,
@@ -5248,8 +5383,8 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
                                                ClassDecl->getLocation(),
                                                /*IdentifierInfo=*/0,
                                                ArgType, /*TInfo=*/0,
-                                               VarDecl::None,
-                                               VarDecl::None, 0);
+                                               SC_None,
+                                               SC_None, 0);
   CopyConstructor->setParams(&FromParam, 1);
   if (Scope *S = getScopeForContext(ClassDecl))
     PushOnScopeChains(CopyConstructor, S, false);
@@ -5288,12 +5423,12 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
   CopyConstructor->setUsed();
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                             CXXConstructorDecl *Constructor,
                             MultiExprArg ExprArgs,
                             bool RequiresZeroInit,
-                            CXXConstructExpr::ConstructionKind ConstructKind) {
+                            unsigned ConstructKind) {
   bool Elidable = false;
 
   // C++0x [class.copy]p34:
@@ -5309,6 +5444,7 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
   if (Constructor->isCopyConstructor() && ExprArgs.size() >= 1) {
     Expr *SubExpr = ((Expr **)ExprArgs.get())[0];
     Elidable = SubExpr->isTemporaryObject() &&
+      ConstructKind == CXXConstructExpr::CK_Complete &&
       Context.hasSameUnqualifiedType(SubExpr->getType(), 
                            Context.getTypeDeclType(Constructor->getParent()));
   }
@@ -5320,27 +5456,28 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
 
 /// BuildCXXConstructExpr - Creates a complete call to a constructor,
 /// including handling of its default argument expressions.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
                             CXXConstructorDecl *Constructor, bool Elidable,
                             MultiExprArg ExprArgs,
                             bool RequiresZeroInit,
-                            CXXConstructExpr::ConstructionKind ConstructKind) {
+                            unsigned ConstructKind) {
   unsigned NumExprs = ExprArgs.size();
   Expr **Exprs = (Expr **)ExprArgs.release();
 
   MarkDeclarationReferenced(ConstructLoc, Constructor);
   return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
                                         Constructor, Elidable, Exprs, NumExprs, 
-                                        RequiresZeroInit, ConstructKind));
+                                        RequiresZeroInit,
+              static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind)));
 }
 
 bool Sema::InitializeVarWithConstructor(VarDecl *VD,
                                         CXXConstructorDecl *Constructor,
                                         MultiExprArg Exprs) {
-  OwningExprResult TempResult =
+  ExprResult TempResult =
     BuildCXXConstructExpr(VD->getLocation(), VD->getType(), Constructor,
-                          move(Exprs));
+                          move(Exprs), false, CXXConstructExpr::CK_Complete);
   if (TempResult.isInvalid())
     return true;
 
@@ -5362,19 +5499,21 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
                           PDiag(diag::err_access_dtor_var)
                             << VD->getDeclName()
                             << VD->getType());
+
+    if (!VD->isInvalidDecl() && VD->hasGlobalStorage())
+      Diag(VD->getLocation(), diag::warn_global_destructor);
   }
 }
 
 /// AddCXXDirectInitializerToDecl - This action is called immediately after
 /// ActOnDeclarator, when a C++ direct initializer is present.
 /// e.g: "int x(1);"
-void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
+void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
                                          SourceLocation LParenLoc,
                                          MultiExprArg Exprs,
                                          SourceLocation *CommaLocs,
                                          SourceLocation RParenLoc) {
   assert(Exprs.size() != 0 && Exprs.get() && "missing expressions");
-  Decl *RealDecl = Dcl.getAs<Decl>();
 
   // If there is no declaration, there was an error parsing it.  Just ignore
   // the initializer.
@@ -5402,9 +5541,6 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
   // The form of initialization (using parentheses or '=') is generally
   // insignificant, but does matter when the entity being initialized has a
   // class type.
-  QualType DeclInitType = VDecl->getType();
-  if (const ArrayType *Array = Context.getAsArrayType(DeclInitType))
-    DeclInitType = Context.getBaseElementType(Array);
 
   if (!VDecl->getType()->isDependentType() &&
       RequireCompleteType(VDecl->getLocation(), VDecl->getType(),
@@ -5428,6 +5564,25 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
     return;
   }
 
+  // C++ [class.static.data]p4
+  //   If a static data member is of const integral or const
+  //   enumeration type, its declaration in the class definition can
+  //   specify a constant-initializer which shall be an integral
+  //   constant expression (5.19). In that case, the member can appear
+  //   in integral constant expressions. The member shall still be
+  //   defined in a namespace scope if it is used in the program and the
+  //   namespace scope definition shall not contain an initializer.
+  //
+  // We already performed a redefinition check above, but for static
+  // data members we also need to check whether there was an in-class
+  // declaration with an initializer.
+  const VarDecl* PrevInit = 0;
+  if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) {
+    Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName();
+    Diag(PrevInit->getLocation(), diag::note_previous_definition);
+    return;
+  } 
+
   // If either the declaration has a dependent type or if any of the
   // expressions is type-dependent, we represent the initialization
   // via a ParenListExpr for later use during template instantiation.
@@ -5454,17 +5609,25 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
                                        LParenLoc, RParenLoc);
   
   InitializationSequence InitSeq(*this, Entity, Kind, 
-                                 (Expr**)Exprs.get(), Exprs.size());
-  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
+                                 Exprs.get(), Exprs.size());
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs));
   if (Result.isInvalid()) {
     VDecl->setInvalidDecl();
     return;
   }
   
-  Result = MaybeCreateCXXExprWithTemporaries(move(Result));
+  Result = MaybeCreateCXXExprWithTemporaries(Result.get());
   VDecl->setInit(Result.takeAs<Expr>());
   VDecl->setCXXDirectInitializer(true);
 
+    if (!VDecl->isInvalidDecl() &&
+        !VDecl->getDeclContext()->isDependentContext() &&
+        VDecl->hasGlobalStorage() &&
+        !VDecl->getInit()->isConstantInitializer(Context,
+                                        VDecl->getType()->isReferenceType()))
+      Diag(VDecl->getLocation(), diag::warn_global_constructor)
+        << VDecl->getInit()->getSourceRange();
+
   if (const RecordType *Record = VDecl->getType()->getAs<RecordType>())
     FinalizeVarWithDestructor(VDecl, Record);
 }
@@ -5478,7 +5641,7 @@ bool
 Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
                               MultiExprArg ArgsPtr,
                               SourceLocation Loc,                                    
-                     ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs) {
+                              ASTOwningVector<Expr*> &ConvertedArgs) {
   // FIXME: This duplicates a lot of code from Sema::ConvertArgumentsForCall.
   unsigned NumArgs = ArgsPtr.size();
   Expr **Args = (Expr **)ArgsPtr.get();
@@ -5508,7 +5671,7 @@ Sema::CompleteConstructorCall(CXXConstructorDecl *Constructor,
 static inline bool
 CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef, 
                                        const FunctionDecl *FnDecl) {
-  const DeclContext *DC = FnDecl->getDeclContext()->getLookupContext();
+  const DeclContext *DC = FnDecl->getDeclContext()->getRedeclContext();
   if (isa<NamespaceDecl>(DC)) {
     return SemaRef.Diag(FnDecl->getLocation(), 
                         diag::err_operator_new_delete_declared_in_namespace)
@@ -5516,7 +5679,7 @@ CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef,
   }
   
   if (isa<TranslationUnitDecl>(DC) && 
-      FnDecl->getStorageClass() == FunctionDecl::Static) {
+      FnDecl->getStorageClass() == SC_Static) {
     return SemaRef.Diag(FnDecl->getLocation(),
                         diag::err_operator_new_delete_declared_static)
       << FnDecl->getDeclName();
@@ -5622,18 +5785,6 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, const FunctionDecl *FnDecl) {
                                  diag::err_operator_delete_param_type))
     return true;
 
-  QualType FirstParamType = FnDecl->getParamDecl(0)->getType();
-  if (FirstParamType->isDependentType())
-    return SemaRef.Diag(FnDecl->getLocation(),
-                        diag::err_operator_delete_dependent_param_type)
-    << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
-
-  if (SemaRef.Context.getCanonicalType(FirstParamType) != 
-      SemaRef.Context.VoidPtrTy)
-    return SemaRef.Diag(FnDecl->getLocation(),
-                        diag::err_operator_delete_param_type)
-      << FnDecl->getDeclName() << SemaRef.Context.VoidPtrTy;
-  
   return false;
 }
 
@@ -5891,7 +6042,7 @@ FinishedParams:
 /// by Lang/StrSize. LBraceLoc, if valid, provides the location of
 /// the '{' brace. Otherwise, this linkage specification does not
 /// have any braces.
-Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
+Decl *Sema::ActOnStartLinkageSpecification(Scope *S,
                                                      SourceLocation ExternLoc,
                                                      SourceLocation LangLoc,
                                                      llvm::StringRef Lang,
@@ -5903,7 +6054,7 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
     Language = LinkageSpecDecl::lang_cxx;
   else {
     Diag(LangLoc, diag::err_bad_language);
-    return DeclPtrTy();
+    return 0;
   }
 
   // FIXME: Add all the various semantics of linkage specifications
@@ -5913,15 +6064,15 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
                                                LBraceLoc.isValid());
   CurContext->addDecl(D);
   PushDeclContext(S, D);
-  return DeclPtrTy::make(D);
+  return D;
 }
 
-/// ActOnFinishLinkageSpecification - Completely the definition of
+/// ActOnFinishLinkageSpecification - Complete the definition of
 /// the C++ linkage specification LinkageSpec. If RBraceLoc is
 /// valid, it's the position of the closing '}' brace in a linkage
 /// specification that uses braces.
-Sema::DeclPtrTy Sema::ActOnFinishLinkageSpecification(Scope *S,
-                                                      DeclPtrTy LinkageSpec,
+Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
+                                                      Decl *LinkageSpec,
                                                       SourceLocation RBraceLoc) {
   if (LinkageSpec)
     PopDeclContext();
@@ -5983,9 +6134,30 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
                              AbstractVariableType))
     Invalid = true;
 
+  // Only the non-fragile NeXT runtime currently supports C++ catches
+  // of ObjC types, and no runtime supports catching ObjC types by value.
+  if (!Invalid && getLangOptions().ObjC1) {
+    QualType T = ExDeclType;
+    if (const ReferenceType *RT = T->getAs<ReferenceType>())
+      T = RT->getPointeeType();
+
+    if (T->isObjCObjectType()) {
+      Diag(Loc, diag::err_objc_object_catch);
+      Invalid = true;
+    } else if (T->isObjCObjectPointerType()) {
+      if (!getLangOptions().NeXTRuntime) {
+        Diag(Loc, diag::err_objc_pointer_cxx_catch_gnu);
+        Invalid = true;
+      } else if (!getLangOptions().ObjCNonFragileABI) {
+        Diag(Loc, diag::err_objc_pointer_cxx_catch_fragile);
+        Invalid = true;
+      }
+    }
+  }
+
   VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
-                                    Name, ExDeclType, TInfo, VarDecl::None,
-                                    VarDecl::None);
+                                    Name, ExDeclType, TInfo, SC_None,
+                                    SC_None);
   ExDecl->setExceptionVariable(true);
   
   if (!Invalid) {
@@ -6005,8 +6177,8 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
       InitializationKind Kind = InitializationKind::CreateCopy(Loc, 
                                                                SourceLocation());
       InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1);
-      OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, 
-                                    MultiExprArg(*this, (void**)&ExDeclRef, 1));
+      ExprResult Result = InitSeq.Perform(*this, Entity, Kind, 
+                                         MultiExprArg(*this, &ExDeclRef, 1));
       if (Result.isInvalid())
         Invalid = true;
       else 
@@ -6022,7 +6194,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
 
 /// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch
 /// handler.
-Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
+Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType ExDeclType = TInfo->getType();
 
@@ -6033,7 +6205,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
                                              ForRedeclaration)) {
     // The scope should be freshly made just for us. There is just no way
     // it contains any previous declaration.
-    assert(!S->isDeclScope(DeclPtrTy::make(PrevDecl)));
+    assert(!S->isDeclScope(PrevDecl));
     if (PrevDecl->isTemplateParameter()) {
       // Maybe we will complain about the shadowed template parameter.
       DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
@@ -6061,22 +6233,20 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
     CurContext->addDecl(ExDecl);
 
   ProcessDeclAttributes(S, ExDecl, D);
-  return DeclPtrTy::make(ExDecl);
+  return ExDecl;
 }
 
-Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
-                                                   ExprArg assertexpr,
-                                                   ExprArg assertmessageexpr) {
-  Expr *AssertExpr = (Expr *)assertexpr.get();
-  StringLiteral *AssertMessage =
-    cast<StringLiteral>((Expr *)assertmessageexpr.get());
+Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
+                                         Expr *AssertExpr,
+                                         Expr *AssertMessageExpr_) {
+  StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr_);
 
   if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent()) {
     llvm::APSInt Value(32);
     if (!AssertExpr->isIntegerConstantExpr(Value, Context)) {
       Diag(AssertLoc, diag::err_static_assert_expression_is_not_constant) <<
         AssertExpr->getSourceRange();
-      return DeclPtrTy();
+      return 0;
     }
 
     if (Value == 0) {
@@ -6085,13 +6255,11 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
     }
   }
 
-  assertexpr.release();
-  assertmessageexpr.release();
   Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc,
                                         AssertExpr, AssertMessage);
 
   CurContext->addDecl(Decl);
-  return DeclPtrTy::make(Decl);
+  return Decl;
 }
 
 /// \brief Perform semantic analysis of the given friend type declaration.
@@ -6167,7 +6335,7 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation FriendLoc,
 /// We permit this as a special case; if there are any template
 /// parameters present at all, require proper matching, i.e.
 ///   template <> template <class T> friend class A<int>::B;
-Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
+Decl *Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
                                           MultiTemplateParamsArg TempParams) {
   SourceLocation Loc = DS.getSourceRange().getBegin();
 
@@ -6181,7 +6349,7 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
   TypeSourceInfo *TSI = GetTypeForDeclarator(TheDeclarator, S);
   QualType T = TSI->getType();
   if (TheDeclarator.isInvalidType())
-    return DeclPtrTy();
+    return 0;
 
   // This is definitely an error in C++98.  It's probably meant to
   // be forbidden in C++0x, too, but the specification is just
@@ -6200,7 +6368,7 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
   if (TempParams.size() && !T->isElaboratedTypeSpecifier()) {
     Diag(Loc, diag::err_tagless_friend_type_template)
       << DS.getSourceRange();
-    return DeclPtrTy();
+    return 0;
   }
   
   // C++98 [class.friend]p1: A friend of a class is a function
@@ -6225,18 +6393,17 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS,
     D = CheckFriendTypeDecl(DS.getFriendSpecLoc(), TSI);
   
   if (!D)
-    return DeclPtrTy();
+    return 0;
   
   D->setAccess(AS_public);
   CurContext->addDecl(D);
 
-  return DeclPtrTy::make(D);
+  return D;
 }
 
-Sema::DeclPtrTy
-Sema::ActOnFriendFunctionDecl(Scope *S,
-                              Declarator &D,
-                              bool IsDefinition,
+Decl *Sema::ActOnFriendFunctionDecl(Scope *S,
+                                         Declarator &D,
+                                         bool IsDefinition,
                               MultiTemplateParamsArg TemplateParams) {
   const DeclSpec &DS = D.getDeclSpec();
 
@@ -6262,7 +6429,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
 
     // It might be worthwhile to try to recover by creating an
     // appropriate declaration.
-    return DeclPtrTy();
+    return 0;
   }
 
   // C++ [namespace.memdef]p3
@@ -6281,7 +6448,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
   //    namespace scope are not considered.
 
   CXXScopeSpec &ScopeQual = D.getCXXScopeSpec();
-  DeclarationName Name = GetNameForDeclarator(D);
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   assert(Name);
 
   // The context we found the declaration in, or in which we should
@@ -6291,14 +6459,14 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
   // FIXME: handle local classes
 
   // Recover from invalid scope qualifiers as if they just weren't there.
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName,
                         ForRedeclaration);
   if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
     DC = computeDeclContext(ScopeQual);
 
     // FIXME: handle dependent contexts
-    if (!DC) return DeclPtrTy();
-    if (RequireCompleteDeclContext(ScopeQual, DC)) return DeclPtrTy();
+    if (!DC) return 0;
+    if (RequireCompleteDeclContext(ScopeQual, DC)) return 0;
 
     LookupQualifiedName(Previous, DC);
 
@@ -6308,7 +6476,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
     LookupResult::Filter F = Previous.makeFilter();
     while (F.hasNext()) {
       NamedDecl *D = F.next();
-      if (!D->getDeclContext()->getLookupContext()->Equals(DC))
+      if (!DC->InEnclosingNamespaceSetOf(
+              D->getDeclContext()->getRedeclContext()))
         F.erase();
     }
     F.done();
@@ -6316,7 +6485,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
     if (Previous.empty()) {
       D.setInvalidType();
       Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
-      return DeclPtrTy();
+      return 0;
     }
 
     // C++ [class.friend]p1: A friend of a class is a function or
@@ -6368,7 +6537,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
       Diag(Loc, diag::err_introducing_special_friend) <<
         (D.getName().getKind() == UnqualifiedId::IK_ConstructorName ? 0 :
          D.getName().getKind() == UnqualifiedId::IK_DestructorName ? 1 : 2);
-      return DeclPtrTy();
+      return 0;
     }
   }
 
@@ -6377,7 +6546,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
                                           move(TemplateParams),
                                           IsDefinition,
                                           Redeclaration);
-  if (!ND) return DeclPtrTy();
+  if (!ND) return 0;
 
   assert(ND->getDeclContext() == DC);
   assert(ND->getLexicalDeclContext() == CurContext);
@@ -6389,7 +6558,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
   // Also update the scope-based lookup if the target context's
   // lookup context is in lexical scope.
   if (!CurContext->isDependentContext()) {
-    DC = DC->getLookupContext();
+    DC = DC->getRedeclContext();
     DC->makeDeclVisibleInContext(ND, /* Recoverable=*/ false);
     if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
       PushOnScopeChains(ND, EnclosingScope, /*AddToContext=*/ false);
@@ -6401,13 +6570,12 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
   FrD->setAccess(AS_public);
   CurContext->addDecl(FrD);
 
-  return DeclPtrTy::make(ND);
+  return ND;
 }
 
-void Sema::SetDeclDeleted(DeclPtrTy dcl, SourceLocation DelLoc) {
-  AdjustDeclIfTemplate(dcl);
+void Sema::SetDeclDeleted(Decl *Dcl, SourceLocation DelLoc) {
+  AdjustDeclIfTemplate(Dcl);
 
-  Decl *Dcl = dcl.getAs<Decl>();
   FunctionDecl *Fn = dyn_cast<FunctionDecl>(Dcl);
   if (!Fn) {
     Diag(DelLoc, diag::err_deleted_non_function);
@@ -6575,9 +6743,8 @@ bool Sema::CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange) {
 /// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
 /// static data member of class X, names should be looked up in the scope of
 /// class X.
-void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
   // If there is no declaration, there was an error parsing it.
-  Decl *D = Dcl.getAs<Decl>();
   if (D == 0) return;
 
   // We should only get called for declarations with scope specifiers, like:
@@ -6587,10 +6754,9 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, DeclPtrTy Dcl) {
 }
 
 /// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
-/// initializer for the out-of-line declaration 'Dcl'.
-void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
+/// initializer for the out-of-line declaration 'D'.
+void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
   // If there is no declaration, there was an error parsing it.
-  Decl *D = Dcl.getAs<Decl>();
   if (D == 0) return;
 
   assert(D->isOutOfLine());
@@ -6600,8 +6766,7 @@ void Sema::ActOnCXXExitDeclInitializer(Scope *S, DeclPtrTy Dcl) {
 /// ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a
 /// C++ if/switch/while/for statement.
 /// e.g: "if (int x = f()) {...}"
-Action::DeclResult
-Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
+DeclResult Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
   // C++ 6.4p2:
   // The declarator shall not specify a function or an array.
   // The type-specifier-seq shall not contain typedef and shall not declare a
@@ -6624,12 +6789,10 @@ Sema::ActOnCXXConditionDeclaration(Scope *S, Declarator &D) {
     Diag(OwnedTag->getLocation(), diag::err_type_defined_in_condition);
   }
   
-  DeclPtrTy Dcl = ActOnDeclarator(S, D);
+  Decl *Dcl = ActOnDeclarator(S, D);
   if (!Dcl)
     return DeclResult();
 
-  VarDecl *VD = cast<VarDecl>(Dcl.getAs<Decl>());
-  VD->setDeclaredInCondition(true);
   return Dcl;
 }
 
@@ -6775,8 +6938,6 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
            e = RD->bases_end(); i != e; ++i) {
     const CXXRecordDecl *Base =
         cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
-    if (i->isVirtual())
-      continue;
     if (Base->getNumVBases() == 0)
       continue;
     MarkVirtualMembersReferenced(Loc, Base);
@@ -6788,7 +6949,7 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
 void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
   if (!getLangOptions().CPlusPlus)
     return;
-  if (const ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
+  if (ObjCInterfaceDecl *OID = ObjCImplementation->getClassInterface()) {
     llvm::SmallVector<ObjCIvarDecl*, 8> ivars;
     CollectIvarsToConstructOrDestruct(OID, ivars);
     if (ivars.empty())
@@ -6805,10 +6966,9 @@ void Sema::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
         InitializationKind::CreateDefault(ObjCImplementation->getLocation());
       
       InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0);
-      Sema::OwningExprResult MemberInit = 
-        InitSeq.Perform(*this, InitEntity, InitKind, 
-                        Sema::MultiExprArg(*this, 0, 0));
-      MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit));
+      ExprResult MemberInit = 
+        InitSeq.Perform(*this, InitEntity, InitKind, MultiExprArg());
+      MemberInit = MaybeCreateCXXExprWithTemporaries(MemberInit.get());
       // Note, MemberInit could actually come back empty if no initialization 
       // is required (e.g., because it would call a trivial default constructor)
       if (!MemberInit.get() || MemberInit.isInvalid())
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 21aeb59..a6902a3 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -11,20 +11,24 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/Sema/ExternalSemaSource.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Sema/DeclSpec.h"
+#include "llvm/ADT/DenseSet.h"
+
 using namespace clang;
 
 /// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
 /// and user declared, in the method definition's AST.
-void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
+void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
   assert(getCurMethodDecl() == 0 && "Method parsing confused");
-  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
+  ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
 
   // If we don't have a valid method decl, simply return.
   if (!MDecl)
@@ -32,10 +36,10 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
 
   // Allow the rest of sema to find private method decl implementations.
   if (MDecl->isInstanceMethod())
-    AddInstanceMethodToGlobalPool(MDecl);
+    AddInstanceMethodToGlobalPool(MDecl, true);
   else
-    AddFactoryMethodToGlobalPool(MDecl);
-
+    AddFactoryMethodToGlobalPool(MDecl, true);
+  
   // Allow all of Sema to see that we are entering a method definition.
   PushDeclContext(FnBodyScope, MDecl);
   PushFunctionScope();
@@ -56,11 +60,11 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
       PushOnScopeChains(*PI, FnBodyScope);
 }
 
-Sema::DeclPtrTy Sema::
+Decl *Sema::
 ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
                          IdentifierInfo *ClassName, SourceLocation ClassLoc,
                          IdentifierInfo *SuperName, SourceLocation SuperLoc,
-                         const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
+                         Decl * const *ProtoRefs, unsigned NumProtoRefs,
                          const SourceLocation *ProtoLocs, 
                          SourceLocation EndProtoLoc, AttributeList *AttrList) {
   assert(ClassName && "Missing class identifier");
@@ -84,11 +88,14 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
 
       // Return the previous class interface.
       // FIXME: don't leak the objects passed in!
-      return DeclPtrTy::make(IDecl);
+      return IDecl;
     } else {
       IDecl->setLocation(AtInterfaceLoc);
       IDecl->setForwardDecl(false);
       IDecl->setClassLoc(ClassLoc);
+      // If the forward decl was in a PCH, we need to write it again in a
+      // dependent AST file.
+      IDecl->setChangedSinceDeserialization(true);
       
       // Since this ObjCInterfaceDecl was created by a forward declaration,
       // we now add it to the DeclContext since it wasn't added before
@@ -176,7 +183,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
     IDecl->setLocEnd(ClassLoc);
   }
 
-  /// Check then save referenced protocols.
+  // Check then save referenced protocols.
   if (NumProtoRefs) {
     IDecl->setProtocolList((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs,
                            ProtoLocs, Context);
@@ -184,16 +191,16 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
   }
 
   CheckObjCDeclScope(IDecl);
-  return DeclPtrTy::make(IDecl);
+  return IDecl;
 }
 
 /// ActOnCompatiblityAlias - this action is called after complete parsing of
 /// @compatibility_alias declaration. It sets up the alias relationships.
-Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
-                                             IdentifierInfo *AliasName,
-                                             SourceLocation AliasLocation,
-                                             IdentifierInfo *ClassName,
-                                             SourceLocation ClassLocation) {
+Decl *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
+                                        IdentifierInfo *AliasName,
+                                        SourceLocation AliasLocation,
+                                        IdentifierInfo *ClassName,
+                                        SourceLocation ClassLocation) {
   // Look for previous declaration of alias name
   NamedDecl *ADecl = LookupSingleName(TUScope, AliasName, AliasLocation,
                                       LookupOrdinaryName, ForRedeclaration);
@@ -203,7 +210,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
     else
       Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
     Diag(ADecl->getLocation(), diag::note_previous_declaration);
-    return DeclPtrTy();
+    return 0;
   }
   // Check for class declaration
   NamedDecl *CDeclU = LookupSingleName(TUScope, ClassName, ClassLocation,
@@ -223,7 +230,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
     Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
     if (CDeclU)
       Diag(CDeclU->getLocation(), diag::note_previous_declaration);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Everything checked out, instantiate a new alias declaration AST.
@@ -233,7 +240,7 @@ Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
   if (!CheckObjCDeclScope(AliasDecl))
     PushOnScopeChains(AliasDecl, TUScope);
 
-  return DeclPtrTy::make(AliasDecl);
+  return AliasDecl;
 }
 
 void Sema::CheckForwardProtocolDeclarationForCircularDependency(
@@ -255,11 +262,11 @@ void Sema::CheckForwardProtocolDeclarationForCircularDependency(
   }
 }
 
-Sema::DeclPtrTy
+Decl *
 Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
                                   IdentifierInfo *ProtocolName,
                                   SourceLocation ProtocolLoc,
-                                  const DeclPtrTy *ProtoRefs,
+                                  Decl * const *ProtoRefs,
                                   unsigned NumProtoRefs,
                                   const SourceLocation *ProtoLocs,
                                   SourceLocation EndProtoLoc,
@@ -274,17 +281,19 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
       Diag(PDecl->getLocation(), diag::note_previous_definition);
       // Just return the protocol we already had.
       // FIXME: don't leak the objects passed in!
-      return DeclPtrTy::make(PDecl);
+      return PDecl;
     }
     ObjCList<ObjCProtocolDecl> PList;
     PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
     CheckForwardProtocolDeclarationForCircularDependency(
       ProtocolName, ProtocolLoc, PDecl->getLocation(), PList);
-    PList.Destroy(Context);
 
     // Make sure the cached decl gets a valid start location.
     PDecl->setLocation(AtProtoInterfaceLoc);
     PDecl->setForwardDecl(false);
+    CurContext->addDecl(PDecl);
+    // Repeat in dependent AST files.
+    PDecl->setChangedSinceDeserialization(true);
   } else {
     PDecl = ObjCProtocolDecl::Create(Context, CurContext,
                                      AtProtoInterfaceLoc,ProtocolName);
@@ -301,7 +310,7 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
   }
 
   CheckObjCDeclScope(PDecl);
-  return DeclPtrTy::make(PDecl);
+  return PDecl;
 }
 
 /// FindProtocolDeclaration - This routine looks up protocols and
@@ -311,7 +320,7 @@ void
 Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
                               const IdentifierLocPair *ProtocolId,
                               unsigned NumProtocols,
-                              llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
+                              llvm::SmallVectorImpl<Decl *> &Protocols) {
   for (unsigned i = 0; i != NumProtocols; ++i) {
     ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
                                              ProtocolId[i].second);
@@ -340,7 +349,7 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
     if (WarnOnDeclarations && PDecl->isForwardDecl())
       Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
         << ProtocolId[i].first;
-    Protocols.push_back(DeclPtrTy::make(PDecl));
+    Protocols.push_back(PDecl);
   }
 }
 
@@ -374,7 +383,7 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
 }
 
 /// ActOnForwardProtocolDeclaration - Handle @protocol foo;
-Action::DeclPtrTy
+Decl *
 Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
                                       const IdentifierLocPair *IdentList,
                                       unsigned NumElts,
@@ -385,13 +394,18 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
   for (unsigned i = 0; i != NumElts; ++i) {
     IdentifierInfo *Ident = IdentList[i].first;
     ObjCProtocolDecl *PDecl = LookupProtocol(Ident, IdentList[i].second);
+    bool isNew = false;
     if (PDecl == 0) { // Not already seen?
       PDecl = ObjCProtocolDecl::Create(Context, CurContext,
                                        IdentList[i].second, Ident);
-      PushOnScopeChains(PDecl, TUScope);
+      PushOnScopeChains(PDecl, TUScope, false);
+      isNew = true;
     }
-    if (attrList)
+    if (attrList) {
       ProcessDeclAttributeList(TUScope, PDecl, attrList);
+      if (!isNew)
+        PDecl->setChangedSinceDeserialization(true);
+    }
     Protocols.push_back(PDecl);
     ProtoLocs.push_back(IdentList[i].second);
   }
@@ -402,15 +416,15 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
                                     ProtoLocs.data());
   CurContext->addDecl(PDecl);
   CheckObjCDeclScope(PDecl);
-  return DeclPtrTy::make(PDecl);
+  return PDecl;
 }
 
-Sema::DeclPtrTy Sema::
+Decl *Sema::
 ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
                             IdentifierInfo *ClassName, SourceLocation ClassLoc,
                             IdentifierInfo *CategoryName,
                             SourceLocation CategoryLoc,
-                            const DeclPtrTy *ProtoRefs,
+                            Decl * const *ProtoRefs,
                             unsigned NumProtoRefs,
                             const SourceLocation *ProtoLocs,
                             SourceLocation EndProtoLoc) {
@@ -426,7 +440,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
                                      ClassLoc, CategoryLoc, CategoryName);
     CDecl->setInvalidDecl();
     Diag(ClassLoc, diag::err_undef_interface) << ClassName;
-    return DeclPtrTy::make(CDecl);
+    return CDecl;
   }
 
   if (!CategoryName && IDecl->getImplementation()) {
@@ -471,18 +485,17 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
     // Protocols in the class extension belong to the class.
     if (CDecl->IsClassExtension())
      IDecl->mergeClassExtensionProtocolList((ObjCProtocolDecl**)ProtoRefs, 
-                                            NumProtoRefs, ProtoLocs,
-                                            Context); 
+                                            NumProtoRefs, Context); 
   }
 
   CheckObjCDeclScope(CDecl);
-  return DeclPtrTy::make(CDecl);
+  return CDecl;
 }
 
 /// ActOnStartCategoryImplementation - Perform semantic checks on the
 /// category implementation declaration and build an ObjCCategoryImplDecl
 /// object.
-Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
+Decl *Sema::ActOnStartCategoryImplementation(
                       SourceLocation AtCatImplLoc,
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *CatName, SourceLocation CatLoc) {
@@ -523,10 +536,10 @@ Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
   }
 
   CheckObjCDeclScope(CDecl);
-  return DeclPtrTy::make(CDecl);
+  return CDecl;
 }
 
-Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
+Decl *Sema::ActOnStartClassImplementation(
                       SourceLocation AtClassImplLoc,
                       IdentifierInfo *ClassName, SourceLocation ClassLoc,
                       IdentifierInfo *SuperClassname,
@@ -617,7 +630,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
                                    IDecl, SDecl);
 
   if (CheckObjCDeclScope(IMPDecl))
-    return DeclPtrTy::make(IMPDecl);
+    return IMPDecl;
 
   // Check that there is no duplicate implementation of this class.
   if (IDecl->getImplementation()) {
@@ -629,7 +642,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
     IDecl->setImplementation(IMPDecl);
     PushOnScopeChains(IMPDecl, TUScope);
   }
-  return DeclPtrTy::make(IMPDecl);
+  return IMPDecl;
 }
 
 void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -910,8 +923,9 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
   }
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
     // Check for any implementation of a methods declared in protocol.
-    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
-         E = I->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          PI = I->all_referenced_protocol_begin(),
+          E = I->all_referenced_protocol_end(); PI != E; ++PI)
       MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
                                  IMPDecl,
                                  (*PI), IncompleteImpl, false);
@@ -957,8 +971,9 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
   // implemented in the implementation class.
 
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
-    for (ObjCInterfaceDecl::protocol_iterator PI = I->protocol_begin(),
-         E = I->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          PI = I->all_referenced_protocol_begin(),
+          E = I->all_referenced_protocol_end(); PI != E; ++PI)
       CheckProtocolMethodDefs(IMPDecl->getLocation(), *PI, IncompleteImpl,
                               InsMap, ClsMap, I);
     // Check class extensions (unnamed categories)
@@ -992,7 +1007,7 @@ void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
 }
 
 /// ActOnForwardClassDeclaration -
-Action::DeclPtrTy
+Decl *
 Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
                                    IdentifierInfo **IdentList,
                                    SourceLocation *IdentLocs,
@@ -1053,7 +1068,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
                                                Interfaces.size());
   CurContext->addDecl(CDecl);
   CheckObjCDeclScope(CDecl);
-  return DeclPtrTy::make(CDecl);
+  return CDecl;
 }
 
 
@@ -1062,13 +1077,14 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
 /// TODO: Handle protocol list; such as id<p1,p2> in type comparisons
 bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
                                       const ObjCMethodDecl *PrevMethod,
-                                      bool matchBasedOnSizeAndAlignment) {
+                                      bool matchBasedOnSizeAndAlignment,
+                                      bool matchBasedOnStrictEqulity) {
   QualType T1 = Context.getCanonicalType(Method->getResultType());
   QualType T2 = Context.getCanonicalType(PrevMethod->getResultType());
 
   if (T1 != T2) {
     // The result types are different.
-    if (!matchBasedOnSizeAndAlignment)
+    if (!matchBasedOnSizeAndAlignment || matchBasedOnStrictEqulity)
       return false;
     // Incomplete types don't have a size and alignment.
     if (T1->isIncompleteType() || T2->isIncompleteType())
@@ -1088,7 +1104,7 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
     T2 = Context.getCanonicalType((*PrevI)->getType());
     if (T1 != T2) {
       // The result types are different.
-      if (!matchBasedOnSizeAndAlignment)
+      if (!matchBasedOnSizeAndAlignment || matchBasedOnStrictEqulity)
         return false;
       // Incomplete types don't have a size and alignment.
       if (T1->isIncompleteType() || T2->isIncompleteType())
@@ -1101,47 +1117,34 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,
   return true;
 }
 
-/// \brief Read the contents of the instance and factory method pools
-/// for a given selector from external storage.
+/// \brief Read the contents of the method pool for a given selector from
+/// external storage.
 ///
-/// This routine should only be called once, when neither the instance
-/// nor the factory method pool has an entry for this selector.
-Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel,
-                                                bool isInstance) {
+/// This routine should only be called once, when the method pool has no entry
+/// for this selector.
+Sema::GlobalMethodPool::iterator Sema::ReadMethodPool(Selector Sel) {
   assert(ExternalSource && "We need an external AST source");
-  assert(InstanceMethodPool.find(Sel) == InstanceMethodPool.end() &&
-         "Selector data already loaded into the instance method pool");
-  assert(FactoryMethodPool.find(Sel) == FactoryMethodPool.end() &&
-         "Selector data already loaded into the factory method pool");
+  assert(MethodPool.find(Sel) == MethodPool.end() &&
+         "Selector data already loaded into the method pool");
 
   // Read the method list from the external source.
-  std::pair<ObjCMethodList, ObjCMethodList> Methods
-    = ExternalSource->ReadMethodPool(Sel);
+  GlobalMethods Methods = ExternalSource->ReadMethodPool(Sel);
 
-  if (isInstance) {
-    if (Methods.second.Method)
-      FactoryMethodPool[Sel] = Methods.second;
-    return InstanceMethodPool.insert(std::make_pair(Sel, Methods.first)).first;
-  }
-
-  if (Methods.first.Method)
-    InstanceMethodPool[Sel] = Methods.first;
-
-  return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first;
+  return MethodPool.insert(std::make_pair(Sel, Methods)).first;
 }
 
-void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
-  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
-    = InstanceMethodPool.find(Method->getSelector());
-  if (Pos == InstanceMethodPool.end()) {
-    if (ExternalSource && !FactoryMethodPool.count(Method->getSelector()))
-      Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/true);
+void Sema::AddMethodToGlobalPool(ObjCMethodDecl *Method, bool impl,
+                                 bool instance) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Method->getSelector());
+  if (Pos == MethodPool.end()) {
+    if (ExternalSource)
+      Pos = ReadMethodPool(Method->getSelector());
     else
-      Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(),
-                                                     ObjCMethodList())).first;
+      Pos = MethodPool.insert(std::make_pair(Method->getSelector(),
+                                             GlobalMethods())).first;
   }
-
-  ObjCMethodList &Entry = Pos->second;
+  Method->setDefined(impl);
+  ObjCMethodList &Entry = instance ? Pos->second.first : Pos->second.second;
   if (Entry.Method == 0) {
     // Haven't seen a method with this selector name yet - add it.
     Entry.Method = Method;
@@ -1152,8 +1155,10 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
   // We've seen a method with this name, see if we have already seen this type
   // signature.
   for (ObjCMethodList *List = &Entry; List; List = List->Next)
-    if (MatchTwoMethodDeclarations(Method, List->Method))
+    if (MatchTwoMethodDeclarations(Method, List->Method)) {
+      List->Method->setDefined(impl);
       return;
+    }
 
   // We have a new signature for an existing method - add it.
   // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
@@ -1161,102 +1166,65 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) {
   Entry.Next = new (Mem) ObjCMethodList(Method, Entry.Next);
 }
 
-// FIXME: Finish implementing -Wno-strict-selector-match.
-ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel,
-                                                       SourceRange R,
-                                                       bool warn) {
-  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
-    = InstanceMethodPool.find(Sel);
-  if (Pos == InstanceMethodPool.end()) {
-    if (ExternalSource && !FactoryMethodPool.count(Sel))
-      Pos = ReadMethodPool(Sel, /*isInstance=*/true);
+ObjCMethodDecl *Sema::LookupMethodInGlobalPool(Selector Sel, SourceRange R,
+                                               bool receiverIdOrClass,
+                                               bool warn, bool instance) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+  if (Pos == MethodPool.end()) {
+    if (ExternalSource)
+      Pos = ReadMethodPool(Sel);
     else
       return 0;
   }
 
-  ObjCMethodList &MethList = Pos->second;
-  bool issueWarning = false;
+  ObjCMethodList &MethList = instance ? Pos->second.first : Pos->second.second;
 
-  if (MethList.Method && MethList.Next) {
-    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
-      // This checks if the methods differ by size & alignment.
-      if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
-        issueWarning = warn;
-  }
-  if (issueWarning && (MethList.Method && MethList.Next)) {
-    Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
-    Diag(MethList.Method->getLocStart(), diag::note_using)
-      << MethList.Method->getSourceRange();
-    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
-      Diag(Next->Method->getLocStart(), diag::note_also_found)
-        << Next->Method->getSourceRange();
-  }
-  return MethList.Method;
-}
+  bool strictSelectorMatch = receiverIdOrClass && warn &&
+    (Diags.getDiagnosticLevel(diag::warn_strict_multiple_method_decl) != 
+      Diagnostic::Ignored);
+  if (warn && MethList.Method && MethList.Next) {
+    bool issueWarning = false;
+    if (strictSelectorMatch)
+      for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) {
+        // This checks if the methods differ in type mismatch.
+        if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, false, true))
+          issueWarning = true;
+      }
 
-void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
-  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
-    = FactoryMethodPool.find(Method->getSelector());
-  if (Pos == FactoryMethodPool.end()) {
-    if (ExternalSource && !InstanceMethodPool.count(Method->getSelector()))
-      Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/false);
-    else
-      Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(),
-                                                    ObjCMethodList())).first;
-  }
+    if (!issueWarning)
+      for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) {
+        // This checks if the methods differ by size & alignment.
+        if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
+          issueWarning = true;
+      }
 
-  ObjCMethodList &FirstMethod = Pos->second;
-  if (!FirstMethod.Method) {
-    // Haven't seen a method with this selector name yet - add it.
-    FirstMethod.Method = Method;
-    FirstMethod.Next = 0;
-  } else {
-    // We've seen a method with this name, now check the type signature(s).
-    bool match = MatchTwoMethodDeclarations(Method, FirstMethod.Method);
-
-    for (ObjCMethodList *Next = FirstMethod.Next; !match && Next;
-         Next = Next->Next)
-      match = MatchTwoMethodDeclarations(Method, Next->Method);
-
-    if (!match) {
-      // We have a new signature for an existing method - add it.
-      // This is extremely rare. Only 1% of Cocoa selectors are "overloaded".
-      ObjCMethodList *Mem = BumpAlloc.Allocate<ObjCMethodList>();
-      ObjCMethodList *OMI = new (Mem) ObjCMethodList(Method, FirstMethod.Next);
-      FirstMethod.Next = OMI;
+    if (issueWarning) {
+      if (strictSelectorMatch)
+        Diag(R.getBegin(), diag::warn_strict_multiple_method_decl) << Sel << R;
+      else
+        Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
+      Diag(MethList.Method->getLocStart(), diag::note_using)
+        << MethList.Method->getSourceRange();
+      for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
+        Diag(Next->Method->getLocStart(), diag::note_also_found)
+          << Next->Method->getSourceRange();
     }
   }
+  return MethList.Method;
 }
 
-ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel,
-                                                      SourceRange R) {
-  llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos
-    = FactoryMethodPool.find(Sel);
-  if (Pos == FactoryMethodPool.end()) {
-    if (ExternalSource && !InstanceMethodPool.count(Sel))
-      Pos = ReadMethodPool(Sel, /*isInstance=*/false);
-    else
-      return 0;
-  }
+ObjCMethodDecl *Sema::LookupImplementedMethodInGlobalPool(Selector Sel) {
+  GlobalMethodPool::iterator Pos = MethodPool.find(Sel);
+  if (Pos == MethodPool.end())
+    return 0;
 
-  ObjCMethodList &MethList = Pos->second;
-  bool issueWarning = false;
+  GlobalMethods &Methods = Pos->second;
 
-  if (MethList.Method && MethList.Next) {
-    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
-      // This checks if the methods differ by size & alignment.
-      if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true))
-        issueWarning = true;
-  }
-  if (issueWarning && (MethList.Method && MethList.Next)) {
-    Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R;
-    Diag(MethList.Method->getLocStart(), diag::note_using)
-      << MethList.Method->getSourceRange();
-    for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next)
-      Diag(Next->Method->getLocStart(), diag::note_also_found)
-        << Next->Method->getSourceRange();
-  }
-  return MethList.Method;
+  if (Methods.first.Method && Methods.first.Method->isDefined())
+    return Methods.first.Method;
+  if (Methods.second.Method && Methods.second.Method->isDefined())
+    return Methods.second.Method;
+  return 0;
 }
 
 /// CompareMethodParamsInBaseAndSuper - This routine compares methods with
@@ -1322,12 +1290,10 @@ void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
 // Note: For class/category implemenations, allMethods/allProperties is
 // always null.
 void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
-                      DeclPtrTy classDecl,
-                      DeclPtrTy *allMethods, unsigned allNum,
-                      DeclPtrTy *allProperties, unsigned pNum,
+                      Decl *ClassDecl,
+                      Decl **allMethods, unsigned allNum,
+                      Decl **allProperties, unsigned pNum,
                       DeclGroupPtrTy *allTUVars, unsigned tuvNum) {
-  Decl *ClassDecl = classDecl.getAs<Decl>();
-
   // FIXME: If we don't have a ClassDecl, we have an error. We should consider
   // always passing in a decl. If the decl has an error, isInvalidDecl()
   // should be true.
@@ -1356,7 +1322,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
 
   for (unsigned i = 0; i < allNum; i++ ) {
     ObjCMethodDecl *Method =
-      cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
+      cast_or_null<ObjCMethodDecl>(allMethods[i]);
 
     if (!Method) continue;  // Already issued a diagnostic.
     if (Method->isInstanceMethod()) {
@@ -1403,14 +1369,14 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
     // Compares properties declared in this class to those of its
     // super class.
     ComparePropertiesInBaseAndSuper(I);
-    CompareProperties(I, DeclPtrTy::make(I));
+    CompareProperties(I, I);
   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
     // Categories are used to extend the class by declaring new methods.
     // By the same token, they are also used to add new properties. No
     // need to compare the added property to those in the class.
 
     // Compare protocol properties with those in category
-    CompareProperties(C, DeclPtrTy::make(C));
+    CompareProperties(C, C);
     if (C->IsClassExtension())
       DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
   }
@@ -1432,6 +1398,7 @@ void Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd,
         DefaultSynthesizeProperties(S, IC, IDecl);
       ImplMethodsVsClassMethods(S, IC, IDecl);
       AtomicPropertySetterGetterRules(IC, IDecl);
+  
       if (LangOpts.ObjCNonFragileABI2)
         while (IDecl->getSuperClass()) {
           DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
@@ -1491,19 +1458,20 @@ CvtQTToAstBitMask(ObjCDeclSpec::ObjCDeclQualifier PQTVal) {
 }
 
 static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &A) {
   // The 'ibaction' attribute is allowed on method definitions because of
   // how the IBAction macro is used on both method declarations and definitions.
   // If the method definitions contains any other attributes, return true.
-  while (A && A->getKind() == AttributeList::AT_IBAction)
-    A = A->getNext();
-  return A != NULL;
+  for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+    if ((*i)->getKind() != attr::IBAction)
+      return true;
+  return false;
 }
 
-Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
+Decl *Sema::ActOnMethodDeclaration(
     SourceLocation MethodLoc, SourceLocation EndLoc,
-    tok::TokenKind MethodType, DeclPtrTy classDecl,
-    ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
+    tok::TokenKind MethodType, Decl *ClassDecl,
+    ObjCDeclSpec &ReturnQT, ParsedType ReturnType,
     Selector Sel,
     // optional arguments. The number of types/arguments is obtained
     // from the Sel.getNumArgs().
@@ -1511,13 +1479,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
     DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
     AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
     bool isVariadic) {
-  Decl *ClassDecl = classDecl.getAs<Decl>();
-
   // Make sure we can establish a context for the method.
   if (!ClassDecl) {
     Diag(MethodLoc, diag::error_missing_method_context);
-    getLabelMap().clear();
-    return DeclPtrTy();
+    getCurFunction()->LabelMap.clear();
+    return 0;
   }
   QualType resultDeclType;
 
@@ -1530,7 +1496,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
     if (resultDeclType->isObjCObjectType()) {
       Diag(MethodLoc, diag::err_object_cannot_be_passed_returned_by_value)
         << 0 << resultDeclType;
-      return DeclPtrTy();
+      return 0;
     }
   } else // get the type for "id".
     resultDeclType = Context.getObjCIdType();
@@ -1540,7 +1506,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
                            ResultTInfo,
                            cast<DeclContext>(ClassDecl),
                            MethodType == tok::minus, isVariadic,
-                           false,
+                           false, false,
                            MethodDeclKind == tok::objc_optional ?
                            ObjCMethodDecl::Optional :
                            ObjCMethodDecl::Required);
@@ -1563,7 +1529,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
     ParmVarDecl* Param
       = ParmVarDecl::Create(Context, ObjCMethod, ArgInfo[i].NameLoc,
                             ArgInfo[i].Name, ArgType, DI,
-                            VarDecl::None, VarDecl::None, 0);
+                            SC_None, SC_None, 0);
 
     if (ArgType->isObjCObjectType()) {
       Diag(ArgInfo[i].NameLoc,
@@ -1582,7 +1548,7 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
   }
 
   for (unsigned i = 0, e = CNumArgs; i != e; ++i) {
-    ParmVarDecl *Param = CParamInfo[i].Param.getAs<ParmVarDecl>();
+    ParmVarDecl *Param = cast<ParmVarDecl>(CParamInfo[i].Param);
     QualType ArgType = Param->getType();
     if (ArgType.isNull())
       ArgType = Context.getObjCIdType();
@@ -1596,7 +1562,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
       Param->setInvalidDecl();
     }
     Param->setDeclContext(ObjCMethod);
-    IdResolver.RemoveDecl(Param);
+    if (Param->getDeclName())
+      IdResolver.RemoveDecl(Param);
     Params.push_back(Param);
   }
   
@@ -1626,7 +1593,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
     }
     InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
                                                    MethodType == tok::minus);
-    if (containsInvalidMethodImplAttribute(AttrList))
+    if (ObjCMethod->hasAttrs() &&
+        containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
       Diag(EndLoc, diag::warn_attribute_method_def);
   } else if (ObjCCategoryImplDecl *CatImpDecl =
              dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1637,7 +1605,8 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
       PrevMethod = CatImpDecl->getClassMethod(Sel);
       CatImpDecl->addClassMethod(ObjCMethod);
     }
-    if (containsInvalidMethodImplAttribute(AttrList))
+    if (ObjCMethod->hasAttrs() &&
+        containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
       Diag(EndLoc, diag::warn_attribute_method_def);
   }
   if (PrevMethod) {
@@ -1649,14 +1618,16 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
 
   // If the interface declared this method, and it was deprecated there,
   // mark it deprecated here.
-  if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
-    ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+  if (InterfaceMD)
+   if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+    ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+                                                       Context));
 
-  return DeclPtrTy::make(ObjCMethod);
+  return ObjCMethod;
 }
 
 bool Sema::CheckObjCDeclScope(Decl *D) {
-  if (isa<TranslationUnitDecl>(CurContext->getLookupContext()))
+  if (isa<TranslationUnitDecl>(CurContext->getRedeclContext()))
     return false;
 
   Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
@@ -1667,9 +1638,9 @@ bool Sema::CheckObjCDeclScope(Decl *D) {
 
 /// Called whenever @defs(ClassName) is encountered in the source.  Inserts the
 /// instance variables of ClassName into Decls.
-void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
+void Sema::ActOnDefs(Scope *S, Decl *TagD, SourceLocation DeclStart,
                      IdentifierInfo *ClassName,
-                     llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
+                     llvm::SmallVectorImpl<Decl*> &Decls) {
   // Check that ClassName is a valid class
   ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName, DeclStart);
   if (!Class) {
@@ -1682,25 +1653,25 @@ void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
   }
 
   // Collect the instance variables
-  llvm::SmallVector<FieldDecl*, 32> RecFields;
-  Context.CollectObjCIvars(Class, RecFields);
+  llvm::SmallVector<ObjCIvarDecl*, 32> Ivars;
+  Context.DeepCollectObjCIvars(Class, true, Ivars);
   // For each ivar, create a fresh ObjCAtDefsFieldDecl.
-  for (unsigned i = 0; i < RecFields.size(); i++) {
-    FieldDecl* ID = RecFields[i];
-    RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>());
+  for (unsigned i = 0; i < Ivars.size(); i++) {
+    FieldDecl* ID = cast<FieldDecl>(Ivars[i]);
+    RecordDecl *Record = dyn_cast<RecordDecl>(TagD);
     Decl *FD = ObjCAtDefsFieldDecl::Create(Context, Record, ID->getLocation(),
                                            ID->getIdentifier(), ID->getType(),
                                            ID->getBitWidth());
-    Decls.push_back(Sema::DeclPtrTy::make(FD));
+    Decls.push_back(FD);
   }
 
   // Introduce all of these fields into the appropriate scope.
-  for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
+  for (llvm::SmallVectorImpl<Decl*>::iterator D = Decls.begin();
        D != Decls.end(); ++D) {
-    FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
+    FieldDecl *FD = cast<FieldDecl>(*D);
     if (getLangOptions().CPlusPlus)
       PushOnScopeChains(cast<FieldDecl>(FD), S);
-    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
+    else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD))
       Record->addDecl(FD);
   }
 }
@@ -1735,7 +1706,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo,
   }
   
   VarDecl *New = VarDecl::Create(Context, CurContext, NameLoc, Name, T, TInfo,
-                                 VarDecl::None, VarDecl::None);
+                                 SC_None, SC_None);
   New->setExceptionVariable(true);
   
   if (Invalid)
@@ -1743,7 +1714,7 @@ VarDecl *Sema::BuildObjCExceptionDecl(TypeSourceInfo *TInfo,
   return New;
 }
 
-Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+Decl *Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
   const DeclSpec &DS = D.getDeclSpec();
   
   // We allow the "register" storage class on exception variables because
@@ -1788,7 +1759,7 @@ Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
   }
   
   // Add the parameter declaration into this scope.
-  S->AddDecl(DeclPtrTy::make(New));
+  S->AddDecl(New);
   if (D.getIdentifier())
     IdResolver.AddDecl(New);
   
@@ -1796,43 +1767,18 @@ Sema::DeclPtrTy Sema::ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
   
   if (New->hasAttr<BlocksAttr>())
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
-  return DeclPtrTy::make(New);
+  return New;
 }
 
 /// CollectIvarsToConstructOrDestruct - Collect those ivars which require
 /// initialization.
-void Sema::CollectIvarsToConstructOrDestruct(const ObjCInterfaceDecl *OI,
+void Sema::CollectIvarsToConstructOrDestruct(ObjCInterfaceDecl *OI,
                                 llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
-  for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
-       E = OI->ivar_end(); I != E; ++I) {
-    ObjCIvarDecl *Iv = (*I);
+  for (ObjCIvarDecl *Iv = OI->all_declared_ivar_begin(); Iv; 
+       Iv= Iv->getNextIvar()) {
     QualType QT = Context.getBaseElementType(Iv->getType());
     if (QT->isRecordType())
-      Ivars.push_back(*I);
-  }
-  
-  // Find ivars to construct/destruct in class extension.
-  for (const ObjCCategoryDecl *CDecl = OI->getFirstClassExtension(); CDecl;
-      CDecl = CDecl->getNextClassExtension()) {
-    for (ObjCCategoryDecl::ivar_iterator I = CDecl->ivar_begin(),
-         E = CDecl->ivar_end(); I != E; ++I) {
-      ObjCIvarDecl *Iv = (*I);
-      QualType QT = Context.getBaseElementType(Iv->getType());
-      if (QT->isRecordType())
-        Ivars.push_back(*I);
-    }
-  }
-  
-  // Also add any ivar defined in this class's implementation.  This
-  // includes synthesized ivars.
-  if (ObjCImplementationDecl *ImplDecl = OI->getImplementation()) {
-    for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(),
-         E = ImplDecl->ivar_end(); I != E; ++I) {
-      ObjCIvarDecl *Iv = (*I);
-      QualType QT = Context.getBaseElementType(Iv->getType());
-      if (QT->isRecordType())
-        Ivars.push_back(*I);
-    }
+      Ivars.push_back(Iv);
   }
 }
 
@@ -1849,3 +1795,15 @@ void ObjCImplementationDecl::setIvarInitializers(ASTContext &C,
   }
 }
 
+void Sema::DiagnoseUseOfUnimplementedSelectors() {
+  if (ReferencedSelectors.empty())
+    return;
+  for (llvm::DenseMap<Selector, SourceLocation>::iterator S = 
+        ReferencedSelectors.begin(),
+       E = ReferencedSelectors.end(); S != E; ++S) {
+    Selector Sel = (*S).first;
+    if (!LookupImplementedMethodInGlobalPool(Sel))
+      Diag((*S).second, diag::warn_unimplemented_selector) << Sel;
+  }
+  return;
+}
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp
index 34a479a..c902e77 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -11,7 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
@@ -261,6 +261,14 @@ bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
 
   bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec();
   bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec();
+  if (getLangOptions().Microsoft) {
+    // Treat throw(whatever) as throw(...) to be compatible with MS headers.
+    if (New->hasExceptionSpec() && New->getNumExceptions() > 0)
+      NewAny = true;
+    if (Old->hasExceptionSpec() && Old->getNumExceptions() > 0)
+      OldAny = true;
+  }
+
   if (OldAny && NewAny)
     return false;
   if (OldAny || NewAny) {
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5f46a97..80b4652 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -11,10 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
@@ -29,11 +29,14 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Designator.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/Template.h"
 using namespace clang;
+using namespace sema;
 
 
 /// \brief Determine whether the use of this declaration is valid, and
@@ -59,7 +62,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
 
   // See if the decl is unavailable
   if (D->getAttr<UnavailableAttr>()) {
-    Diag(Loc, diag::warn_unavailable) << D->getDeclName();
+    Diag(Loc, diag::err_unavailable) << D->getDeclName();
     Diag(D->getLocation(), diag::note_unavailable_here) << 0;
   }
 
@@ -192,7 +195,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
 
   if (Ty->isFunctionType())
     ImpCastExprToType(E, Context.getPointerType(Ty),
-                      CastExpr::CK_FunctionToPointerDecay);
+                      CK_FunctionToPointerDecay);
   else if (Ty->isArrayType()) {
     // In C90 mode, arrays only promote to pointers if the array expression is
     // an lvalue.  The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -208,7 +211,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
     if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
         E->isLvalue(Context) == Expr::LV_Valid)
       ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
-                        CastExpr::CK_ArrayToPointerDecay);
+                        CK_ArrayToPointerDecay);
   }
 }
 
@@ -229,7 +232,7 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
     //   If the lvalue has qualified type, the value has the unqualified
     //   version of the type of the lvalue; otherwise, the value has the
     //   type of the lvalue.
-    ImpCastExprToType(E, Ty.getUnqualifiedType(), CastExpr::CK_NoOp);
+    ImpCastExprToType(E, Ty.getUnqualifiedType(), CK_NoOp);
   }
 }
 
@@ -258,12 +261,12 @@ Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
   //   other types are unchanged by the integer promotions.
   QualType PTy = Context.isPromotableBitField(Expr);
   if (!PTy.isNull()) {
-    ImpCastExprToType(Expr, PTy, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(Expr, PTy, CK_IntegralCast);
     return Expr;
   }
   if (Ty->isPromotableIntegerType()) {
     QualType PT = Context.getPromotedIntegerType(Ty);
-    ImpCastExprToType(Expr, PT, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(Expr, PT, CK_IntegralCast);
     return Expr;
   }
 
@@ -281,7 +284,7 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
   // If this is a 'float' (CVR qualified or typedef) promote to double.
   if (Ty->isSpecificBuiltinType(BuiltinType::Float))
     return ImpCastExprToType(Expr, Context.DoubleTy,
-                             CastExpr::CK_FloatingCast);
+                             CK_FloatingCast);
 
   UsualUnaryConversions(Expr);
 }
@@ -355,8 +358,8 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
 
   QualType destType = Context.UsualArithmeticConversionsType(lhs, rhs);
   if (!isCompAssign)
-    ImpCastExprToType(lhsExpr, destType, CastExpr::CK_Unknown);
-  ImpCastExprToType(rhsExpr, destType, CastExpr::CK_Unknown);
+    ImpCastExprToType(lhsExpr, destType, CK_Unknown);
+  ImpCastExprToType(rhsExpr, destType, CK_Unknown);
   return destType;
 }
 
@@ -371,7 +374,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
 /// multiple tokens.  However, the common case is that StringToks points to one
 /// string.
 ///
-Action::OwningExprResult
+ExprResult
 Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
   assert(NumStringToks && "Must have at least one string!");
 
@@ -459,13 +462,20 @@ static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock,
 }
 
 
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+                       const CXXScopeSpec *SS) {
+  DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
+  return BuildDeclRefExpr(D, Ty, NameInfo, SS);
+}
 
 /// BuildDeclRefExpr - Build a DeclRefExpr.
-Sema::OwningExprResult
-Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+                       const DeclarationNameInfo &NameInfo,
                        const CXXScopeSpec *SS) {
   if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
-    Diag(Loc,
+    Diag(NameInfo.getLoc(),
          diag::err_auto_variable_cannot_appear_in_own_initializer)
       << D->getDeclName();
     return ExprError();
@@ -479,7 +489,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
     } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
       if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
         if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
-          Diag(Loc, diag::err_reference_to_local_var_in_enclosing_function)
+          Diag(NameInfo.getLoc(),
+               diag::err_reference_to_local_var_in_enclosing_function)
             << D->getIdentifier() << FD->getDeclName();
           Diag(D->getLocation(), diag::note_local_variable_declared_here)
             << D->getIdentifier();
@@ -489,12 +500,12 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
     }
   }
 
-  MarkDeclarationReferenced(Loc, D);
+  MarkDeclarationReferenced(NameInfo.getLoc(), D);
 
   return Owned(DeclRefExpr::Create(Context,
                               SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
                                    SS? SS->getRange() : SourceRange(),
-                                   D, Loc, Ty));
+                                   D, NameInfo, Ty));
 }
 
 /// \brief Given a field that represents a member of an anonymous
@@ -535,7 +546,7 @@ VarDecl *Sema::BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
   return BaseObject;
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
                                                FieldDecl *Field,
                                                Expr *BaseObjectExpr,
@@ -553,7 +564,6 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
   if (BaseObject) {
     // BaseObject is an anonymous struct/union variable (and is,
     // therefore, not part of another non-anonymous record).
-    if (BaseObjectExpr) BaseObjectExpr->Destroy(Context);
     MarkDeclarationReferenced(Loc, BaseObject);
     BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(),
                                                SourceLocation());
@@ -640,7 +650,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
   return Owned(Result);
 }
 
-/// Decomposes the given name into a DeclarationName, its location, and
+/// Decomposes the given name into a DeclarationNameInfo, its location, and
 /// possibly a list of template arguments.
 ///
 /// If this produces template arguments, it is permitted to call
@@ -652,8 +662,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
 static void DecomposeUnqualifiedId(Sema &SemaRef,
                                    const UnqualifiedId &Id,
                                    TemplateArgumentListInfo &Buffer,
-                                   DeclarationName &Name,
-                                   SourceLocation &NameLoc,
+                                   DeclarationNameInfo &NameInfo,
                              const TemplateArgumentListInfo *&TemplateArgs) {
   if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
     Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
@@ -665,15 +674,12 @@ static void DecomposeUnqualifiedId(Sema &SemaRef,
     SemaRef.translateTemplateArguments(TemplateArgsPtr, Buffer);
     TemplateArgsPtr.release();
 
-    TemplateName TName =
-      Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
-
-    Name = SemaRef.Context.getNameForTemplate(TName);
-    NameLoc = Id.TemplateId->TemplateNameLoc;
+    TemplateName TName = Id.TemplateId->Template.get();
+    SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc;
+    NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc);
     TemplateArgs = &Buffer;
   } else {
-    Name = SemaRef.GetNameFromUnqualifiedId(Id);
-    NameLoc = Id.StartLocation;
+    NameInfo = SemaRef.GetNameFromUnqualifiedId(Id);
     TemplateArgs = 0;
   }
 }
@@ -700,23 +706,6 @@ static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) {
   return true;
 }
 
-/// Determines whether we can lookup this id-expression now or whether
-/// we have to wait until template instantiation is complete.
-static bool IsDependentIdExpression(Sema &SemaRef, const CXXScopeSpec &SS) {
-  DeclContext *DC = SemaRef.computeDeclContext(SS, false);
-
-  // If the qualifier scope isn't computable, it's definitely dependent.
-  if (!DC) return true;
-
-  // If the qualifier scope doesn't name a record, we can always look into it.
-  if (!isa<CXXRecordDecl>(DC)) return false;
-
-  // We can't look into record types unless they're fully-formed.
-  if (!IsFullyFormedScope(SemaRef, cast<CXXRecordDecl>(DC))) return true;
-
-  return false;
-}
-
 /// Determines if the given class is provably not derived from all of
 /// the prospective base classes.
 static bool IsProvablyNotDerivedFrom(Sema &SemaRef,
@@ -905,25 +894,30 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
         // TODO: fixit for inserting 'Base<T>::' in the other cases.
         // Actually quite difficult!
         if (isInstance) {
-          Diag(R.getNameLoc(), diagnostic) << Name
-            << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
-
           UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
               CallsUndergoingInstantiation.back()->getCallee());
-          CXXMethodDecl *DepMethod = cast<CXXMethodDecl>(
+          CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
               CurMethod->getInstantiatedFromMemberFunction());
-          QualType DepThisType = DepMethod->getThisType(Context);
-          CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(),
-                                                           DepThisType, false);
-          TemplateArgumentListInfo TList;
-          if (ULE->hasExplicitTemplateArgs())
-            ULE->copyTemplateArgumentsInto(TList);
-          CXXDependentScopeMemberExpr *DepExpr =
-              CXXDependentScopeMemberExpr::Create(
-                  Context, DepThis, DepThisType, true, SourceLocation(),
-                  ULE->getQualifier(), ULE->getQualifierRange(), NULL, Name,
-                  R.getNameLoc(), &TList);
-          CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+          if (DepMethod) {
+            Diag(R.getNameLoc(), diagnostic) << Name
+              << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
+            QualType DepThisType = DepMethod->getThisType(Context);
+            CXXThisExpr *DepThis = new (Context) CXXThisExpr(
+                                       R.getNameLoc(), DepThisType, false);
+            TemplateArgumentListInfo TList;
+            if (ULE->hasExplicitTemplateArgs())
+              ULE->copyTemplateArgumentsInto(TList);
+            CXXDependentScopeMemberExpr *DepExpr =
+                CXXDependentScopeMemberExpr::Create(
+                    Context, DepThis, DepThisType, true, SourceLocation(),
+                    ULE->getQualifier(), ULE->getQualifierRange(), NULL,
+                    R.getLookupNameInfo(), &TList);
+            CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+          } else {
+            // FIXME: we should be able to handle this case too. It is correct
+            // to add this-> here. This is a workaround for PR7947.
+            Diag(R.getNameLoc(), diagnostic) << Name;
+          }
         } else {
           Diag(R.getNameLoc(), diagnostic) << Name;
         }
@@ -935,6 +929,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
         // Tell the callee to try to recover.
         return false;
       }
+
+      R.clear();
     }
   }
 
@@ -1005,11 +1001,74 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
   return true;
 }
 
-Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
-                                               CXXScopeSpec &SS,
-                                               UnqualifiedId &Id,
-                                               bool HasTrailingLParen,
-                                               bool isAddressOfOperand) {
+static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef,
+                                                       IdentifierInfo *II,
+                                                       SourceLocation NameLoc) {
+  ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+  ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+  if (!IDecl)
+    return 0;
+  ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+  if (!ClassImpDecl)
+    return 0;
+  ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+  if (!property)
+    return 0;
+  if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+    if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      return 0;
+  return property;
+}
+
+static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
+                                               LookupResult &Lookup,
+                                               IdentifierInfo *II,
+                                               SourceLocation NameLoc) {
+  ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+  bool LookForIvars;
+  if (Lookup.empty())
+    LookForIvars = true;
+  else if (CurMeth->isClassMethod())
+    LookForIvars = false;
+  else
+    LookForIvars = (Lookup.isSingleResult() &&
+                    Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+  if (!LookForIvars)
+    return 0;
+  
+  ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+  if (!IDecl)
+    return 0;
+  ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+  if (!ClassImpDecl)
+    return 0;
+  bool DynamicImplSeen = false;
+  ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+  if (!property)
+    return 0;
+  if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+    DynamicImplSeen = 
+      (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+  if (!DynamicImplSeen) {
+    QualType PropType = SemaRef.Context.getCanonicalType(property->getType());
+    ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(SemaRef.Context, ClassImpDecl, 
+                                              NameLoc,
+                                              II, PropType, /*Dinfo=*/0,
+                                              ObjCIvarDecl::Protected,
+                                              (Expr *)0, true);
+    ClassImpDecl->addDecl(Ivar);
+    IDecl->makeDeclVisibleInContext(Ivar, false);
+    property->setPropertyIvarDecl(Ivar);
+    return Ivar;
+  }
+  return 0;
+}
+
+ExprResult Sema::ActOnIdExpression(Scope *S,
+                                   CXXScopeSpec &SS,
+                                   UnqualifiedId &Id,
+                                   bool HasTrailingLParen,
+                                   bool isAddressOfOperand) {
   assert(!(isAddressOfOperand && HasTrailingLParen) &&
          "cannot be direct & operand and have a trailing lparen");
 
@@ -1019,13 +1078,13 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
   TemplateArgumentListInfo TemplateArgsBuffer;
 
   // Decompose the UnqualifiedId into the following data.
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   const TemplateArgumentListInfo *TemplateArgs;
-  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
-                         Name, NameLoc, TemplateArgs);
+  DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
 
+  DeclarationName Name = NameInfo.getName();
   IdentifierInfo *II = Name.getAsIdentifierInfo();
+  SourceLocation NameLoc = NameInfo.getLoc();
 
   // C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
@@ -1038,16 +1097,30 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
   //        names a dependent type.
   // Determine whether this is a member of an unknown specialization;
   // we need to handle these differently.
-  if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
-       Name.getCXXNameType()->isDependentType()) ||
-      (SS.isSet() && IsDependentIdExpression(*this, SS))) {
-    return ActOnDependentIdExpression(SS, Name, NameLoc,
-                                      isAddressOfOperand,
-                                      TemplateArgs);
+  bool DependentID = false;
+  if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+      Name.getCXXNameType()->isDependentType()) {
+    DependentID = true;
+  } else if (SS.isSet()) {
+    DeclContext *DC = computeDeclContext(SS, false);
+    if (DC) {
+      if (RequireCompleteDeclContext(SS, DC))
+        return ExprError();
+      // FIXME: We should be checking whether DC is the current instantiation.
+      if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
+        DependentID = !IsFullyFormedScope(*this, RD);
+    } else {
+      DependentID = true;
+    }
   }
 
+  if (DependentID) {
+    return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand,
+                                      TemplateArgs);
+  }
+  bool IvarLookupFollowUp = false;
   // Perform the required lookup.
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   if (TemplateArgs) {
     // Lookup the template name again to correctly establish the context in
     // which it was found. This is really unfortunate as we already did the
@@ -1058,18 +1131,26 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
     LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false,
                        MemberOfUnknownSpecialization);
   } else {
-    bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+    IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
     LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
 
     // If this reference is in an Objective-C method, then we need to do
     // some special Objective-C lookup, too.
     if (IvarLookupFollowUp) {
-      OwningExprResult E(LookupInObjCMethod(R, S, II, true));
+      ExprResult E(LookupInObjCMethod(R, S, II, true));
       if (E.isInvalid())
         return ExprError();
 
       Expr *Ex = E.takeAs<Expr>();
       if (Ex) return Owned(Ex);
+      // Synthesize ivars lazily
+      if (getLangOptions().ObjCNonFragileABI2) {
+        if (SynthesizeProvisionalIvar(*this, R, II, NameLoc))
+          return ActOnIdExpression(S, SS, Id, HasTrailingLParen,
+                                   isAddressOfOperand);
+      }
+      // for further use, this must be set to false if in class method.
+      IvarLookupFollowUp = getCurMethodDecl()->isInstanceMethod();
     }
   }
 
@@ -1102,7 +1183,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
       // reference the ivar.
       if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
         R.clear();
-        OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+        ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
         assert(E.isInvalid() || E.get());
         return move(E);
       }
@@ -1113,23 +1194,15 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
   assert(!R.empty() || ADL);
 
   if (VarDecl *Var = R.getAsSingle<VarDecl>()) {
-    // Warn about constructs like:
-    //   if (void *X = foo()) { ... } else { X }.
-    // In the else block, the pointer is always false.
-    if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
-      Scope *CheckS = S;
-      while (CheckS && CheckS->getControlParent()) {
-        if ((CheckS->getFlags() & Scope::ElseScope) &&
-            CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
-          ExprError(Diag(NameLoc, diag::warn_value_always_zero)
-            << Var->getDeclName()
-            << (Var->getType()->isPointerType() ? 2 :
-                Var->getType()->isBooleanType() ? 1 : 0));
-          break;
-        }
-
-        // Move to the parent of this scope.
-        CheckS = CheckS->getParent();
+    if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp &&
+        !getLangOptions().ObjCNonFragileABI2 &&
+        Var->isFileVarDecl()) {
+      ObjCPropertyDecl *Property = 
+        OkToSynthesizeProvisionalIvar(*this, II, NameLoc);
+      if (Property) {
+        Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName();
+        Diag(Property->getLocation(), diag::note_property_declare);
+        Diag(Var->getLocation(), diag::note_global_declared_at);
       }
     }
   } else if (FunctionDecl *Func = R.getAsSingle<FunctionDecl>()) {
@@ -1152,15 +1225,43 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
   }
 
   // Check whether this might be a C++ implicit instance member access.
-  // C++ [expr.prim.general]p6:
-  //   Within the definition of a non-static member function, an
-  //   identifier that names a non-static member is transformed to a
-  //   class member access expression.
-  // But note that &SomeClass::foo is grammatically distinct, even
-  // though we don't parse it that way.
+  // C++ [class.mfct.non-static]p3:
+  //   When an id-expression that is not part of a class member access
+  //   syntax and not used to form a pointer to member is used in the
+  //   body of a non-static member function of class X, if name lookup
+  //   resolves the name in the id-expression to a non-static non-type
+  //   member of some class C, the id-expression is transformed into a
+  //   class member access expression using (*this) as the
+  //   postfix-expression to the left of the . operator.
+  //
+  // But we don't actually need to do this for '&' operands if R
+  // resolved to a function or overloaded function set, because the
+  // expression is ill-formed if it actually works out to be a
+  // non-static member function:
+  //
+  // C++ [expr.ref]p4:
+  //   Otherwise, if E1.E2 refers to a non-static member function. . .
+  //   [t]he expression can be used only as the left-hand operand of a
+  //   member function call.
+  //
+  // There are other safeguards against such uses, but it's important
+  // to get this right here so that we don't end up making a
+  // spuriously dependent expression if we're inside a dependent
+  // instance method.
   if (!R.empty() && (*R.begin())->isCXXClassMember()) {
-    bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty());
-    if (!isAbstractMemberPointer)
+    bool MightBeImplicitMember;
+    if (!isAddressOfOperand)
+      MightBeImplicitMember = true;
+    else if (!SS.isEmpty())
+      MightBeImplicitMember = false;
+    else if (R.isOverloadedResult())
+      MightBeImplicitMember = false;
+    else if (R.isUnresolvableResult())
+      MightBeImplicitMember = true;
+    else
+      MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl());
+
+    if (MightBeImplicitMember)
       return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs);
   }
 
@@ -1171,7 +1272,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
 }
 
 /// Builds an expression which might be an implicit member expression.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
                                       LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs) {
@@ -1210,25 +1311,25 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
 /// declaration name, generally during template instantiation.
 /// There's a large number of things which don't need to be done along
 /// this path.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
-                                        DeclarationName Name,
-                                        SourceLocation NameLoc) {
+                                        const DeclarationNameInfo &NameInfo) {
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
-    return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
+    return BuildDependentDeclRefExpr(SS, NameInfo, 0);
 
   if (RequireCompleteDeclContext(SS, DC))
     return ExprError();
 
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   LookupQualifiedName(R, DC);
 
   if (R.isAmbiguous())
     return ExprError();
 
   if (R.empty()) {
-    Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_no_member)
+      << NameInfo.getName() << DC << SS.getRange();
     return ExprError();
   }
 
@@ -1243,7 +1344,7 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
 /// actually quite a lot of extra work involved.
 ///
 /// Returns a null sentinel to indicate trivial success.
-Sema::OwningExprResult
+ExprResult
 Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
                          IdentifierInfo *II, bool AllowBuiltinCreation) {
   SourceLocation Loc = Lookup.getNameLoc();
@@ -1298,7 +1399,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
       UnqualifiedId SelfName;
       SelfName.setIdentifier(&II, SourceLocation());
       CXXScopeSpec SelfScopeSpec;
-      OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+      ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
                                                     SelfName, false, false);
       MarkDeclarationReferenced(Loc, IV);
       return Owned(new (Context)
@@ -1403,9 +1504,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
   SourceRange FromRange = From->getSourceRange();
   SourceLocation FromLoc = FromRange.getBegin();
 
-  bool isLvalue
-    = (From->isLvalue(Context) == Expr::LV_Valid) && !PointerConversions;
-  
+  ExprValueKind VK = CastCategory(From);
+
   // C++ [class.member.lookup]p8:
   //   [...] Ambiguities can often be resolved by qualifying a name with its
   //   class name.
@@ -1435,15 +1535,15 @@ Sema::PerformObjectMemberConversion(Expr *&From,
     // type of the object type, in which case we just ignore it.
     // Otherwise build the appropriate casts.
     if (IsDerivedFrom(FromRecordType, QRecordType)) {
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
       if (CheckDerivedToBaseConversion(FromRecordType, QRecordType,
                                        FromLoc, FromRange, &BasePath))
         return true;
 
       if (PointerConversions)
         QType = Context.getPointerType(QType);
-      ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
-                        isLvalue, BasePath);
+      ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
+                        VK, &BasePath);
 
       FromType = QType;
       FromRecordType = QRecordType;
@@ -1471,7 +1571,7 @@ Sema::PerformObjectMemberConversion(Expr *&From,
     // conversion is non-trivial.
     if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) {
       assert(IsDerivedFrom(FromRecordType, URecordType));
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
       if (CheckDerivedToBaseConversion(FromRecordType, URecordType,
                                        FromLoc, FromRange, &BasePath))
         return true;
@@ -1479,8 +1579,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
       QualType UType = URecordType;
       if (PointerConversions)
         UType = Context.getPointerType(UType);
-      ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
-                        isLvalue, BasePath);
+      ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
+                        VK, &BasePath);
       FromType = UType;
       FromRecordType = URecordType;
     }
@@ -1490,14 +1590,14 @@ Sema::PerformObjectMemberConversion(Expr *&From,
     IgnoreAccess = true;
   }
 
-  CXXBaseSpecifierArray BasePath;
+  CXXCastPath BasePath;
   if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
                                    FromLoc, FromRange, &BasePath,
                                    IgnoreAccess))
     return true;
 
-  ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
-                    isLvalue, BasePath);
+  ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase,
+                    VK, &BasePath);
   return false;
 }
 
@@ -1505,7 +1605,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
 static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
                                    const CXXScopeSpec &SS, ValueDecl *Member,
                                    DeclAccessPair FoundDecl,
-                                   SourceLocation Loc, QualType Ty,
+                                   const DeclarationNameInfo &MemberNameInfo,
+                                   QualType Ty,
                           const TemplateArgumentListInfo *TemplateArgs = 0) {
   NestedNameSpecifier *Qualifier = 0;
   SourceRange QualifierRange;
@@ -1515,14 +1616,15 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
   }
 
   return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange,
-                            Member, FoundDecl, Loc, TemplateArgs, Ty);
+                            Member, FoundDecl, MemberNameInfo,
+                            TemplateArgs, Ty);
 }
 
 /// Builds an implicit member access expression.  The current context
 /// is known to be an instance method, and the given unqualified lookup
 /// set is known to contain only instance members, at least one of which
 /// is from an appropriate type.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
                               LookupResult &R,
                               const TemplateArgumentListInfo *TemplateArgs,
@@ -1551,7 +1653,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
     This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true);
   }
 
-  return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
+  return BuildMemberReferenceExpr(This, ThisType,
                                   /*OpLoc*/ SourceLocation(),
                                   /*IsArrow*/ true,
                                   SS,
@@ -1638,14 +1740,15 @@ static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
   return false;
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
                                LookupResult &R,
                                bool NeedsADL) {
   // If this is a single, fully-resolved result and we don't need ADL,
   // just build an ordinary singleton decl ref.
   if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>())
-    return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl());
+    return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
+                                    R.getFoundDecl());
 
   // We only need to check the declaration if there's exactly one
   // result, because in the overloaded case the results can only be
@@ -1664,8 +1767,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
                                    (NestedNameSpecifier*) SS.getScopeRep(),
-                                   SS.getRange(),
-                                   R.getLookupName(), R.getNameLoc(),
+                                   SS.getRange(), R.getLookupNameInfo(),
                                    NeedsADL, R.isOverloadedResult(),
                                    R.begin(), R.end());
 
@@ -1674,13 +1776,15 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
 
 
 /// \brief Complete semantic analysis for a reference to the given declaration.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                               SourceLocation Loc, NamedDecl *D) {
+                               const DeclarationNameInfo &NameInfo,
+                               NamedDecl *D) {
   assert(D && "Cannot refer to a NULL declaration");
   assert(!isa<FunctionTemplateDecl>(D) &&
          "Cannot refer unambiguously to a function template");
 
+  SourceLocation Loc = NameInfo.getLoc();
   if (CheckDeclInExpr(*this, Loc, D))
     return ExprError();
 
@@ -1755,13 +1859,13 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
                     DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T,
                                           SourceLocation());
       
-        OwningExprResult Res = PerformCopyInitialization(
+        ExprResult Res = PerformCopyInitialization(
                           InitializedEntity::InitializeBlock(VD->getLocation(), 
                                                          T, false),
                                                          SourceLocation(),
                                                          Owned(E));
         if (!Res.isInvalid()) {
-          Res = MaybeCreateCXXExprWithTemporaries(move(Res));
+          Res = MaybeCreateCXXExprWithTemporaries(Res.get());
           Expr *Init = Res.takeAs<Expr>();
           BDRE->setCopyConstructorExpr(Init);
         }
@@ -1772,10 +1876,11 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
   // If this reference is not in a block or if the referenced variable is
   // within the block, create a normal DeclRefExpr.
 
-  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, &SS);
+  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
+                          NameInfo, &SS);
 }
 
-Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
+ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
                                                  tok::TokenKind Kind) {
   PredefinedExpr::IdentType IT;
 
@@ -1790,6 +1895,8 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
   // string.
 
   Decl *currentDecl = getCurFunctionOrMethodDecl();
+  if (!currentDecl && getCurBlock())
+    currentDecl = getCurBlock()->TheDecl;
   if (!currentDecl) {
     Diag(Loc, diag::ext_predef_outside_function);
     currentDecl = Context.getTranslationUnitDecl();
@@ -1808,7 +1915,7 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
   return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
 }
 
-Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
+ExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
   llvm::SmallString<16> CharBuffer;
   bool Invalid = false;
   llvm::StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid);
@@ -1835,13 +1942,13 @@ Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
                                               Ty, Tok.getLocation()));
 }
 
-Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
+ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
   // Fast path for a single digit (which is quite common).  A single digit
   // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
   if (Tok.getLength() == 1) {
     const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
     unsigned IntSize = Context.Target.getIntWidth();
-    return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'),
+    return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'),
                     Context.IntTy, Tok.getLocation()));
   }
 
@@ -1899,7 +2006,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
     }
 
     bool isExact = (result == APFloat::opOK);
-    Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
+    Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation());
 
   } else if (!Literal.isIntegerLiteral()) {
     return ExprError();
@@ -1986,7 +2093,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
       if (ResultVal.getBitWidth() != Width)
         ResultVal.trunc(Width);
     }
-    Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+    Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
   }
 
   // If this is an imaginary literal, create the ImaginaryLiteral wrapper.
@@ -1997,9 +2104,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
   return Owned(Res);
 }
 
-Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L,
-                                              SourceLocation R, ExprArg Val) {
-  Expr *E = Val.takeAs<Expr>();
+ExprResult Sema::ActOnParenExpr(SourceLocation L,
+                                              SourceLocation R, Expr *E) {
   assert((E != 0) && "ActOnParenExpr() missing expr");
   return Owned(new (Context) ParenExpr(L, R, E));
 }
@@ -2083,7 +2189,7 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
 }
 
 /// \brief Build a sizeof or alignof expression given a type operand.
-Action::OwningExprResult
+ExprResult
 Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
                               SourceLocation OpLoc,
                               bool isSizeOf, SourceRange R) {
@@ -2104,7 +2210,7 @@ Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
 
 /// \brief Build a sizeof or alignof expression given an expression
 /// operand.
-Action::OwningExprResult
+ExprResult
 Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
                               bool isSizeOf, SourceRange R) {
   // Verify that the operand is valid.
@@ -2132,7 +2238,7 @@ Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
 /// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and
 /// the same for @c alignof and @c __alignof
 /// Note that the ArgRange is invalid if isType is false.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
                              void *TyOrEx, const SourceRange &ArgRange) {
   // If error parsing type, ignore.
@@ -2140,17 +2246,14 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
 
   if (isType) {
     TypeSourceInfo *TInfo;
-    (void) GetTypeFromParser(TyOrEx, &TInfo);
+    (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
     return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange);
   }
 
   Expr *ArgEx = (Expr *)TyOrEx;
-  Action::OwningExprResult Result
+  ExprResult Result
     = CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
 
-  if (Result.isInvalid())
-    DeleteExpr(ArgEx);
-
   return move(Result);
 }
 
@@ -2174,32 +2277,31 @@ QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {
 
 
 
-Action::OwningExprResult
+ExprResult
 Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
-                          tok::TokenKind Kind, ExprArg Input) {
-  UnaryOperator::Opcode Opc;
+                          tok::TokenKind Kind, Expr *Input) {
+  UnaryOperatorKind Opc;
   switch (Kind) {
   default: assert(0 && "Unknown unary op!");
-  case tok::plusplus:   Opc = UnaryOperator::PostInc; break;
-  case tok::minusminus: Opc = UnaryOperator::PostDec; break;
+  case tok::plusplus:   Opc = UO_PostInc; break;
+  case tok::minusminus: Opc = UO_PostDec; break;
   }
 
-  return BuildUnaryOp(S, OpLoc, Opc, move(Input));
+  return BuildUnaryOp(S, OpLoc, Opc, Input);
 }
 
-Action::OwningExprResult
-Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
-                              ExprArg Idx, SourceLocation RLoc) {
+ExprResult
+Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
+                              Expr *Idx, SourceLocation RLoc) {
   // Since this might be a postfix expression, get rid of ParenListExprs.
-  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+  if (Result.isInvalid()) return ExprError();
+  Base = Result.take();
 
-  Expr *LHSExp = static_cast<Expr*>(Base.get()),
-       *RHSExp = static_cast<Expr*>(Idx.get());
+  Expr *LHSExp = Base, *RHSExp = Idx;
 
   if (getLangOptions().CPlusPlus &&
       (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) {
-    Base.release();
-    Idx.release();
     return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
                                                   Context.DependentTy, RLoc));
   }
@@ -2209,18 +2311,18 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
        LHSExp->getType()->isEnumeralType() ||
        RHSExp->getType()->isRecordType() ||
        RHSExp->getType()->isEnumeralType())) {
-    return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move(Base),move(Idx));
+    return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx);
   }
 
-  return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc);
+  return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc);
 }
 
 
-Action::OwningExprResult
-Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
-                                     ExprArg Idx, SourceLocation RLoc) {
-  Expr *LHSExp = static_cast<Expr*>(Base.get());
-  Expr *RHSExp = static_cast<Expr*>(Idx.get());
+ExprResult
+Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
+                                     Expr *Idx, SourceLocation RLoc) {
+  Expr *LHSExp = Base;
+  Expr *RHSExp = Idx;
 
   // Perform default conversions.
   if (!LHSExp->getType()->getAs<VectorType>())
@@ -2274,7 +2376,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
     Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         LHSExp->getSourceRange();
     ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
-                      CastExpr::CK_ArrayToPointerDecay);
+                      CK_ArrayToPointerDecay);
     LHSTy = LHSExp->getType();
 
     BaseExpr = LHSExp;
@@ -2285,7 +2387,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
     Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
         RHSExp->getSourceRange();
     ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
-                      CastExpr::CK_ArrayToPointerDecay);
+                      CK_ArrayToPointerDecay);
     RHSTy = RHSExp->getType();
 
     BaseExpr = RHSExp;
@@ -2296,8 +2398,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
        << LHSExp->getSourceRange() << RHSExp->getSourceRange());
   }
   // C99 6.5.2.1p1
-  if (!(IndexExpr->getType()->isIntegerType() &&
-        IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
+  if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
     return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
                      << IndexExpr->getSourceRange());
 
@@ -2329,8 +2430,6 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
     return ExprError();
   }
 
-  Base.release();
-  Idx.release();
   return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
                                                 ResultType, RLoc));
 }
@@ -2377,7 +2476,7 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
     // We didn't get to the end of the string. This means the component names
     // didn't come from the same set *or* we encountered an illegal name.
     Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
-      << std::string(compStr,compStr+1) << SourceRange(CompLoc);
+      << llvm::StringRef(compStr, 1) << SourceRange(CompLoc);
     return QualType();
   }
 
@@ -2470,15 +2569,13 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
   return GDecl;
 }
 
-Sema::OwningExprResult
-Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
+ExprResult
+Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType,
                                bool IsArrow, SourceLocation OpLoc,
                                const CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
-                               DeclarationName Name, SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs) {
-  Expr *BaseExpr = Base.takeAs<Expr>();
-
   // Even in dependent contexts, try to diagnose base expressions with
   // obviously wrong types, e.g.:
   //
@@ -2493,24 +2590,24 @@ Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
     if (PT && (!getLangOptions().ObjC1 ||
                PT->getPointeeType()->isRecordType())) {
       assert(BaseExpr && "cannot happen with implicit member accesses");
-      Diag(NameLoc, diag::err_typecheck_member_reference_struct_union)
+      Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union)
         << BaseType << BaseExpr->getSourceRange();
       return ExprError();
     }
   }
 
-  assert(BaseType->isDependentType() || Name.isDependentName() ||
+  assert(BaseType->isDependentType() ||
+         NameInfo.getName().isDependentName() ||
          isDependentScopeSpecifier(SS));
 
   // Get the type being accessed in BaseType.  If this is an arrow, the BaseExpr
   // must have pointer type, and the accessed type is the pointee.
   return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
                                                    IsArrow, OpLoc,
-                 static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+                                                   SS.getScopeRep(),
                                                    SS.getRange(),
                                                    FirstQualifierInScope,
-                                                   Name, NameLoc,
-                                                   TemplateArgs));
+                                                   NameInfo, TemplateArgs));
 }
 
 /// We know that the given qualified member reference points only to
@@ -2562,12 +2659,15 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
       return false;
 
     // Note that we use the DC of the decl, not the underlying decl.
-    CXXRecordDecl *RecordD = cast<CXXRecordDecl>((*I)->getDeclContext());
-    while (RecordD->isAnonymousStructOrUnion())
-      RecordD = cast<CXXRecordDecl>(RecordD->getParent());
+    DeclContext *DC = (*I)->getDeclContext();
+    while (DC->isTransparentContext())
+      DC = DC->getParent();
 
+    if (!DC->isRecord())
+      continue;
+    
     llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord;
-    MemberRecord.insert(RecordD->getCanonicalDecl());
+    MemberRecord.insert(cast<CXXRecordDecl>(DC)->getCanonicalDecl());
 
     if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord))
       return false;
@@ -2646,24 +2746,21 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
   return false;
 }
 
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
                                SourceLocation OpLoc, bool IsArrow,
                                CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
-                               DeclarationName Name, SourceLocation NameLoc,
+                               const DeclarationNameInfo &NameInfo,
                                const TemplateArgumentListInfo *TemplateArgs) {
-  Expr *Base = BaseArg.takeAs<Expr>();
-
   if (BaseType->isDependentType() ||
       (SS.isSet() && isDependentScopeSpecifier(SS)))
-    return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType,
+    return ActOnDependentMemberExpr(Base, BaseType,
                                     IsArrow, OpLoc,
                                     SS, FirstQualifierInScope,
-                                    Name, NameLoc,
-                                    TemplateArgs);
+                                    NameInfo, TemplateArgs);
 
-  LookupResult R(*this, Name, NameLoc, LookupMemberName);
+  LookupResult R(*this, NameInfo, LookupMemberName);
 
   // Implicit member accesses.
   if (!Base) {
@@ -2676,9 +2773,9 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
 
   // Explicit member accesses.
   } else {
-    OwningExprResult Result =
+    ExprResult Result =
       LookupMemberExpr(R, Base, IsArrow, OpLoc,
-                       SS, /*ObjCImpDecl*/ DeclPtrTy(), TemplateArgs != 0);
+                       SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0);
 
     if (Result.isInvalid()) {
       Owned(Base);
@@ -2692,20 +2789,19 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
     BaseType = Base->getType();
   }
 
-  return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType,
+  return BuildMemberReferenceExpr(Base, BaseType,
                                   OpLoc, IsArrow, SS, FirstQualifierInScope,
                                   R, TemplateArgs);
 }
 
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
                                SourceLocation OpLoc, bool IsArrow,
                                const CXXScopeSpec &SS,
                                NamedDecl *FirstQualifierInScope,
                                LookupResult &R,
                          const TemplateArgumentListInfo *TemplateArgs,
                                bool SuppressQualifierCheck) {
-  Expr *BaseExpr = Base.takeAs<Expr>();
   QualType BaseType = BaseExprType;
   if (IsArrow) {
     assert(BaseType->isPointerType());
@@ -2713,10 +2809,10 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
   }
   R.setBaseObjectType(BaseType);
 
-  NestedNameSpecifier *Qualifier =
-    static_cast<NestedNameSpecifier*>(SS.getScopeRep());
-  DeclarationName MemberName = R.getLookupName();
-  SourceLocation MemberLoc = R.getNameLoc();
+  NestedNameSpecifier *Qualifier = SS.getScopeRep();
+  const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
+  DeclarationName MemberName = MemberNameInfo.getName();
+  SourceLocation MemberLoc = MemberNameInfo.getLoc();
 
   if (R.isAmbiguous())
     return ExprError();
@@ -2765,7 +2861,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
                                      BaseExpr, BaseExprType,
                                      IsArrow, OpLoc,
                                      Qualifier, SS.getRange(),
-                                     MemberName, MemberLoc,
+                                     MemberNameInfo,
                                      TemplateArgs, R.begin(), R.end());
 
     return Owned(MemExpr);
@@ -2787,7 +2883,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
   if (!BaseExpr) {
     // If this is not an instance member, convert to a non-member access.
     if (!MemberDecl->isCXXInstanceMember())
-      return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
+      return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl);
 
     SourceLocation Loc = R.getNameLoc();
     if (SS.getRange().isValid())
@@ -2838,34 +2934,36 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
     if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
       return ExprError();
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 FD, FoundDecl, MemberLoc, MemberType));
+                                 FD, FoundDecl, MemberNameInfo,
+                                 MemberType));
   }
 
   if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, Var);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 Var, FoundDecl, MemberLoc,
+                                 Var, FoundDecl, MemberNameInfo,
                                  Var->getType().getNonReferenceType()));
   }
 
   if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, MemberDecl);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 MemberFn, FoundDecl, MemberLoc,
+                                 MemberFn, FoundDecl, MemberNameInfo,
                                  MemberFn->getType()));
   }
 
   if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
     MarkDeclarationReferenced(MemberLoc, MemberDecl);
     return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
-                                 Enum, FoundDecl, MemberLoc, Enum->getType()));
+                                 Enum, FoundDecl, MemberNameInfo,
+                                 Enum->getType()));
   }
 
   Owned(BaseExpr);
 
   // We found something that we didn't expect. Complain.
   if (isa<TypeDecl>(MemberDecl))
-    Diag(MemberLoc,diag::err_typecheck_member_reference_type)
+    Diag(MemberLoc, diag::err_typecheck_member_reference_type)
       << MemberName << BaseType << int(IsArrow);
   else
     Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
@@ -2887,11 +2985,11 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
 ///
 /// The ObjCImpDecl bit is a gross hack that will need to be properly
 /// fixed for ObjC++.
-Sema::OwningExprResult
+ExprResult
 Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
                        bool &IsArrow, SourceLocation OpLoc,
                        CXXScopeSpec &SS,
-                       DeclPtrTy ObjCImpDecl, bool HasTemplateArgs) {
+                       Decl *ObjCImpDecl, bool HasTemplateArgs) {
   assert(BaseExpr && "no base expression");
 
   // Perform default conversions.
@@ -2921,8 +3019,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
           << QualType(Fun, 0)
           << FixItHint::CreateInsertion(Loc, "()");
 
-        OwningExprResult NewBase
-          = ActOnCallExpr(0, ExprArg(*this, BaseExpr), Loc,
+        ExprResult NewBase
+          = ActOnCallExpr(0, BaseExpr, Loc,
                           MultiExprArg(*this, 0, 0), 0, Loc);
         BaseExpr = 0;
         if (NewBase.isInvalid())
@@ -2952,7 +3050,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
     // is a reference to 'isa'.
     if (BaseType != Context.ObjCIdRedefinitionType) {
       BaseType = Context.ObjCIdRedefinitionType;
-      ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+      ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
     }
   }
 
@@ -2963,7 +3061,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
     // is a reference to 'sel_id'.
     if (BaseType != Context.ObjCSelRedefinitionType) {
       BaseType = Context.ObjCSelRedefinitionType;
-      ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+      ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
     }
   }
 
@@ -3022,7 +3120,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
   if (BaseType->isObjCClassType() &&
       BaseType != Context.ObjCClassRedefinitionType) {
     BaseType = Context.ObjCClassRedefinitionType;
-    ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+    ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
   }
 
   if (IsArrow) {
@@ -3129,12 +3227,11 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
             // down the context as argument to this routine. Ideally, this context
             // need be passed down in the AST node and somehow calculated from the
             // AST for a function decl.
-            Decl *ImplDecl = ObjCImpDecl.getAs<Decl>();
             if (ObjCImplementationDecl *IMPD =
-                dyn_cast<ObjCImplementationDecl>(ImplDecl))
+                dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
               ClassOfMethodDecl = IMPD->getClassInterface();
             else if (ObjCCategoryImplDecl* CatImplClass =
-                        dyn_cast<ObjCCategoryImplDecl>(ImplDecl))
+                        dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
               ClassOfMethodDecl = CatImplClass->getClassInterface();
           }
 
@@ -3235,12 +3332,12 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
 /// \param ObjCImpDecl the current ObjC @implementation decl;
 ///   this is an ugly hack around the fact that ObjC @implementations
 ///   aren't properly put in the context chain
-Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
+ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
                                                    SourceLocation OpLoc,
                                                    tok::TokenKind OpKind,
                                                    CXXScopeSpec &SS,
                                                    UnqualifiedId &Id,
-                                                   DeclPtrTy ObjCImpDecl,
+                                                   Decl *ObjCImpDecl,
                                                    bool HasTrailingLParen) {
   if (SS.isSet() && SS.isInvalid())
     return ExprError();
@@ -3248,12 +3345,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
   TemplateArgumentListInfo TemplateArgsBuffer;
 
   // Decompose the name into its component parts.
-  DeclarationName Name;
-  SourceLocation NameLoc;
+  DeclarationNameInfo NameInfo;
   const TemplateArgumentListInfo *TemplateArgs;
   DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
-                         Name, NameLoc, TemplateArgs);
+                         NameInfo, TemplateArgs);
 
+  DeclarationName Name = NameInfo.getName();
   bool IsArrow = (OpKind == tok::arrow);
 
   NamedDecl *FirstQualifierInScope
@@ -3261,19 +3358,18 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
                        static_cast<NestedNameSpecifier*>(SS.getScopeRep())));
 
   // This is a postfix expression, so get rid of ParenListExprs.
-  BaseArg = MaybeConvertParenListExprToParenExpr(S, move(BaseArg));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+  if (Result.isInvalid()) return ExprError();
+  Base = Result.take();
 
-  Expr *Base = BaseArg.takeAs<Expr>();
-  OwningExprResult Result(*this);
   if (Base->getType()->isDependentType() || Name.isDependentName() ||
       isDependentScopeSpecifier(SS)) {
-    Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
+    Result = ActOnDependentMemberExpr(Base, Base->getType(),
                                       IsArrow, OpLoc,
                                       SS, FirstQualifierInScope,
-                                      Name, NameLoc,
-                                      TemplateArgs);
+                                      NameInfo, TemplateArgs);
   } else {
-    LookupResult R(*this, Name, NameLoc, LookupMemberName);
+    LookupResult R(*this, NameInfo, LookupMemberName);
     Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
                               SS, ObjCImpDecl, TemplateArgs != 0);
 
@@ -3289,12 +3385,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
       // call now.
       if (!HasTrailingLParen &&
           Id.getKind() == UnqualifiedId::IK_DestructorName)
-        return DiagnoseDtorReference(NameLoc, move(Result));
+        return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
 
       return move(Result);
     }
 
-    Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(),
+    Result = BuildMemberReferenceExpr(Base, Base->getType(),
                                       OpLoc, IsArrow, SS, FirstQualifierInScope,
                                       R, TemplateArgs);
   }
@@ -3302,7 +3398,7 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
   return move(Result);
 }
 
-Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
                                                     FunctionDecl *FD,
                                                     ParmVarDecl *Param) {
   if (Param->hasUnparsedDefaultArg()) {
@@ -3324,7 +3420,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
       InstantiatingTemplate Inst(*this, CallLoc, Param, Innermost.first,
                                  Innermost.second);
 
-      OwningExprResult Result = SubstExpr(UninstExpr, ArgList);
+      ExprResult Result = SubstExpr(UninstExpr, ArgList);
       if (Result.isInvalid())
         return ExprError();
 
@@ -3338,7 +3434,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
 
       InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
       Result = InitSeq.Perform(*this, Entity, Kind,
-                               MultiExprArg(*this, (void**)&ResultE, 1));
+                               MultiExprArg(*this, &ResultE, 1));
       if (Result.isInvalid())
         return ExprError();
 
@@ -3457,7 +3553,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
       InitializedEntity Entity =
         Param? InitializedEntity::InitializeParameter(Param)
              : InitializedEntity::InitializeParameter(ProtoArgType);
-      OwningExprResult ArgE = PerformCopyInitialization(Entity,
+      ExprResult ArgE = PerformCopyInitialization(Entity,
                                                         SourceLocation(),
                                                         Owned(Arg));
       if (ArgE.isInvalid())
@@ -3467,7 +3563,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
     } else {
       ParmVarDecl *Param = FDecl->getParamDecl(i);
 
-      OwningExprResult ArgExpr =
+      ExprResult ArgExpr =
         BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
       if (ArgExpr.isInvalid())
         return true;
@@ -3492,18 +3588,18 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
 /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
 /// This provides the location of the left/right parens and a list of comma
 /// locations.
-Action::OwningExprResult
-Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
+ExprResult
+Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
                     MultiExprArg args,
                     SourceLocation *CommaLocs, SourceLocation RParenLoc) {
   unsigned NumArgs = args.size();
 
   // Since this might be a postfix expression, get rid of ParenListExprs.
-  fn = MaybeConvertParenListExprToParenExpr(S, move(fn));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
+  if (Result.isInvalid()) return ExprError();
+  Fn = Result.take();
 
-  Expr *Fn = fn.takeAs<Expr>();
-  Expr **Args = reinterpret_cast<Expr**>(args.release());
-  assert(Fn && "no function call expression");
+  Expr **Args = args.release();
 
   if (getLangOptions().CPlusPlus) {
     // If this is a pseudo-destructor expression, build the call immediately.
@@ -3515,9 +3611,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
                                     SourceRange(Args[0]->getLocStart(),
                                                 Args[NumArgs-1]->getLocEnd()));
 
-        for (unsigned I = 0; I != NumArgs; ++I)
-          Args[I]->Destroy(Context);
-
         NumArgs = 0;
       }
 
@@ -3572,27 +3665,27 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
 
     // Determine whether this is a call to a pointer-to-member function.
     if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) {
-      if (BO->getOpcode() == BinaryOperator::PtrMemD ||
-          BO->getOpcode() == BinaryOperator::PtrMemI) {
+      if (BO->getOpcode() == BO_PtrMemD ||
+          BO->getOpcode() == BO_PtrMemI) {
         if (const FunctionProtoType *FPT
                                 = BO->getType()->getAs<FunctionProtoType>()) {
           QualType ResultTy = FPT->getCallResultType(Context);
 
-          ExprOwningPtr<CXXMemberCallExpr>
-            TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args,
-                                                          NumArgs, ResultTy,
-                                                          RParenLoc));
+          CXXMemberCallExpr *TheCall
+            = new (Context) CXXMemberCallExpr(Context, BO, Args,
+                                              NumArgs, ResultTy,
+                                              RParenLoc);
 
           if (CheckCallReturnType(FPT->getResultType(),
                                   BO->getRHS()->getSourceRange().getBegin(),
-                                  TheCall.get(), 0))
+                                  TheCall, 0))
             return ExprError();
 
-          if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs,
+          if (ConvertArgumentsForCall(TheCall, BO, 0, FPT, Args, NumArgs,
                                       RParenLoc))
             return ExprError();
 
-          return Owned(MaybeBindToTemporary(TheCall.release()).release());
+          return MaybeBindToTemporary(TheCall);
         }
         return ExprError(Diag(Fn->getLocStart(),
                               diag::err_typecheck_call_not_function)
@@ -3625,7 +3718,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
 /// block-pointer type.
 ///
 /// \param NDecl the declaration being called, if available
-Sema::OwningExprResult
+ExprResult
 Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
                             SourceLocation LParenLoc,
                             Expr **Args, unsigned NumArgs,
@@ -3637,10 +3730,10 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
 
   // Make the call expr early, before semantic checks.  This guarantees cleanup
   // of arguments and function on error.
-  ExprOwningPtr<CallExpr> TheCall(this, new (Context) CallExpr(Context, Fn,
-                                                               Args, NumArgs,
-                                                               Context.BoolTy,
-                                                               RParenLoc));
+  CallExpr *TheCall = new (Context) CallExpr(Context, Fn,
+                                             Args, NumArgs,
+                                             Context.BoolTy,
+                                             RParenLoc);
 
   const FunctionType *FuncT;
   if (!Fn->getType()->isBlockPointerType()) {
@@ -3661,7 +3754,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
 
   // Check for a valid return type
   if (CheckCallReturnType(FuncT->getResultType(),
-                          Fn->getSourceRange().getBegin(), TheCall.get(),
+                          Fn->getSourceRange().getBegin(), TheCall,
                           FDecl))
     return ExprError();
 
@@ -3669,7 +3762,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
   TheCall->setType(FuncT->getCallResultType(Context));
 
   if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
-    if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
+    if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs,
                                 RParenLoc))
       return ExprError();
   } else {
@@ -3713,22 +3806,22 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
 
   // Do special checking on direct calls to functions.
   if (FDecl) {
-    if (CheckFunctionCall(FDecl, TheCall.get()))
+    if (CheckFunctionCall(FDecl, TheCall))
       return ExprError();
 
     if (unsigned BuiltinID = FDecl->getBuiltinID())
-      return CheckBuiltinFunctionCall(BuiltinID, TheCall.take());
+      return CheckBuiltinFunctionCall(BuiltinID, TheCall);
   } else if (NDecl) {
-    if (CheckBlockCall(NDecl, TheCall.get()))
+    if (CheckBlockCall(NDecl, TheCall))
       return ExprError();
   }
 
-  return MaybeBindToTemporary(TheCall.take());
+  return MaybeBindToTemporary(TheCall);
 }
 
-Action::OwningExprResult
-Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
-                           SourceLocation RParenLoc, ExprArg InitExpr) {
+ExprResult
+Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
+                           SourceLocation RParenLoc, Expr *InitExpr) {
   assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
   // FIXME: put back this assert when initializers are worked out.
   //assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
@@ -3738,14 +3831,13 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
   if (!TInfo)
     TInfo = Context.getTrivialTypeSourceInfo(literalType);
 
-  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr));
+  return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
-                               SourceLocation RParenLoc, ExprArg InitExpr) {
+                               SourceLocation RParenLoc, Expr *literalExpr) {
   QualType literalType = TInfo->getType();
-  Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
 
   if (literalType->isArrayType()) {
     if (literalType->isVariableArrayType())
@@ -3764,13 +3856,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
     = InitializationKind::CreateCast(SourceRange(LParenLoc, RParenLoc),
                                      /*IsCStyleCast=*/true);
   InitializationSequence InitSeq(*this, Entity, Kind, &literalExpr, 1);
-  OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
-                                   MultiExprArg(*this, (void**)&literalExpr, 1),
+  ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                       MultiExprArg(*this, &literalExpr, 1),
                                             &literalType);
   if (Result.isInvalid())
     return ExprError();
-  InitExpr.release();
-  literalExpr = static_cast<Expr*>(Result.get());
+  literalExpr = Result.get();
 
   bool isFileScope = getCurFunctionOrMethodDecl() == 0;
   if (isFileScope) { // 6.5.2.5p3
@@ -3778,17 +3869,15 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
       return ExprError();
   }
 
-  Result.release();
-
   return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
                                                  literalExpr, isFileScope));
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
                     SourceLocation RBraceLoc) {
   unsigned NumInit = initlist.size();
-  Expr **InitList = reinterpret_cast<Expr**>(initlist.release());
+  Expr **InitList = initlist.release();
 
   // Semantic analysis for initializers is done by ActOnDeclarator() and
   // CheckInitializer() - it requires knowledge of the object being intialized.
@@ -3799,45 +3888,45 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
   return Owned(E);
 }
 
-static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
+static CastKind getScalarCastKind(ASTContext &Context,
                                             QualType SrcTy, QualType DestTy) {
   if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
-    return CastExpr::CK_NoOp;
+    return CK_NoOp;
 
   if (SrcTy->hasPointerRepresentation()) {
     if (DestTy->hasPointerRepresentation())
       return DestTy->isObjCObjectPointerType() ?
-                CastExpr::CK_AnyPointerToObjCPointerCast :
-                CastExpr::CK_BitCast;
+                CK_AnyPointerToObjCPointerCast :
+                CK_BitCast;
     if (DestTy->isIntegerType())
-      return CastExpr::CK_PointerToIntegral;
+      return CK_PointerToIntegral;
   }
 
   if (SrcTy->isIntegerType()) {
     if (DestTy->isIntegerType())
-      return CastExpr::CK_IntegralCast;
+      return CK_IntegralCast;
     if (DestTy->hasPointerRepresentation())
-      return CastExpr::CK_IntegralToPointer;
+      return CK_IntegralToPointer;
     if (DestTy->isRealFloatingType())
-      return CastExpr::CK_IntegralToFloating;
+      return CK_IntegralToFloating;
   }
 
   if (SrcTy->isRealFloatingType()) {
     if (DestTy->isRealFloatingType())
-      return CastExpr::CK_FloatingCast;
+      return CK_FloatingCast;
     if (DestTy->isIntegerType())
-      return CastExpr::CK_FloatingToIntegral;
+      return CK_FloatingToIntegral;
   }
 
   // FIXME: Assert here.
   // assert(false && "Unhandled cast combination!");
-  return CastExpr::CK_Unknown;
+  return CK_Unknown;
 }
 
 /// CheckCastTypes - Check type constraints for casting between types.
 bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
-                          CastExpr::CastKind& Kind,
-                          CXXBaseSpecifierArray &BasePath,
+                          CastKind& Kind,
+                          CXXCastPath &BasePath,
                           bool FunctionalStyle) {
   if (getLangOptions().CPlusPlus)
     return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath,
@@ -3849,10 +3938,14 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
   // type needs to be scalar.
   if (castType->isVoidType()) {
     // Cast to void allows any expr type.
-    Kind = CastExpr::CK_ToVoid;
+    Kind = CK_ToVoid;
     return false;
   }
 
+  if (RequireCompleteType(TyR.getBegin(), castType,
+                          diag::err_typecheck_cast_to_incomplete))
+    return true;
+
   if (!castType->isScalarType() && !castType->isVectorType()) {
     if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
         (castType->isStructureType() || castType->isUnionType())) {
@@ -3860,7 +3953,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
       // FIXME: Check that the cast destination type is complete.
       Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar)
         << castType << castExpr->getSourceRange();
-      Kind = CastExpr::CK_NoOp;
+      Kind = CK_NoOp;
       return false;
     }
 
@@ -3880,7 +3973,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
       if (Field == FieldEnd)
         return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type)
           << castExpr->getType() << castExpr->getSourceRange();
-      Kind = CastExpr::CK_ToUnion;
+      Kind = CK_ToUnion;
       return false;
     }
 
@@ -3922,11 +4015,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
   }
 
   Kind = getScalarCastKind(Context, castExpr->getType(), castType);
+
+  if (Kind == CK_Unknown || Kind == CK_BitCast)
+    CheckCastAlign(castExpr, castType, TyR);
+
   return false;
 }
 
 bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
-                           CastExpr::CastKind &Kind) {
+                           CastKind &Kind) {
   assert(VectorTy->isVectorType() && "Not a vector type!");
 
   if (Ty->isVectorType() || Ty->isIntegerType()) {
@@ -3941,12 +4038,12 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
                 diag::err_invalid_conversion_between_vector_and_scalar)
       << VectorTy << Ty << R;
 
-  Kind = CastExpr::CK_BitCast;
+  Kind = CK_BitCast;
   return false;
 }
 
 bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
-                              CastExpr::CastKind &Kind) {
+                              CastKind &Kind) {
   assert(DestTy->isExtVectorType() && "Not an extended vector type!");
 
   QualType SrcTy = CastExpr->getType();
@@ -3957,7 +4054,7 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
     if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
       return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
         << DestTy << SrcTy << R;
-    Kind = CastExpr::CK_BitCast;
+    Kind = CK_BitCast;
     return false;
   }
 
@@ -3973,14 +4070,14 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
   ImpCastExprToType(CastExpr, DestElemTy,
                     getScalarCastKind(Context, SrcTy, DestElemTy));
 
-  Kind = CastExpr::CK_VectorSplat;
+  Kind = CK_VectorSplat;
   return false;
 }
 
-Action::OwningExprResult
-Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
-                    SourceLocation RParenLoc, ExprArg Op) {
-  assert((Ty != 0) && (Op.get() != 0) &&
+ExprResult
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty,
+                    SourceLocation RParenLoc, Expr *castExpr) {
+  assert((Ty != 0) && (castExpr != 0) &&
          "ActOnCastExpr(): missing type or expr");
 
   TypeSourceInfo *castTInfo;
@@ -3989,55 +4086,52 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
     castTInfo = Context.getTrivialTypeSourceInfo(castType);
 
   // If the Expr being casted is a ParenListExpr, handle it specially.
-  Expr *castExpr = (Expr *)Op.get();
   if (isa<ParenListExpr>(castExpr))
-    return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),
+    return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, castExpr,
                                     castTInfo);
 
-  return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op));
+  return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, castExpr);
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
-                          SourceLocation RParenLoc, ExprArg Op) {
-  Expr *castExpr = static_cast<Expr*>(Op.get());
-
-  CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-  CXXBaseSpecifierArray BasePath;
+                          SourceLocation RParenLoc, Expr *castExpr) {
+  CastKind Kind = CK_Unknown;
+  CXXCastPath BasePath;
   if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr,
                      Kind, BasePath))
     return ExprError();
 
-  Op.release();
-  return Owned(new (Context) CStyleCastExpr(
+  return Owned(CStyleCastExpr::Create(Context,
                                     Ty->getType().getNonLValueExprType(Context),
-                                            Kind, castExpr, BasePath, Ty,
-                                            LParenLoc, RParenLoc));
+                                      Kind, castExpr, &BasePath, Ty,
+                                      LParenLoc, RParenLoc));
 }
 
 /// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
 /// of comma binary operators.
-Action::OwningExprResult
-Sema::MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg EA) {
-  Expr *expr = EA.takeAs<Expr>();
+ExprResult
+Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *expr) {
   ParenListExpr *E = dyn_cast<ParenListExpr>(expr);
   if (!E)
     return Owned(expr);
 
-  OwningExprResult Result(*this, E->getExpr(0));
+  ExprResult Result(E->getExpr(0));
 
   for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i)
-    Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, move(Result),
-                        Owned(E->getExpr(i)));
+    Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(),
+                        E->getExpr(i));
 
-  return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), move(Result));
+  if (Result.isInvalid()) return ExprError();
+
+  return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
-                               SourceLocation RParenLoc, ExprArg Op,
+                               SourceLocation RParenLoc, Expr *Op,
                                TypeSourceInfo *TInfo) {
-  ParenListExpr *PE = (ParenListExpr *)Op.get();
+  ParenListExpr *PE = cast<ParenListExpr>(Op);
   QualType Ty = TInfo->getType();
   bool isAltiVecLiteral = false;
 
@@ -4065,24 +4159,24 @@ Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
 
     // FIXME: This means that pretty-printing the final AST will produce curly
     // braces instead of the original commas.
-    Op.release();
     InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc,
                                                  &initExprs[0],
                                                  initExprs.size(), RParenLoc);
     E->setType(Ty);
-    return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E));
+    return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, E);
   } else {
     // This is not an AltiVec-style cast, so turn the ParenListExpr into a
     // sequence of BinOp comma operators.
-    Op = MaybeConvertParenListExprToParenExpr(S, move(Op));
-    return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, move(Op));
+    ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Op);
+    if (Result.isInvalid()) return ExprError();
+    return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Result.take());
   }
 }
 
-Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
+ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
                                                   SourceLocation R,
                                                   MultiExprArg Val,
-                                                  TypeTy *TypeOfCast) {
+                                                  ParsedType TypeOfCast) {
   unsigned nexprs = Val.size();
   Expr **exprs = reinterpret_cast<Expr**>(Val.release());
   assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
@@ -4148,8 +4242,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
     if (!RHSTy->isVoidType())
       Diag(LHS->getLocStart(), diag::ext_typecheck_cond_one_void)
         << LHS->getSourceRange();
-    ImpCastExprToType(LHS, Context.VoidTy, CastExpr::CK_ToVoid);
-    ImpCastExprToType(RHS, Context.VoidTy, CastExpr::CK_ToVoid);
+    ImpCastExprToType(LHS, Context.VoidTy, CK_ToVoid);
+    ImpCastExprToType(RHS, Context.VoidTy, CK_ToVoid);
     return Context.VoidTy;
   }
   // C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
@@ -4157,12 +4251,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
   if ((LHSTy->isAnyPointerType() || LHSTy->isBlockPointerType()) &&
       RHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     // promote the null to a pointer.
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_Unknown);
+    ImpCastExprToType(RHS, LHSTy, CK_Unknown);
     return LHSTy;
   }
   if ((RHSTy->isAnyPointerType() || RHSTy->isBlockPointerType()) &&
       LHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_Unknown);
+    ImpCastExprToType(LHS, RHSTy, CK_Unknown);
     return RHSTy;
   }
 
@@ -4178,8 +4272,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
     if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
       if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
         QualType destType = Context.getPointerType(Context.VoidTy);
-        ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
-        ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+        ImpCastExprToType(LHS, destType, CK_BitCast);
+        ImpCastExprToType(RHS, destType, CK_BitCast);
         return destType;
       }
       Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
@@ -4203,13 +4297,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
       // reason, but this is what gcc does, and we do have to pick
       // to get a consistent AST.
       QualType incompatTy = Context.getPointerType(Context.VoidTy);
-      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
-      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The block pointer types are compatible.
-    ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
 
@@ -4226,9 +4320,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
         = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
       QualType destType = Context.getPointerType(destPointee);
       // Add qualifiers if necessary.
-      ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+      ImpCastExprToType(LHS, destType, CK_NoOp);
       // Promote to void*.
-      ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+      ImpCastExprToType(RHS, destType, CK_BitCast);
       return destType;
     }
     if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -4236,9 +4330,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
         = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
       QualType destType = Context.getPointerType(destPointee);
       // Add qualifiers if necessary.
-      ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+      ImpCastExprToType(RHS, destType, CK_NoOp);
       // Promote to void*.
-      ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+      ImpCastExprToType(LHS, destType, CK_BitCast);
       return destType;
     }
 
@@ -4254,8 +4348,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
       // reason, but this is what gcc does, and we do have to pick
       // to get a consistent AST.
       QualType incompatTy = Context.getPointerType(Context.VoidTy);
-      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
-      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The pointer types are compatible.
@@ -4265,8 +4359,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
     // type.
     // FIXME: Need to calculate the composite type.
     // FIXME: Need to add qualifiers
-    ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
 
@@ -4274,13 +4368,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
   if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
     Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
       << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_IntegralToPointer);
+    ImpCastExprToType(LHS, RHSTy, CK_IntegralToPointer);
     return RHSTy;
   }
   if (LHSTy->isPointerType() && RHSTy->isIntegerType()) {
     Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
       << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_IntegralToPointer);
+    ImpCastExprToType(RHS, LHSTy, CK_IntegralToPointer);
     return LHSTy;
   }
 
@@ -4302,34 +4396,34 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
   // redefinition type if an attempt is made to access its fields.
   if (LHSTy->isObjCClassType() &&
       (RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (RHSTy->isObjCClassType() &&
       (LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, RHSTy, CK_BitCast);
     return RHSTy;
   }
   // And the same for struct objc_object* / id
   if (LHSTy->isObjCIdType() &&
       (RHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (RHSTy->isObjCIdType() &&
       (LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, RHSTy, CK_BitCast);
     return RHSTy;
   }
   // And the same for struct objc_selector* / SEL
   if (Context.isObjCSelType(LHSTy) &&
       (RHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
-    ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, LHSTy, CK_BitCast);
     return LHSTy;
   }
   if (Context.isObjCSelType(RHSTy) &&
       (LHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
-    ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, RHSTy, CK_BitCast);
     return RHSTy;
   }
   // Check constraints for Objective-C object pointers types.
@@ -4378,13 +4472,13 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
       << LHSTy << RHSTy
       << LHS->getSourceRange() << RHS->getSourceRange();
       QualType incompatTy = Context.getObjCIdType();
-      ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
-      ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+      ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+      ImpCastExprToType(RHS, incompatTy, CK_BitCast);
       return incompatTy;
     }
     // The object pointer types are compatible.
-    ImpCastExprToType(LHS, compositeType, CastExpr::CK_BitCast);
-    ImpCastExprToType(RHS, compositeType, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, compositeType, CK_BitCast);
+    ImpCastExprToType(RHS, compositeType, CK_BitCast);
     return compositeType;
   }
   // Check Objective-C object pointer types and 'void *'
@@ -4395,9 +4489,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
     = Context.getQualifiedType(lhptee, rhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+    ImpCastExprToType(LHS, destType, CK_NoOp);
     // Promote to void*.
-    ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+    ImpCastExprToType(RHS, destType, CK_BitCast);
     return destType;
   }
   if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -4407,9 +4501,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
     = Context.getQualifiedType(rhptee, lhptee.getQualifiers());
     QualType destType = Context.getPointerType(destPointee);
     // Add qualifiers if necessary.
-    ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+    ImpCastExprToType(RHS, destType, CK_NoOp);
     // Promote to void*.
-    ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+    ImpCastExprToType(LHS, destType, CK_BitCast);
     return destType;
   }
   return QualType();
@@ -4417,30 +4511,27 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
 
 /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
 /// in the case of a the GNU conditional expr extension.
-Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
+ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
                                                   SourceLocation ColonLoc,
-                                                  ExprArg Cond, ExprArg LHS,
-                                                  ExprArg RHS) {
-  Expr *CondExpr = (Expr *) Cond.get();
-  Expr *LHSExpr = (Expr *) LHS.get(), *RHSExpr = (Expr *) RHS.get();
-
+                                                  Expr *CondExpr, Expr *LHSExpr,
+                                                  Expr *RHSExpr) {
   // If this is the gnu "x ?: y" extension, analyze the types as though the LHS
   // was the condition.
   bool isLHSNull = LHSExpr == 0;
-  if (isLHSNull)
-    LHSExpr = CondExpr;
+  Expr *SAVEExpr = 0;
+  if (isLHSNull) {
+    LHSExpr = SAVEExpr = CondExpr;
+  }
 
   QualType result = CheckConditionalOperands(CondExpr, LHSExpr,
                                              RHSExpr, QuestionLoc);
   if (result.isNull())
     return ExprError();
 
-  Cond.release();
-  LHS.release();
-  RHS.release();
   return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc,
-                                                 isLHSNull ? 0 : LHSExpr,
-                                                 ColonLoc, RHSExpr, result));
+                                                 LHSExpr, ColonLoc, 
+                                                 RHSExpr, SAVEExpr,
+                                                 result));
 }
 
 // CheckPointerTypesForAssignment - This is a very tricky routine (despite
@@ -4506,12 +4597,12 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
     // "unsigned char" on systems where "char" is unsigned.
     if (lhptee->isCharType())
       lhptee = Context.UnsignedCharTy;
-    else if (lhptee->isSignedIntegerType())
+    else if (lhptee->hasSignedIntegerRepresentation())
       lhptee = Context.getCorrespondingUnsignedType(lhptee);
 
     if (rhptee->isCharType())
       rhptee = Context.UnsignedCharTy;
-    else if (rhptee->isSignedIntegerType())
+    else if (rhptee->hasSignedIntegerRepresentation())
       rhptee = Context.getCorrespondingUnsignedType(rhptee);
 
     if (lhptee == rhptee) {
@@ -4668,13 +4759,18 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
   }
 
   if (lhsType->isVectorType() || rhsType->isVectorType()) {
-    // If we are allowing lax vector conversions, and LHS and RHS are both
-    // vectors, the total size only needs to be the same. This is a bitcast;
-    // no bits are changed but the result type is different.
-    if (getLangOptions().LaxVectorConversions &&
-        lhsType->isVectorType() && rhsType->isVectorType()) {
-      if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
+    if (lhsType->isVectorType() && rhsType->isVectorType()) {
+      // If we are allowing lax vector conversions, and LHS and RHS are both
+      // vectors, the total size only needs to be the same. This is a bitcast;
+      // no bits are changed but the result type is different.
+      if (getLangOptions().LaxVectorConversions &&
+         (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)))
         return IncompatibleVectors;
+
+      // Allow assignments of an AltiVec vector type to an equivalent GCC
+      // vector type and vice versa
+      if (Context.areCompatibleVectorTypes(lhsType, rhsType))
+        return Compatible;
     }
     return Incompatible;
   }
@@ -4832,14 +4928,14 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
       // 2) null pointer constant
       if (FromType->isPointerType())
         if (FromType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
-          ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_BitCast);
+          ImpCastExprToType(rExpr, it->getType(), CK_BitCast);
           InitField = *it;
           break;
         }
 
       if (rExpr->isNullPointerConstant(Context,
                                        Expr::NPC_ValueDependentIsNull)) {
-        ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_IntegralToPointer);
+        ImpCastExprToType(rExpr, it->getType(), CK_IntegralToPointer);
         InitField = *it;
         break;
       }
@@ -4883,14 +4979,14 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
        lhsType->isBlockPointerType())
       && rExpr->isNullPointerConstant(Context,
                                       Expr::NPC_ValueDependentIsNull)) {
-    ImpCastExprToType(rExpr, lhsType, CastExpr::CK_Unknown);
+    ImpCastExprToType(rExpr, lhsType, CK_Unknown);
     return Compatible;
   }
 
   // This check seems unnatural, however it is necessary to ensure the proper
   // conversion of functions/arrays. If the conversion were done for all
   // DeclExpr's (created by ActOnIdExpression), it would mess up the unary
-  // expressions that surpress this implicit conversion (&, sizeof).
+  // expressions that suppress this implicit conversion (&, sizeof).
   //
   // Suppress this for references: C++ 8.5.3p5.
   if (!lhsType->isReferenceType())
@@ -4907,7 +5003,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
   // does not have reference type.
   if (result != Incompatible && rExpr->getType() != lhsType)
     ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context),
-                      CastExpr::CK_Unknown);
+                      CK_Unknown);
   return result;
 }
 
@@ -4933,22 +5029,35 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
   // Handle the case of a vector & extvector type of the same size and element
   // type.  It would be nice if we only had one vector type someday.
   if (getLangOptions().LaxVectorConversions) {
-    // FIXME: Should we warn here?
     if (const VectorType *LV = lhsType->getAs<VectorType>()) {
-      if (const VectorType *RV = rhsType->getAs<VectorType>())
+      if (const VectorType *RV = rhsType->getAs<VectorType>()) {
         if (LV->getElementType() == RV->getElementType() &&
             LV->getNumElements() == RV->getNumElements()) {
           if (lhsType->isExtVectorType()) {
-            ImpCastExprToType(rex, lhsType, CastExpr::CK_BitCast);
+            ImpCastExprToType(rex, lhsType, CK_BitCast);
             return lhsType;
           } 
 
-          ImpCastExprToType(lex, rhsType, CastExpr::CK_BitCast);
+          ImpCastExprToType(lex, rhsType, CK_BitCast);
           return rhsType;
+        } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){
+          // If we are allowing lax vector conversions, and LHS and RHS are both
+          // vectors, the total size only needs to be the same. This is a
+          // bitcast; no bits are changed but the result type is different.
+          ImpCastExprToType(rex, lhsType, CK_BitCast);
+          return lhsType;
         }
+      }
     }
   }
 
+  // Handle the case of equivalent AltiVec and GCC vector types
+  if (lhsType->isVectorType() && rhsType->isVectorType() &&
+      Context.areCompatibleVectorTypes(lhsType, rhsType)) {
+    ImpCastExprToType(lex, rhsType, CK_BitCast);
+    return rhsType;
+  }
+
   // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
   // swap back (so that we don't reverse the inputs to a subtract, for instance.
   bool swapped = false;
@@ -4963,7 +5072,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
     QualType EltTy = LV->getElementType();
     if (EltTy->isIntegralType(Context) && rhsType->isIntegralType(Context)) {
       if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
-        ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast);
+        ImpCastExprToType(rex, lhsType, CK_IntegralCast);
         if (swapped) std::swap(rex, lex);
         return lhsType;
       }
@@ -4971,7 +5080,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
     if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
         rhsType->isRealFloatingType()) {
       if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
-        ImpCastExprToType(rex, lhsType, CastExpr::CK_FloatingCast);
+        ImpCastExprToType(rex, lhsType, CK_FloatingCast);
         if (swapped) std::swap(rex, lex);
         return lhsType;
       }
@@ -5008,7 +5117,8 @@ QualType Sema::CheckMultiplyDivideOperands(
 QualType Sema::CheckRemainderOperands(
   Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
   if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
-    if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
+    if (lex->getType()->hasIntegerRepresentation() && 
+        rex->getType()->hasIntegerRepresentation())
       return CheckVectorOperands(Loc, lex, rex);
     return InvalidOperands(Loc, lex, rex);
   }
@@ -5253,7 +5363,8 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
 QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
                                   bool isCompAssign) {
   // C99 6.5.7p2: Each of the operands shall have integer type.
-  if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
+  if (!lex->getType()->hasIntegerRepresentation() || 
+      !rex->getType()->hasIntegerRepresentation())
     return InvalidOperands(Loc, lex, rex);
 
   // Vector shifts promote their scalar inputs to vector type.
@@ -5269,7 +5380,7 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
       LHSTy = Context.getPromotedIntegerType(LHSTy);
   }
   if (!isCompAssign)
-    ImpCastExprToType(lex, LHSTy, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(lex, LHSTy, CK_IntegralCast);
 
   UsualUnaryConversions(rex);
 
@@ -5305,7 +5416,7 @@ static bool IsWithinTemplateSpecialization(Decl *D) {
 // C99 6.5.8, C++ [expr.rel]
 QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
                                     unsigned OpaqueOpc, bool isRelational) {
-  BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)OpaqueOpc;
+  BinaryOperatorKind Opc = (BinaryOperatorKind) OpaqueOpc;
 
   // Handle vector comparisons separately.
   if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
@@ -5334,19 +5445,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
             !IsWithinTemplateSpecialization(DRL->getDecl())) {
           DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always)
                               << 0 // self-
-                              << (Opc == BinaryOperator::EQ
-                                  || Opc == BinaryOperator::LE
-                                  || Opc == BinaryOperator::GE));
+                              << (Opc == BO_EQ
+                                  || Opc == BO_LE
+                                  || Opc == BO_GE));
         } else if (lType->isArrayType() && rType->isArrayType() &&
                    !DRL->getDecl()->getType()->isReferenceType() &&
                    !DRR->getDecl()->getType()->isReferenceType()) {
             // what is it always going to eval to?
             char always_evals_to;
             switch(Opc) {
-            case BinaryOperator::EQ: // e.g. array1 == array2
+            case BO_EQ: // e.g. array1 == array2
               always_evals_to = 0; // false
               break;
-            case BinaryOperator::NE: // e.g. array1 != array2
+            case BO_NE: // e.g. array1 != array2
               always_evals_to = 1; // true
               break;
             default:
@@ -5386,12 +5497,12 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
     if (literalString) {
       std::string resultComparison;
       switch (Opc) {
-      case BinaryOperator::LT: resultComparison = ") < 0"; break;
-      case BinaryOperator::GT: resultComparison = ") > 0"; break;
-      case BinaryOperator::LE: resultComparison = ") <= 0"; break;
-      case BinaryOperator::GE: resultComparison = ") >= 0"; break;
-      case BinaryOperator::EQ: resultComparison = ") == 0"; break;
-      case BinaryOperator::NE: resultComparison = ") != 0"; break;
+      case BO_LT: resultComparison = ") < 0"; break;
+      case BO_GT: resultComparison = ") > 0"; break;
+      case BO_LE: resultComparison = ") <= 0"; break;
+      case BO_GE: resultComparison = ") >= 0"; break;
+      case BO_EQ: resultComparison = ") == 0"; break;
+      case BO_NE: resultComparison = ") != 0"; break;
       default: assert(false && "Invalid comparison operator");
       }
 
@@ -5461,7 +5572,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
           if (isSFINAEContext())
             return QualType();
           
-          ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+          ImpCastExprToType(rex, lType, CK_BitCast);
           return ResultTy;
         }
       }
@@ -5487,8 +5598,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
           << lex->getSourceRange() << rex->getSourceRange();
       }
 
-      ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
-      ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+      ImpCastExprToType(lex, T, CK_BitCast);
+      ImpCastExprToType(rex, T, CK_BitCast);
       return ResultTy;
     }
     // C99 6.5.9p2 and C99 6.5.8p2
@@ -5513,7 +5624,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
     if (LCanPointeeTy != RCanPointeeTy)
-      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, lType, CK_BitCast);
     return ResultTy;
   }
 
@@ -5523,13 +5634,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
     if (RHSIsNull &&
         (lType->isPointerType() ||
          (!isRelational && lType->isMemberPointerType()))) {
-      ImpCastExprToType(rex, lType, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(rex, lType, 
+                        lType->isMemberPointerType()
+                          ? CK_NullToMemberPointer
+                          : CK_IntegralToPointer);
       return ResultTy;
     }
     if (LHSIsNull &&
         (rType->isPointerType() ||
          (!isRelational && rType->isMemberPointerType()))) {
-      ImpCastExprToType(lex, rType, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(lex, rType, 
+                        rType->isMemberPointerType()
+                          ? CK_NullToMemberPointer
+                          : CK_IntegralToPointer);
       return ResultTy;
     }
 
@@ -5560,8 +5677,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
           << lex->getSourceRange() << rex->getSourceRange();
       }
 
-      ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
-      ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+      ImpCastExprToType(lex, T, CK_BitCast);
+      ImpCastExprToType(rex, T, CK_BitCast);
       return ResultTy;
     }
 
@@ -5580,7 +5697,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
       Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
         << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
-    ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    ImpCastExprToType(rex, lType, CK_BitCast);
     return ResultTy;
   }
   // Allow block pointers to be compared with null pointer constants.
@@ -5595,7 +5712,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
         Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
           << lType << rType << lex->getSourceRange() << rex->getSourceRange();
     }
-    ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+    ImpCastExprToType(rex, lType, CK_BitCast);
     return ResultTy;
   }
 
@@ -5613,14 +5730,14 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
         Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
           << lType << rType << lex->getSourceRange() << rex->getSourceRange();
       }
-      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, lType, CK_BitCast);
       return ResultTy;
     }
     if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {
       if (!Context.areComparableObjCPointerTypes(lType, rType))
         Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
           << lType << rType << lex->getSourceRange() << rex->getSourceRange();
-      ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+      ImpCastExprToType(rex, lType, CK_BitCast);
       return ResultTy;
     }
   }
@@ -5648,21 +5765,21 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
     }
     
     if (lType->isIntegerType())
-      ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(lex, rType, CK_IntegralToPointer);
     else
-      ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(rex, lType, CK_IntegralToPointer);
     return ResultTy;
   }
   
   // Handle block pointers.
   if (!isRelational && RHSIsNull
       && lType->isBlockPointerType() && rType->isIntegerType()) {
-    ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+    ImpCastExprToType(rex, lType, CK_IntegralToPointer);
     return ResultTy;
   }
   if (!isRelational && LHSIsNull
       && lType->isIntegerType() && rType->isBlockPointerType()) {
-    ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+    ImpCastExprToType(lex, rType, CK_IntegralToPointer);
     return ResultTy;
   }
   return InvalidOperands(Loc, lex, rex);
@@ -5707,7 +5824,7 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
   // Return the type for the comparison, which is the same as vector type for
   // integer vectors, or an integer type of identical size and number of
   // elements for floating point vectors.
-  if (lType->isIntegerType())
+  if (lType->hasIntegerRepresentation())
     return lType;
 
   const VectorType *VTy = lType->getAs<VectorType>();
@@ -5724,8 +5841,13 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
 
 inline QualType Sema::CheckBitwiseOperands(
   Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
-  if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
-    return CheckVectorOperands(Loc, lex, rex);
+  if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+    if (lex->getType()->hasIntegerRepresentation() &&
+        rex->getType()->hasIntegerRepresentation())
+      return CheckVectorOperands(Loc, lex, rex);
+    
+    return InvalidOperands(Loc, lex, rex);
+  }
 
   QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
 
@@ -5741,18 +5863,21 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
   // bitwise one.  We do this when the LHS is a non-bool integer and the RHS
   // is a constant.
   if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() &&
-      rex->getType()->isIntegerType() && rex->isEvaluatable(Context) &&
-      // Don't warn if the RHS is a (constant folded) boolean expression like
-      // "sizeof(int) == 4".
-      !rex->isKnownToHaveBooleanValue() &&
+      rex->getType()->isIntegerType() && !rex->isValueDependent() &&
       // Don't warn in macros.
-      !Loc.isMacroID())
-    Diag(Loc, diag::warn_logical_instead_of_bitwise)
-     << rex->getSourceRange()
-      << (Opc == BinaryOperator::LAnd ? "&&" : "||")
-      << (Opc == BinaryOperator::LAnd ? "&" : "|");
-  
-  
+      !Loc.isMacroID()) {
+    // If the RHS can be constant folded, and if it constant folds to something
+    // that isn't 0 or 1 (which indicate a potential logical operation that
+    // happened to fold to true/false) then warn.
+    Expr::EvalResult Result;
+    if (rex->Evaluate(Result, Context) && !Result.HasSideEffects &&
+        Result.Val.getInt() != 0 && Result.Val.getInt() != 1) {
+      Diag(Loc, diag::warn_logical_instead_of_bitwise)
+       << rex->getSourceRange()
+        << (Opc == BO_LAnd ? "&&" : "||")
+        << (Opc == BO_LAnd ? "&" : "|");
+    }
+  }
   
   if (!Context.getLangOptions().CPlusPlus) {
     UsualUnaryConversions(lex);
@@ -5907,8 +6032,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
     if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
       RHSCheck = ICE->getSubExpr();
     if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
-      if ((UO->getOpcode() == UnaryOperator::Plus ||
-           UO->getOpcode() == UnaryOperator::Minus) &&
+      if ((UO->getOpcode() == UO_Plus ||
+           UO->getOpcode() == UO_Minus) &&
           Loc.isFileID() && UO->getOperatorLoc().isFileID() &&
           // Only if the two operators are exactly adjacent.
           Loc.getFileLocWithOffset(1) == UO->getOperatorLoc() &&
@@ -5917,7 +6042,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
           Loc.getFileLocWithOffset(2) != UO->getSubExpr()->getLocStart() &&
           UO->getSubExpr()->getLocStart().isFileID()) {
         Diag(Loc, diag::warn_not_compound_assign)
-          << (UO->getOpcode() == UnaryOperator::Plus ? "+" : "-")
+          << (UO->getOpcode() == UO_Plus ? "+" : "-")
           << SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
       }
     }
@@ -5938,7 +6063,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
   // only handles the pattern "*null = whatever", which is a very syntactic
   // check.
   if (UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS->IgnoreParenCasts()))
-    if (UO->getOpcode() == UnaryOperator::Deref &&
+    if (UO->getOpcode() == UO_Deref &&
         UO->getSubExpr()->IgnoreParenCasts()->
           isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) &&
         !UO->getType().isVolatileQualified()) {
@@ -6083,9 +6208,9 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
     UnaryOperator *UO = cast<UnaryOperator>(E);
 
     switch(UO->getOpcode()) {
-    case UnaryOperator::Real:
-    case UnaryOperator::Imag:
-    case UnaryOperator::Extension:
+    case UO_Real:
+    case UO_Imag:
+    case UO_Extension:
       return getPrimaryDecl(UO->getSubExpr());
     default:
       return 0;
@@ -6109,17 +6234,19 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
 /// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue.
 /// In C++, the operand might be an overloaded function name, in which case
 /// we allow the '&' but retain the overloaded-function type.
-QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
-  // Make sure to ignore parentheses in subsequent checks
-  op = op->IgnoreParens();
-
-  if (op->isTypeDependent())
+QualType Sema::CheckAddressOfOperand(Expr *OrigOp, SourceLocation OpLoc) {
+  if (OrigOp->isTypeDependent())
     return Context.DependentTy;
+  if (OrigOp->getType() == Context.OverloadTy)
+    return Context.OverloadTy;
+
+  // Make sure to ignore parentheses in subsequent checks
+  Expr *op = OrigOp->IgnoreParens();
 
   if (getLangOptions().C99) {
     // Implement C99-only parts of addressof rules.
     if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
-      if (uOp->getOpcode() == UnaryOperator::Deref)
+      if (uOp->getOpcode() == UO_Deref)
         // Per C99 6.5.3.2, the address of a deref always returns a valid result
         // (assuming the deref expression is valid).
         return uOp->getSubExpr()->getType();
@@ -6130,32 +6257,41 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
   NamedDecl *dcl = getPrimaryDecl(op);
   Expr::isLvalueResult lval = op->isLvalue(Context);
 
-  MemberExpr *ME = dyn_cast<MemberExpr>(op);
-  if (lval == Expr::LV_MemberFunction && ME &&
-      isa<CXXMethodDecl>(ME->getMemberDecl())) {
-    ValueDecl *dcl = cast<MemberExpr>(op)->getMemberDecl();
-    // &f where f is a member of the current object, or &o.f, or &p->f
-    // All these are not allowed, and we need to catch them before the dcl
-    // branch of the if, below.
-    Diag(OpLoc, diag::err_unqualified_pointer_member_function)
-        << dcl;
-    // FIXME: Improve this diagnostic and provide a fixit.
-
-    // Now recover by acting as if the function had been accessed qualified.
-    return Context.getMemberPointerType(op->getType(),
-                Context.getTypeDeclType(cast<RecordDecl>(dcl->getDeclContext()))
-                       .getTypePtr());
-  }
-  
   if (lval == Expr::LV_ClassTemporary) {
     Diag(OpLoc, isSFINAEContext()? diag::err_typecheck_addrof_class_temporary
                                  : diag::ext_typecheck_addrof_class_temporary)
       << op->getType() << op->getSourceRange();
     if (isSFINAEContext())
       return QualType();
-  } else if (isa<ObjCSelectorExpr>(op))
+  } else if (isa<ObjCSelectorExpr>(op)) {
     return Context.getPointerType(op->getType());
-  else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
+  } else if (lval == Expr::LV_MemberFunction) {
+    // If it's an instance method, make a member pointer.
+    // The expression must have exactly the form &A::foo.
+
+    // If the underlying expression isn't a decl ref, give up.
+    if (!isa<DeclRefExpr>(op)) {
+      Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
+        << OrigOp->getSourceRange();
+      return QualType();
+    }
+    DeclRefExpr *DRE = cast<DeclRefExpr>(op);
+    CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
+
+    // The id-expression was parenthesized.
+    if (OrigOp != DRE) {
+      Diag(OpLoc, diag::err_parens_pointer_member_function)
+        << OrigOp->getSourceRange();
+
+    // The method was named without a qualifier.
+    } else if (!DRE->getQualifier()) {
+      Diag(OpLoc, diag::err_unqualified_pointer_member_function)
+        << op->getSourceRange();
+    }
+
+    return Context.getMemberPointerType(op->getType(),
+              Context.getTypeDeclType(MD->getParent()).getTypePtr());
+  } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
     // C99 6.5.3.2p1
     // The operand must be either an l-value or a function designator
     if (!op->getType()->isFunctionType()) {
@@ -6183,13 +6319,14 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
     // FIXME: Can LHS ever be null here?
     if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull())
       return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc);
-  } else if (isa<UnresolvedLookupExpr>(op)) {
-    return Context.OverloadTy;
   } else if (dcl) { // C99 6.5.3.2p1
     // We have an lvalue with a decl. Make sure the decl is not declared
     // with the register storage-class specifier.
     if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
-      if (vd->getStorageClass() == VarDecl::Register) {
+      // in C++ it is not error to take address of a register
+      // variable (c++03 7.1.1P3)
+      if (vd->getStorageClass() == SC_Register &&
+          !getLangOptions().CPlusPlus) {
         Diag(OpLoc, diag::err_typecheck_address_of)
           << "register variable" << op->getSourceRange();
         return QualType();
@@ -6214,13 +6351,6 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
                 Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
         }
       }
-    } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(dcl)) {
-      // Okay: we can take the address of a function.
-      // As above.
-      if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() &&
-          MD->isInstance())
-        return Context.getMemberPointerType(op->getType(),
-              Context.getTypeDeclType(MD->getParent()).getTypePtr());
     } else if (!isa<FunctionDecl>(dcl))
       assert(0 && "Unknown/unexpected decl type");
   }
@@ -6233,6 +6363,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
   }
 
   // If the operand has type "type", the result has type "pointer to type".
+  if (op->getType()->isObjCObjectType())
+    return Context.getObjCObjectPointerType(op->getType());
   return Context.getPointerType(op->getType());
 }
 
@@ -6264,63 +6396,63 @@ QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
   return Result;
 }
 
-static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode(
+static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode(
   tok::TokenKind Kind) {
-  BinaryOperator::Opcode Opc;
+  BinaryOperatorKind Opc;
   switch (Kind) {
   default: assert(0 && "Unknown binop!");
-  case tok::periodstar:           Opc = BinaryOperator::PtrMemD; break;
-  case tok::arrowstar:            Opc = BinaryOperator::PtrMemI; break;
-  case tok::star:                 Opc = BinaryOperator::Mul; break;
-  case tok::slash:                Opc = BinaryOperator::Div; break;
-  case tok::percent:              Opc = BinaryOperator::Rem; break;
-  case tok::plus:                 Opc = BinaryOperator::Add; break;
-  case tok::minus:                Opc = BinaryOperator::Sub; break;
-  case tok::lessless:             Opc = BinaryOperator::Shl; break;
-  case tok::greatergreater:       Opc = BinaryOperator::Shr; break;
-  case tok::lessequal:            Opc = BinaryOperator::LE; break;
-  case tok::less:                 Opc = BinaryOperator::LT; break;
-  case tok::greaterequal:         Opc = BinaryOperator::GE; break;
-  case tok::greater:              Opc = BinaryOperator::GT; break;
-  case tok::exclaimequal:         Opc = BinaryOperator::NE; break;
-  case tok::equalequal:           Opc = BinaryOperator::EQ; break;
-  case tok::amp:                  Opc = BinaryOperator::And; break;
-  case tok::caret:                Opc = BinaryOperator::Xor; break;
-  case tok::pipe:                 Opc = BinaryOperator::Or; break;
-  case tok::ampamp:               Opc = BinaryOperator::LAnd; break;
-  case tok::pipepipe:             Opc = BinaryOperator::LOr; break;
-  case tok::equal:                Opc = BinaryOperator::Assign; break;
-  case tok::starequal:            Opc = BinaryOperator::MulAssign; break;
-  case tok::slashequal:           Opc = BinaryOperator::DivAssign; break;
-  case tok::percentequal:         Opc = BinaryOperator::RemAssign; break;
-  case tok::plusequal:            Opc = BinaryOperator::AddAssign; break;
-  case tok::minusequal:           Opc = BinaryOperator::SubAssign; break;
-  case tok::lesslessequal:        Opc = BinaryOperator::ShlAssign; break;
-  case tok::greatergreaterequal:  Opc = BinaryOperator::ShrAssign; break;
-  case tok::ampequal:             Opc = BinaryOperator::AndAssign; break;
-  case tok::caretequal:           Opc = BinaryOperator::XorAssign; break;
-  case tok::pipeequal:            Opc = BinaryOperator::OrAssign; break;
-  case tok::comma:                Opc = BinaryOperator::Comma; break;
+  case tok::periodstar:           Opc = BO_PtrMemD; break;
+  case tok::arrowstar:            Opc = BO_PtrMemI; break;
+  case tok::star:                 Opc = BO_Mul; break;
+  case tok::slash:                Opc = BO_Div; break;
+  case tok::percent:              Opc = BO_Rem; break;
+  case tok::plus:                 Opc = BO_Add; break;
+  case tok::minus:                Opc = BO_Sub; break;
+  case tok::lessless:             Opc = BO_Shl; break;
+  case tok::greatergreater:       Opc = BO_Shr; break;
+  case tok::lessequal:            Opc = BO_LE; break;
+  case tok::less:                 Opc = BO_LT; break;
+  case tok::greaterequal:         Opc = BO_GE; break;
+  case tok::greater:              Opc = BO_GT; break;
+  case tok::exclaimequal:         Opc = BO_NE; break;
+  case tok::equalequal:           Opc = BO_EQ; break;
+  case tok::amp:                  Opc = BO_And; break;
+  case tok::caret:                Opc = BO_Xor; break;
+  case tok::pipe:                 Opc = BO_Or; break;
+  case tok::ampamp:               Opc = BO_LAnd; break;
+  case tok::pipepipe:             Opc = BO_LOr; break;
+  case tok::equal:                Opc = BO_Assign; break;
+  case tok::starequal:            Opc = BO_MulAssign; break;
+  case tok::slashequal:           Opc = BO_DivAssign; break;
+  case tok::percentequal:         Opc = BO_RemAssign; break;
+  case tok::plusequal:            Opc = BO_AddAssign; break;
+  case tok::minusequal:           Opc = BO_SubAssign; break;
+  case tok::lesslessequal:        Opc = BO_ShlAssign; break;
+  case tok::greatergreaterequal:  Opc = BO_ShrAssign; break;
+  case tok::ampequal:             Opc = BO_AndAssign; break;
+  case tok::caretequal:           Opc = BO_XorAssign; break;
+  case tok::pipeequal:            Opc = BO_OrAssign; break;
+  case tok::comma:                Opc = BO_Comma; break;
   }
   return Opc;
 }
 
-static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
+static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
   tok::TokenKind Kind) {
-  UnaryOperator::Opcode Opc;
+  UnaryOperatorKind Opc;
   switch (Kind) {
   default: assert(0 && "Unknown unary op!");
-  case tok::plusplus:     Opc = UnaryOperator::PreInc; break;
-  case tok::minusminus:   Opc = UnaryOperator::PreDec; break;
-  case tok::amp:          Opc = UnaryOperator::AddrOf; break;
-  case tok::star:         Opc = UnaryOperator::Deref; break;
-  case tok::plus:         Opc = UnaryOperator::Plus; break;
-  case tok::minus:        Opc = UnaryOperator::Minus; break;
-  case tok::tilde:        Opc = UnaryOperator::Not; break;
-  case tok::exclaim:      Opc = UnaryOperator::LNot; break;
-  case tok::kw___real:    Opc = UnaryOperator::Real; break;
-  case tok::kw___imag:    Opc = UnaryOperator::Imag; break;
-  case tok::kw___extension__: Opc = UnaryOperator::Extension; break;
+  case tok::plusplus:     Opc = UO_PreInc; break;
+  case tok::minusminus:   Opc = UO_PreDec; break;
+  case tok::amp:          Opc = UO_AddrOf; break;
+  case tok::star:         Opc = UO_Deref; break;
+  case tok::plus:         Opc = UO_Plus; break;
+  case tok::minus:        Opc = UO_Minus; break;
+  case tok::tilde:        Opc = UO_Not; break;
+  case tok::exclaim:      Opc = UO_LNot; break;
+  case tok::kw___real:    Opc = UO_Real; break;
+  case tok::kw___imag:    Opc = UO_Imag; break;
+  case tok::kw___extension__: Opc = UO_Extension; break;
   }
   return Opc;
 }
@@ -6328,106 +6460,111 @@ static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
 /// CreateBuiltinBinOp - Creates a new built-in binary operation with
 /// operator @p Opc at location @c TokLoc. This routine only supports
 /// built-in operations; ActOnBinOp handles overloaded operators.
-Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
-                                                  unsigned Op,
-                                                  Expr *lhs, Expr *rhs) {
+ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
+                                    unsigned Op,
+                                    Expr *lhs, Expr *rhs) {
   QualType ResultTy;     // Result type of the binary operator.
-  BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op;
+  BinaryOperatorKind Opc = (BinaryOperatorKind) Op;
   // The following two variables are used for compound assignment operators
   QualType CompLHSTy;    // Type of LHS after promotions for computation
   QualType CompResultTy; // Type of computation result
 
   switch (Opc) {
-  case BinaryOperator::Assign:
+  case BO_Assign:
     ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType());
     break;
-  case BinaryOperator::PtrMemD:
-  case BinaryOperator::PtrMemI:
+  case BO_PtrMemD:
+  case BO_PtrMemI:
     ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc,
-                                            Opc == BinaryOperator::PtrMemI);
+                                            Opc == BO_PtrMemI);
     break;
-  case BinaryOperator::Mul:
-  case BinaryOperator::Div:
+  case BO_Mul:
+  case BO_Div:
     ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false,
-                                           Opc == BinaryOperator::Div);
+                                           Opc == BO_Div);
     break;
-  case BinaryOperator::Rem:
+  case BO_Rem:
     ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::Add:
+  case BO_Add:
     ResultTy = CheckAdditionOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::Sub:
+  case BO_Sub:
     ResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::Shl:
-  case BinaryOperator::Shr:
+  case BO_Shl:
+  case BO_Shr:
     ResultTy = CheckShiftOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::LE:
-  case BinaryOperator::LT:
-  case BinaryOperator::GE:
-  case BinaryOperator::GT:
+  case BO_LE:
+  case BO_LT:
+  case BO_GE:
+  case BO_GT:
     ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, true);
     break;
-  case BinaryOperator::EQ:
-  case BinaryOperator::NE:
+  case BO_EQ:
+  case BO_NE:
     ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, false);
     break;
-  case BinaryOperator::And:
-  case BinaryOperator::Xor:
-  case BinaryOperator::Or:
+  case BO_And:
+  case BO_Xor:
+  case BO_Or:
     ResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc);
     break;
-  case BinaryOperator::LAnd:
-  case BinaryOperator::LOr:
+  case BO_LAnd:
+  case BO_LOr:
     ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc, Opc);
     break;
-  case BinaryOperator::MulAssign:
-  case BinaryOperator::DivAssign:
+  case BO_MulAssign:
+  case BO_DivAssign:
     CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true,
-                                              Opc == BinaryOperator::DivAssign);
+                                              Opc == BO_DivAssign);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::RemAssign:
+  case BO_RemAssign:
     CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::AddAssign:
+  case BO_AddAssign:
     CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy);
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::SubAssign:
+  case BO_SubAssign:
     CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy);
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::ShlAssign:
-  case BinaryOperator::ShrAssign:
+  case BO_ShlAssign:
+  case BO_ShrAssign:
     CompResultTy = CheckShiftOperands(lhs, rhs, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::AndAssign:
-  case BinaryOperator::XorAssign:
-  case BinaryOperator::OrAssign:
+  case BO_AndAssign:
+  case BO_XorAssign:
+  case BO_OrAssign:
     CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
     CompLHSTy = CompResultTy;
     if (!CompResultTy.isNull())
       ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
     break;
-  case BinaryOperator::Comma:
+  case BO_Comma:
     ResultTy = CheckCommaOperands(lhs, rhs, OpLoc);
     break;
   }
   if (ResultTy.isNull())
     return ExprError();
+  if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
+    if (Opc >= BO_Assign && Opc <= BO_OrAssign) 
+          Diag(OpLoc, diag::err_assignment_requires_nonfragile_object)
+                << ResultTy;
+  }
   if (CompResultTy.isNull())
     return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc));
   else
@@ -6479,7 +6616,7 @@ static void SuggestParentheses(Sema &Self, SourceLocation Loc,
 /// operators are mixed in a way that suggests that the programmer forgot that
 /// comparison operators have higher precedence. The most typical example of
 /// such code is "flags & 0x0020 != 0", which is equivalent to "flags & 1".
-static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
                                       SourceLocation OpLoc,Expr *lhs,Expr *rhs){
   typedef BinaryOperator BinOp;
   BinOp::Opcode lhsopc = static_cast<BinOp::Opcode>(-1),
@@ -6526,19 +6663,17 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
 /// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
 /// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3".
 /// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does.
-static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
                                     SourceLocation OpLoc, Expr *lhs, Expr *rhs){
   if (BinaryOperator::isBitwiseOp(Opc))
     DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs);
 }
 
 // Binary Operators.  'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
-                                          tok::TokenKind Kind,
-                                          ExprArg LHS, ExprArg RHS) {
-  BinaryOperator::Opcode Opc = ConvertTokenKindToBinaryOpcode(Kind);
-  Expr *lhs = LHS.takeAs<Expr>(), *rhs = RHS.takeAs<Expr>();
-
+ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
+                            tok::TokenKind Kind,
+                            Expr *lhs, Expr *rhs) {
+  BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind);
   assert((lhs != 0) && "ActOnBinOp(): missing left expression");
   assert((rhs != 0) && "ActOnBinOp(): missing right expression");
 
@@ -6548,9 +6683,9 @@ Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
   return BuildBinOp(S, TokLoc, Opc, lhs, rhs);
 }
 
-Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
-                                          BinaryOperator::Opcode Opc,
-                                          Expr *lhs, Expr *rhs) {
+ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
+                            BinaryOperatorKind Opc,
+                            Expr *lhs, Expr *rhs) {
   if (getLangOptions().CPlusPlus &&
       (lhs->getType()->isOverloadableType() ||
        rhs->getType()->isOverloadableType())) {
@@ -6573,38 +6708,32 @@ Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
   return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs);
 }
 
-Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
+ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
                                                     unsigned OpcIn,
-                                                    ExprArg InputArg) {
-  UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
+                                                    Expr *Input) {
+  UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn);
 
-  // FIXME: Input is modified below, but InputArg is not updated appropriately.
-  Expr *Input = (Expr *)InputArg.get();
   QualType resultType;
   switch (Opc) {
-  case UnaryOperator::OffsetOf:
-    assert(false && "Invalid unary operator");
-    break;
-      
-  case UnaryOperator::PreInc:
-  case UnaryOperator::PreDec:
-  case UnaryOperator::PostInc:
-  case UnaryOperator::PostDec:
+  case UO_PreInc:
+  case UO_PreDec:
+  case UO_PostInc:
+  case UO_PostDec:
     resultType = CheckIncrementDecrementOperand(Input, OpLoc,
-                                                Opc == UnaryOperator::PreInc ||
-                                                Opc == UnaryOperator::PostInc,
-                                                Opc == UnaryOperator::PreInc ||
-                                                Opc == UnaryOperator::PreDec);
+                                                Opc == UO_PreInc ||
+                                                Opc == UO_PostInc,
+                                                Opc == UO_PreInc ||
+                                                Opc == UO_PreDec);
     break;
-  case UnaryOperator::AddrOf:
+  case UO_AddrOf:
     resultType = CheckAddressOfOperand(Input, OpLoc);
     break;
-  case UnaryOperator::Deref:
+  case UO_Deref:
     DefaultFunctionArrayLvalueConversion(Input);
     resultType = CheckIndirectionOperand(Input, OpLoc);
     break;
-  case UnaryOperator::Plus:
-  case UnaryOperator::Minus:
+  case UO_Plus:
+  case UO_Minus:
     UsualUnaryConversions(Input);
     resultType = Input->getType();
     if (resultType->isDependentType())
@@ -6616,13 +6745,13 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
              resultType->isEnumeralType())
       break;
     else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6
-             Opc == UnaryOperator::Plus &&
+             Opc == UO_Plus &&
              resultType->isPointerType())
       break;
 
     return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
       << resultType << Input->getSourceRange());
-  case UnaryOperator::Not: // bitwise complement
+  case UO_Not: // bitwise complement
     UsualUnaryConversions(Input);
     resultType = Input->getType();
     if (resultType->isDependentType())
@@ -6632,11 +6761,11 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
       // C99 does not support '~' for complex conjugation.
       Diag(OpLoc, diag::ext_integer_complement_complex)
         << resultType << Input->getSourceRange();
-    else if (!resultType->isIntegerType())
+    else if (!resultType->hasIntegerRepresentation())
       return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
         << resultType << Input->getSourceRange());
     break;
-  case UnaryOperator::LNot: // logical negation
+  case UO_LNot: // logical negation
     // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
     DefaultFunctionArrayLvalueConversion(Input);
     resultType = Input->getType();
@@ -6649,27 +6778,25 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
     // In C++, it's bool. C++ 5.3.1p8
     resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy;
     break;
-  case UnaryOperator::Real:
-  case UnaryOperator::Imag:
-    resultType = CheckRealImagOperand(Input, OpLoc, Opc == UnaryOperator::Real);
+  case UO_Real:
+  case UO_Imag:
+    resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real);
     break;
-  case UnaryOperator::Extension:
+  case UO_Extension:
     resultType = Input->getType();
     break;
   }
   if (resultType.isNull())
     return ExprError();
 
-  InputArg.release();
   return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc));
 }
 
-Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
-                                            UnaryOperator::Opcode Opc,
-                                            ExprArg input) {
-  Expr *Input = (Expr*)input.get();
+ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+                              UnaryOperatorKind Opc,
+                              Expr *Input) {
   if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() &&
-      Opc != UnaryOperator::Extension) {
+      UnaryOperator::getOverloadedOperator(Opc) != OO_None) {
     // Find all of the overloaded operators visible from this
     // point. We perform both an operator-name lookup from the local
     // scope and an argument-dependent lookup based on the types of
@@ -6680,24 +6807,24 @@ Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
       LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
                                    Functions);
 
-    return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
+    return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input);
   }
 
-  return CreateBuiltinUnaryOp(OpLoc, Opc, move(input));
+  return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
 }
 
 // Unary Operators.  'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
-                                            tok::TokenKind Op, ExprArg input) {
-  return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), move(input));
+ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+                                            tok::TokenKind Op, Expr *Input) {
+  return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), Input);
 }
 
 /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
+ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
                                             SourceLocation LabLoc,
                                             IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
 
   // If we haven't seen this label yet, create a forward reference. It
   // will be validated and/or cleaned up in ActOnFinishFunctionBody.
@@ -6709,10 +6836,9 @@ Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
                                        Context.getPointerType(Context.VoidTy)));
 }
 
-Sema::OwningExprResult
-Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
+ExprResult
+Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
                     SourceLocation RPLoc) { // "({..})"
-  Stmt *SubStmt = static_cast<Stmt*>(substmt.get());
   assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
   CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
 
@@ -6742,11 +6868,10 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
   // FIXME: Check that expression type is complete/non-abstract; statement
   // expressions are not lvalues.
 
-  substmt.release();
   return Owned(new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc));
 }
 
-Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
+ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
                                                   TypeSourceInfo *TInfo,
                                                   OffsetOfComponent *CompPtr,
                                                   unsigned NumComponents,
@@ -6865,22 +6990,27 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
       Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
       return ExprError();
     }
-      
+
+    RecordDecl *Parent = MemberDecl->getParent();
+    bool AnonStructUnion = Parent->isAnonymousStructOrUnion();
+    if (AnonStructUnion) {
+      do {
+        Parent = cast<RecordDecl>(Parent->getParent());
+      } while (Parent->isAnonymousStructOrUnion());
+    }
+
     // If the member was found in a base class, introduce OffsetOfNodes for
     // the base class indirections.
     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
                        /*DetectVirtual=*/false);
-    if (IsDerivedFrom(CurrentType, 
-                      Context.getTypeDeclType(MemberDecl->getParent()), 
-                      Paths)) {
+    if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) {
       CXXBasePath &Path = Paths.front();
       for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end();
            B != BEnd; ++B)
         Comps.push_back(OffsetOfNode(B->Base));
     }
-    
-    if (cast<RecordDecl>(MemberDecl->getDeclContext())->
-                                                isAnonymousStructOrUnion()) {
+
+    if (AnonStructUnion) {
       llvm::SmallVector<FieldDecl*, 4> Path;
       BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
       unsigned n = Path.size();
@@ -6897,10 +7027,10 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
                                     Exprs.data(), Exprs.size(), RParenLoc));  
 }
 
-Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
+ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
                                                   SourceLocation BuiltinLoc,
                                                   SourceLocation TypeLoc,
-                                                  TypeTy *argty,
+                                                  ParsedType argty,
                                                   OffsetOfComponent *CompPtr,
                                                   unsigned NumComponents,
                                                   SourceLocation RPLoc) {
@@ -6910,151 +7040,32 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
   if (ArgTy.isNull())
     return ExprError();
 
-  if (getLangOptions().CPlusPlus) {
-    if (!ArgTInfo)
-      ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
-    
-    return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, 
-                                RPLoc);
-  }
-  
-  // FIXME: The code below is marked for death, once we have proper CodeGen
-  // support for non-constant OffsetOf expressions.
-  
-  bool Dependent = ArgTy->isDependentType();
-  
-  // We must have at least one component that refers to the type, and the first
-  // one is known to be a field designator.  Verify that the ArgTy represents
-  // a struct/union/class.
-  if (!Dependent && !ArgTy->isRecordType())
-    return ExprError(Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy);
-  
-  // FIXME: Type must be complete per C99 7.17p3 because a declaring a variable
-  // with an incomplete type would be illegal.
-  
-  // Otherwise, create a null pointer as the base, and iteratively process
-  // the offsetof designators.
-  QualType ArgTyPtr = Context.getPointerType(ArgTy);
-  Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr);
-  Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref,
-                                    ArgTy, SourceLocation());
-  
-  // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
-  // GCC extension, diagnose them.
-  // FIXME: This diagnostic isn't actually visible because the location is in
-  // a system header!
-  if (NumComponents != 1)
-    Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator)
-    << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd);
-  
-  if (!Dependent) {
-    bool DidWarnAboutNonPOD = false;
-    
-    if (RequireCompleteType(TypeLoc, Res->getType(),
-                            diag::err_offsetof_incomplete_type))
-      return ExprError();
-    
-    // FIXME: Dependent case loses a lot of information here. And probably
-    // leaks like a sieve.
-    for (unsigned i = 0; i != NumComponents; ++i) {
-      const OffsetOfComponent &OC = CompPtr[i];
-      if (OC.isBrackets) {
-        // Offset of an array sub-field.  TODO: Should we allow vector elements?
-        const ArrayType *AT = Context.getAsArrayType(Res->getType());
-        if (!AT) {
-          Res->Destroy(Context);
-          return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type)
-                           << Res->getType());
-        }
-        
-        // FIXME: C++: Verify that operator[] isn't overloaded.
-        
-        // Promote the array so it looks more like a normal array subscript
-        // expression.
-        DefaultFunctionArrayLvalueConversion(Res);
-        
-        // C99 6.5.2.1p1
-        Expr *Idx = static_cast<Expr*>(OC.U.E);
-        // FIXME: Leaks Res
-        if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())
-          return ExprError(Diag(Idx->getLocStart(),
-                                diag::err_typecheck_subscript_not_integer)
-                           << Idx->getSourceRange());
-        
-        Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(),
-                                               OC.LocEnd);
-        continue;
-      }
-      
-      const RecordType *RC = Res->getType()->getAs<RecordType>();
-      if (!RC) {
-        Res->Destroy(Context);
-        return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
-                         << Res->getType());
-      }
-      
-      // Get the decl corresponding to this.
-      RecordDecl *RD = RC->getDecl();
-      if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
-        if (!CRD->isPOD() && !DidWarnAboutNonPOD &&
-            DiagRuntimeBehavior(BuiltinLoc,
-                                PDiag(diag::warn_offsetof_non_pod_type)
-                                << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
-                                << Res->getType()))
-          DidWarnAboutNonPOD = true;
-      }
-      
-      LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
-      LookupQualifiedName(R, RD);
-      
-      FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
-      // FIXME: Leaks Res
-      if (!MemberDecl)
-        return ExprError(Diag(BuiltinLoc, diag::err_no_member)
-                         << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
-      
-      // C99 7.17p3:
-      //   (If the specified member is a bit-field, the behavior is undefined.)
-      //
-      // We diagnose this as an error.
-      if (MemberDecl->getBitWidth()) {
-        Diag(OC.LocEnd, diag::err_offsetof_bitfield)
-          << MemberDecl->getDeclName()
-          << SourceRange(BuiltinLoc, RPLoc);
-        Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
-        return ExprError();
-      }
-      
-      // FIXME: C++: Verify that MemberDecl isn't a static field.
-      // FIXME: Verify that MemberDecl isn't a bitfield.
-      if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {
-        Res = BuildAnonymousStructUnionMemberReference(
-                                                       OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
-      } else {
-        PerformObjectMemberConversion(Res, /*Qualifier=*/0,
-                                      *R.begin(), MemberDecl);
-        // MemberDecl->getType() doesn't get the right qualifiers, but it
-        // doesn't matter here.
-        Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,
-                                       MemberDecl->getType().getNonReferenceType());
-      }
-    }
-  }
-  
-  return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf,
-                                           Context.getSizeType(), BuiltinLoc));
+  if (!ArgTInfo)
+    ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
+
+  return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents, 
+                              RPLoc);
 }
 
 
-Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
-                                                      TypeTy *arg1,TypeTy *arg2,
+ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                                      ParsedType arg1,ParsedType arg2,
                                                       SourceLocation RPLoc) {
-  // FIXME: Preserve type source info.
-  QualType argT1 = GetTypeFromParser(arg1);
-  QualType argT2 = GetTypeFromParser(arg2);
+  TypeSourceInfo *argTInfo1;
+  QualType argT1 = GetTypeFromParser(arg1, &argTInfo1);
+  TypeSourceInfo *argTInfo2;
+  QualType argT2 = GetTypeFromParser(arg2, &argTInfo2);
 
   assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
 
+  return BuildTypesCompatibleExpr(BuiltinLoc, argTInfo1, argTInfo2, RPLoc);
+}
+
+ExprResult
+Sema::BuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                               TypeSourceInfo *argTInfo1,
+                               TypeSourceInfo *argTInfo2,
+                               SourceLocation RPLoc) {
   if (getLangOptions().CPlusPlus) {
     Diag(BuiltinLoc, diag::err_types_compatible_p_in_cplusplus)
       << SourceRange(BuiltinLoc, RPLoc);
@@ -7062,17 +7073,14 @@ Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
   }
 
   return Owned(new (Context) TypesCompatibleExpr(Context.IntTy, BuiltinLoc,
-                                                 argT1, argT2, RPLoc));
+                                                 argTInfo1, argTInfo2, RPLoc));
 }
 
-Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
-                                             ExprArg cond,
-                                             ExprArg expr1, ExprArg expr2,
-                                             SourceLocation RPLoc) {
-  Expr *CondExpr = static_cast<Expr*>(cond.get());
-  Expr *LHSExpr = static_cast<Expr*>(expr1.get());
-  Expr *RHSExpr = static_cast<Expr*>(expr2.get());
 
+ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
+                                             Expr *CondExpr,
+                                             Expr *LHSExpr, Expr *RHSExpr,
+                                             SourceLocation RPLoc) {
   assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
 
   QualType resType;
@@ -7095,7 +7103,6 @@ Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
                                              : RHSExpr->isValueDependent();
   }
 
-  cond.release(); expr1.release(); expr2.release();
   return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
                                         resType, RPLoc,
                                         resType->isDependentType(),
@@ -7232,8 +7239,8 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
 
 /// ActOnBlockStmtExpr - This is called when the body of a block statement
 /// literal was successfully completed.  ^(int x){...}
-Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
-                                                StmtArg body, Scope *CurScope) {
+ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
+                                                Stmt *Body, Scope *CurScope) {
   // If blocks are disabled, emit an error.
   if (!LangOpts.Blocks)
     Diag(CaretLoc, diag::err_blocks_disable);
@@ -7295,10 +7302,10 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
   BlockTy = Context.getBlockPointerType(BlockTy);
 
   // If needed, diagnose invalid gotos and switches in the block.
-  if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
-    DiagnoseInvalidJumps(static_cast<CompoundStmt*>(body.get()));
+  if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+    DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
 
-  BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+  BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
 
   bool Good = true;
   // Check goto/label use.
@@ -7320,22 +7327,29 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
     return ExprError();
   }
 
+  BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
+                                              BSI->hasBlockDeclRefExprs);
+
   // Issue any analysis-based warnings.
   const sema::AnalysisBasedWarnings::Policy &WP =
     AnalysisWarnings.getDefaultPolicy();
-  AnalysisWarnings.IssueWarnings(WP, BSI->TheDecl, BlockTy);
+  AnalysisWarnings.IssueWarnings(WP, Result);
 
-  Expr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
-                                         BSI->hasBlockDeclRefExprs);
   PopFunctionOrBlockScope();
   return Owned(Result);
 }
 
-Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
-                                        ExprArg expr, TypeTy *type,
+ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
+                                        Expr *expr, ParsedType type,
                                         SourceLocation RPLoc) {
-  QualType T = GetTypeFromParser(type);
-  Expr *E = static_cast<Expr*>(expr.get());
+  TypeSourceInfo *TInfo;
+  QualType T = GetTypeFromParser(type, &TInfo);
+  return BuildVAArgExpr(BuiltinLoc, expr, TInfo, RPLoc);
+}
+
+ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
+                                            Expr *E, TypeSourceInfo *TInfo,
+                                            SourceLocation RPLoc) {
   Expr *OrigExpr = E;
 
   InitBuiltinVaListType();
@@ -7367,13 +7381,11 @@ Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
   // FIXME: Check that type is complete/non-abstract
   // FIXME: Warn if a non-POD type is passed in.
 
-  expr.release();
-  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, 
-                                       T.getNonLValueExprType(Context),
-                                       RPLoc));
+  QualType T = TInfo->getType().getNonLValueExprType(Context);
+  return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
 }
 
-Sema::OwningExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
   // The type of __null will be int or long, depending on the size of
   // pointers on the target.
   QualType Ty;
@@ -7647,8 +7659,10 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
     unsigned TypeQuals;
     if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) {
-        if (!Constructor->isUsed(false))
-          DefineImplicitDefaultConstructor(Loc, Constructor);
+      if (Constructor->getParent()->hasTrivialConstructor())
+        return;
+      if (!Constructor->isUsed(false))
+        DefineImplicitDefaultConstructor(Loc, Constructor);
     } else if (Constructor->isImplicit() &&
                Constructor->isCopyConstructor(TypeQuals)) {
       if (!Constructor->isUsed(false))
@@ -7696,13 +7710,20 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
           PendingLocalImplicitInstantiations.push_back(std::make_pair(Function,
                                                                       Loc));
         else
-          PendingImplicitInstantiations.push_back(std::make_pair(Function,
-                                                                 Loc));
+          PendingInstantiations.push_back(std::make_pair(Function, Loc));
+      }
+    } else // Walk redefinitions, as some of them may be instantiable.
+      for (FunctionDecl::redecl_iterator i(Function->redecls_begin()),
+           e(Function->redecls_end()); i != e; ++i) {
+        if (!i->isUsed(false) && i->isImplicitlyInstantiable())
+          MarkDeclarationReferenced(Loc, *i);
       }
-    }
 
     // FIXME: keep track of references to static functions
-    Function->setUsed(true);
+
+    // Recursive functions should be marked when used from another function.
+    if (CurContext != Function)
+      Function->setUsed(true);
 
     return;
   }
@@ -7716,7 +7737,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
       if (MSInfo->getPointOfInstantiation().isInvalid() &&
           MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
         MSInfo->setPointOfInstantiation(Loc);
-        PendingImplicitInstantiations.push_back(std::make_pair(Var, Loc));
+        PendingInstantiations.push_back(std::make_pair(Var, Loc));
       }
     }
 
@@ -7836,7 +7857,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
 
   if (isa<BinaryOperator>(E)) {
     BinaryOperator *Op = cast<BinaryOperator>(E);
-    if (Op->getOpcode() != BinaryOperator::Assign)
+    if (Op->getOpcode() != BO_Assign)
       return;
 
     // Greylist some idioms by putting them into a warning subcategory.
@@ -7899,16 +7920,13 @@ bool Sema::CheckBooleanCondition(Expr *&E, SourceLocation Loc) {
   return false;
 }
 
-Sema::OwningExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
-                                                   ExprArg SubExpr) {
-  Expr *Sub = SubExpr.takeAs<Expr>();
+ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+                                       Expr *Sub) {
   if (!Sub)
     return ExprError();
   
-  if (CheckBooleanCondition(Sub, Loc)) {
-    Sub->Destroy(Context);
+  if (CheckBooleanCondition(Sub, Loc))
     return ExprError();
-  }
   
   return Owned(Sub);
 }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 090400f..5720d93 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -11,28 +11,31 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
 #include "llvm/ADT/STLExtras.h"
 using namespace clang;
-
-Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
-                                        IdentifierInfo &II, 
-                                        SourceLocation NameLoc,
-                                        Scope *S, CXXScopeSpec &SS,
-                                        TypeTy *ObjectTypePtr,
-                                        bool EnteringContext) {
+using namespace sema;
+
+ParsedType Sema::getDestructorName(SourceLocation TildeLoc,
+                                   IdentifierInfo &II, 
+                                   SourceLocation NameLoc,
+                                   Scope *S, CXXScopeSpec &SS,
+                                   ParsedType ObjectTypePtr,
+                                   bool EnteringContext) {
   // Determine where to perform name lookup.
 
   // FIXME: This area of the standard is very messy, and the current
@@ -149,7 +152,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
 
     // FIXME: Should we be suppressing ambiguities here?
     if (Found.isAmbiguous())
-      return 0;
+      return ParsedType();
 
     if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
       QualType T = Context.getTypeDeclType(Type);
@@ -158,7 +161,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
           Context.hasSameUnqualifiedType(T, SearchType)) {
         // We found our type!
 
-        return T.getAsOpaquePtr();
+        return ParsedType::make(T);
       }
     }
 
@@ -191,7 +194,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
               = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
           if (Spec->getSpecializedTemplate()->getCanonicalDecl() ==
                 Template->getCanonicalDecl())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
         }
 
         continue;
@@ -210,7 +213,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
         // specialized.
         if (TemplateDecl *SpecTemplate = SpecName.getAsTemplateDecl()) {
           if (SpecTemplate->getCanonicalDecl() == Template->getCanonicalDecl())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
 
           continue;
         }
@@ -221,7 +224,7 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
                                     = SpecName.getAsDependentTemplateName()) {
           if (DepTemplate->isIdentifier() &&
               DepTemplate->getIdentifier() == Template->getIdentifier())
-            return MemberOfType.getAsOpaquePtr();
+            return ParsedType::make(MemberOfType);
 
           continue;
         }
@@ -242,8 +245,10 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
       Range = SourceRange(NameLoc);
     }
 
-    return CheckTypenameType(ETK_None, NNS, II, SourceLocation(),
-                             Range, NameLoc).getAsOpaquePtr();
+    QualType T = CheckTypenameType(ETK_None, NNS, II,
+                                   SourceLocation(),
+                                   Range, NameLoc);
+    return ParsedType::make(T);
   }
 
   if (ObjectTypePtr)
@@ -252,11 +257,11 @@ Action::TypeTy *Sema::getDestructorName(SourceLocation TildeLoc,
   else
     Diag(NameLoc, diag::err_destructor_class_name);
 
-  return 0;
+  return ParsedType();
 }
 
 /// \brief Build a C++ typeid expression with a type operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                             SourceLocation TypeidLoc,
                                             TypeSourceInfo *Operand,
                                             SourceLocation RParenLoc) {
@@ -279,12 +284,11 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
 }
 
 /// \brief Build a C++ typeid expression with an expression operand.
-Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
+ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
                                             SourceLocation TypeidLoc,
-                                            ExprArg Operand,
+                                            Expr *E,
                                             SourceLocation RParenLoc) {
   bool isUnevaluatedOperand = true;
-  Expr *E = static_cast<Expr *>(Operand.get());
   if (E && !E->isTypeDependent()) {
     QualType T = E->getType();
     if (const RecordType *RecordT = T->getAs<RecordType>()) {
@@ -296,10 +300,10 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
         return ExprError();
       
       // C++ [expr.typeid]p3:
-      //   When typeid is applied to an expression other than an lvalue of a
+      //   When typeid is applied to an expression other than an glvalue of a
       //   polymorphic class type [...] [the] expression is an unevaluated
       //   operand. [...]
-      if (RecordD->isPolymorphic() && E->isLvalue(Context) == Expr::LV_Valid) {
+      if (RecordD->isPolymorphic() && E->Classify(Context).isGLValue()) {
         isUnevaluatedOperand = false;
 
         // We require a vtable to query the type at run time.
@@ -316,9 +320,7 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
     QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
     if (!Context.hasSameType(T, UnqualT)) {
       T = UnqualT;
-      ImpCastExprToType(E, UnqualT, CastExpr::CK_NoOp, E->isLvalue(Context));
-      Operand.release();
-      Operand = Owned(E);
+      ImpCastExprToType(E, UnqualT, CK_NoOp, CastCategory(E));
     }
   }
   
@@ -329,12 +331,12 @@ Sema::OwningExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
     ExprEvalContexts.back().Context = Unevaluated;
   
   return Owned(new (Context) CXXTypeidExpr(TypeInfoType.withConst(),
-                                           Operand.takeAs<Expr>(),
+                                           E,
                                            SourceRange(TypeidLoc, RParenLoc)));  
 }
 
 /// ActOnCXXTypeidOfType - Parse typeid( type-id ) or typeid (expression);
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
                      bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
   // Find the std::type_info type.
@@ -343,7 +345,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
 
   IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
   LookupResult R(*this, TypeInfoII, SourceLocation(), LookupTagName);
-  LookupQualifiedName(R, StdNamespace);
+  LookupQualifiedName(R, getStdNamespace());
   RecordDecl *TypeInfoRecordDecl = R.getAsSingle<RecordDecl>();
   if (!TypeInfoRecordDecl)
     return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
@@ -353,7 +355,8 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
   if (isType) {
     // The operand is a type; handle it as such.
     TypeSourceInfo *TInfo = 0;
-    QualType T = GetTypeFromParser(TyOrExpr, &TInfo);
+    QualType T = GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrExpr),
+                                   &TInfo);
     if (T.isNull())
       return ExprError();
     
@@ -364,11 +367,11 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
   }
 
   // The operand is an expression.  
-  return BuildCXXTypeId(TypeInfoType, OpLoc, Owned((Expr*)TyOrExpr), RParenLoc);
+  return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
 }
 
 /// ActOnCXXBoolLiteral - Parse {true,false} literals.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
   assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
          "Unknown C++ Boolean value!");
@@ -377,15 +380,14 @@ Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
 }
 
 /// ActOnCXXNullPtrLiteral - Parse 'nullptr'.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXNullPtrLiteral(SourceLocation Loc) {
   return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
 }
 
 /// ActOnCXXThrow - Parse throw expressions.
-Action::OwningExprResult
-Sema::ActOnCXXThrow(SourceLocation OpLoc, ExprArg E) {
-  Expr *Ex = E.takeAs<Expr>();
+ExprResult
+Sema::ActOnCXXThrow(SourceLocation OpLoc, Expr *Ex) {
   if (Ex && !Ex->isTypeDependent() && CheckCXXThrowOperand(OpLoc, Ex))
     return ExprError();
   return Owned(new (Context) CXXThrowExpr(Ex, Context.VoidTy, OpLoc));
@@ -400,8 +402,8 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
   //   the type from "array of T" or "function returning T" to "pointer to T" 
   //   or "pointer to function returning T", [...]
   if (E->getType().hasQualifiers())
-    ImpCastExprToType(E, E->getType().getUnqualifiedType(), CastExpr::CK_NoOp,
-                      E->isLvalue(Context) == Expr::LV_Valid);
+    ImpCastExprToType(E, E->getType().getUnqualifiedType(), CK_NoOp,
+                      CastCategory(E));
   
   DefaultFunctionArrayConversion(E);
 
@@ -432,7 +434,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
   InitializedEntity Entity =
     InitializedEntity::InitializeException(ThrowLoc, E->getType(),
                                            /*NRVO=*/false);
-  OwningExprResult Res = PerformCopyInitialization(Entity,
+  ExprResult Res = PerformCopyInitialization(Entity,
                                                    SourceLocation(),
                                                    Owned(E));
   if (Res.isInvalid())
@@ -464,7 +466,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
   return false;
 }
 
-Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
+ExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
   /// C++ 9.3.2: In the body of a non-static member function, the keyword this
   /// is a non-lvalue expression whose value is the address of the object for
   /// which the function is called.
@@ -483,8 +485,8 @@ Action::OwningExprResult Sema::ActOnCXXThis(SourceLocation ThisLoc) {
 /// Can be interpreted either as function-style casting ("int(x)")
 /// or class type construction ("ClassType(x,y,z)")
 /// or creation of a value-initialized type ("int()").
-Action::OwningExprResult
-Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
+ExprResult
+Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, ParsedType TypeRep,
                                 SourceLocation LParenLoc,
                                 MultiExprArg exprs,
                                 SourceLocation *CommaLocs,
@@ -532,19 +534,19 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
   // corresponding cast expression.
   //
   if (NumExprs == 1) {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckCastTypes(TypeRange, Ty, Exprs[0], Kind, BasePath,
                        /*FunctionalStyle=*/true))
       return ExprError();
 
     exprs.release();
 
-    return Owned(new (Context) CXXFunctionalCastExpr(
+    return Owned(CXXFunctionalCastExpr::Create(Context,
                                               Ty.getNonLValueExprType(Context),
-                                                     TInfo, TyBeginLoc, Kind,
-                                                     Exprs[0], BasePath,
-                                                     RParenLoc));
+                                               TInfo, TyBeginLoc, Kind,
+                                               Exprs[0], &BasePath,
+                                               RParenLoc));
   }
 
   if (Ty->isRecordType()) {
@@ -555,7 +557,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
                  : InitializationKind::CreateValue(TypeRange.getBegin(), 
                                                    LParenLoc, RParenLoc);
     InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
-    OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+    ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
                                               move(exprs));
 
     // FIXME: Improve AST representation?
@@ -587,7 +589,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
 /// or
 /// @code ::new Foo(23, "hello") @endcode
 /// For the interpretation of this heap of arguments, consult the base version.
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
                   SourceLocation PlacementRParen, SourceRange TypeIdParens, 
@@ -643,13 +645,13 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
                      AllocType,
                      D.getSourceRange().getBegin(),
                      R,
-                     Owned(ArraySize),
+                     ArraySize,
                      ConstructorLParen,
                      move(ConstructorArgs),
                      ConstructorRParen);
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   SourceLocation PlacementLParen,
                   MultiExprArg PlacementArgs,
@@ -658,7 +660,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                   QualType AllocType,
                   SourceLocation TypeLoc,
                   SourceRange TypeRange,
-                  ExprArg ArraySizeE,
+                  Expr *ArraySize,
                   SourceLocation ConstructorLParen,
                   MultiExprArg ConstructorArgs,
                   SourceLocation ConstructorRParen) {
@@ -667,12 +669,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
 
   // Per C++0x [expr.new]p5, the type being constructed may be a
   // typedef of an array type.
-  if (!ArraySizeE.get()) {
+  if (!ArraySize) {
     if (const ConstantArrayType *Array
                               = Context.getAsConstantArrayType(AllocType)) {
-      ArraySizeE = Owned(new (Context) IntegerLiteral(Array->getSize(),
-                                                      Context.getSizeType(),
-                                                      TypeRange.getEnd()));
+      ArraySize = IntegerLiteral::Create(Context, Array->getSize(),
+                                         Context.getSizeType(),
+                                         TypeRange.getEnd());
       AllocType = Array->getElementType();
     }
   }
@@ -681,13 +683,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
 
   // C++ 5.3.4p6: "The expression in a direct-new-declarator shall have integral
   //   or enumeration type with a non-negative value."
-  Expr *ArraySize = (Expr *)ArraySizeE.get();
   if (ArraySize && !ArraySize->isTypeDependent()) {
     
     QualType SizeType = ArraySize->getType();
     
-    OwningExprResult ConvertedSize
-      = ConvertToIntegralOrEnumerationType(StartLoc, move(ArraySizeE), 
+    ExprResult ConvertedSize
+      = ConvertToIntegralOrEnumerationType(StartLoc, ArraySize,
                                        PDiag(diag::err_array_size_not_integral),
                                      PDiag(diag::err_array_size_incomplete_type)
                                        << ArraySize->getSourceRange(),
@@ -700,8 +701,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
     if (ConvertedSize.isInvalid())
       return ExprError();
     
-    ArraySize = ConvertedSize.takeAs<Expr>();
-    ArraySizeE = Owned(ArraySize);
+    ArraySize = ConvertedSize.take();
     SizeType = ArraySize->getType();
     if (!SizeType->isIntegralOrEnumerationType())
       return ExprError();
@@ -716,8 +716,20 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                         llvm::APInt::getNullValue(Value.getBitWidth()), 
                                  Value.isUnsigned()))
           return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
-                           diag::err_typecheck_negative_array_size)
+                                diag::err_typecheck_negative_array_size)
             << ArraySize->getSourceRange());
+        
+        if (!AllocType->isDependentType()) {
+          unsigned ActiveSizeBits
+            = ConstantArrayType::getNumAddressingBits(Context, AllocType, Value);
+          if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context)) {
+            Diag(ArraySize->getSourceRange().getBegin(), 
+                 diag::err_array_too_large)
+              << Value.toString(10)
+              << ArraySize->getSourceRange();
+            return ExprError();
+          }
+        }
       } else if (TypeIdParens.isValid()) {
         // Can't have dynamic array size when the type-id is in parentheses.
         Diag(ArraySize->getLocStart(), diag::ext_new_paren_array_nonconst)
@@ -730,7 +742,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
     }
     
     ImpCastExprToType(ArraySize, Context.getSizeType(),
-                      CastExpr::CK_IntegralCast);
+                      CK_IntegralCast);
   }
 
   FunctionDecl *OperatorNew = 0;
@@ -768,7 +780,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
   CXXConstructorDecl *Constructor = 0;
   Expr **ConsArgs = (Expr**)ConstructorArgs.get();
   unsigned NumConsArgs = ConstructorArgs.size();
-  ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this);
+  ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
 
   // Array 'new' can't have any initializers.
   if (NumConsArgs && (ResultType->isArrayType() || ArraySize)) {
@@ -798,7 +810,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
     InitializedEntity Entity
       = InitializedEntity::InitializeNew(StartLoc, AllocType);
     InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs);
-    OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, 
+    ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, 
                                                 move(ConstructorArgs));
     if (FullInit.isInvalid())
       return ExprError();
@@ -839,7 +851,6 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
   
   PlacementArgs.release();
   ConstructorArgs.release();
-  ArraySizeE.release();
   
   // FIXME: The TypeSourceInfo should also be included in CXXNewExpr.
   return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
@@ -911,7 +922,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
   // We don't care about the actual value of this argument.
   // FIXME: Should the Sema create the expression and embed it in the syntax
   // tree? Or should the consumer just recalculate the value?
-  IntegerLiteral Size(llvm::APInt::getNullValue(
+  IntegerLiteral Size(Context, llvm::APInt::getNullValue(
                       Context.Target.getPointerWidth(0)),
                       Context.getSizeType(),
                       SourceLocation());
@@ -929,9 +940,11 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
   DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
                                         IsArray ? OO_Array_Delete : OO_Delete);
 
-  if (AllocType->isRecordType() && !UseGlobal) {
+  QualType AllocElemType = Context.getBaseElementType(AllocType);
+
+  if (AllocElemType->isRecordType() && !UseGlobal) {
     CXXRecordDecl *Record
-      = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
     if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0],
                           AllocArgs.size(), Record, /*AllowMissing=*/true,
                           OperatorNew))
@@ -969,9 +982,9 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
   //   the allocated type is not a class type or array thereof, the
   //   deallocation function’s name is looked up in the global scope.
   LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
-  if (AllocType->isRecordType() && !UseGlobal) {
+  if (AllocElemType->isRecordType() && !UseGlobal) {
     CXXRecordDecl *RD
-      = cast<CXXRecordDecl>(AllocType->getAs<RecordType>()->getDecl());
+      = cast<CXXRecordDecl>(AllocElemType->getAs<RecordType>()->getDecl());
     LookupQualifiedName(FoundDelete, RD);
   }
   if (FoundDelete.isAmbiguous())
@@ -1115,7 +1128,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
 
   // Do the resolution.
   OverloadCandidateSet::iterator Best;
-  switch(BestViableFunction(Candidates, StartLoc, Best)) {
+  switch (Candidates.BestViableFunction(*this, StartLoc, Best)) {
   case OR_Success: {
     // Got one!
     FunctionDecl *FnDecl = Best->Function;
@@ -1125,7 +1138,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
     // Watch out for variadic allocator function.
     unsigned NumArgsInFnDecl = FnDecl->getNumParams();
     for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
-      OwningExprResult Result
+      ExprResult Result
         = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                        FnDecl->getParamDecl(i)),
                                     SourceLocation(),
@@ -1143,20 +1156,20 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
   case OR_No_Viable_Function:
     Diag(StartLoc, diag::err_ovl_no_viable_function_in_call)
       << Name << Range;
-    PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+    Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     return true;
 
   case OR_Ambiguous:
     Diag(StartLoc, diag::err_ovl_ambiguous_call)
       << Name << Range;
-    PrintOverloadCandidates(Candidates, OCD_ViableCandidates, Args, NumArgs);
+    Candidates.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
     return true;
 
   case OR_Deleted:
     Diag(StartLoc, diag::err_ovl_deleted_call)
       << Best->Function->isDeleted()
       << Name << Range;
-    PrintOverloadCandidates(Candidates, OCD_AllCandidates, Args, NumArgs);
+    Candidates.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     return true;
   }
   assert(false && "Unreachable, bad result from BestViableFunction");
@@ -1199,11 +1212,11 @@ void Sema::DeclareGlobalNewDelete() {
     // The "std::bad_alloc" class has not yet been declared, so build it
     // implicitly.
     StdBadAlloc = CXXRecordDecl::Create(Context, TTK_Class, 
-                                        getStdNamespace(), 
+                                        getOrCreateStdNamespace(), 
                                         SourceLocation(), 
                                       &PP.getIdentifierTable().get("bad_alloc"), 
                                         SourceLocation(), 0);
-    StdBadAlloc->setImplicit(true);
+    getStdBadAlloc()->setImplicit(true);
   }
   
   GlobalNewDeleteDeclared = true;
@@ -1245,8 +1258,11 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
           Context.getCanonicalType(
             Func->getParamDecl(0)->getType().getUnqualifiedType());
         // FIXME: Do we need to check for default arguments here?
-        if (Func->getNumParams() == 1 && InitialParamType == Argument)
+        if (Func->getNumParams() == 1 && InitialParamType == Argument) {
+          if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
+            Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
           return;
+        }
       }
     }
   }
@@ -1257,7 +1273,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
        Name.getCXXOverloadedOperator() == OO_Array_New);
   if (HasBadAllocExceptionSpec) {
     assert(StdBadAlloc && "Must have std::bad_alloc declared");
-    BadAllocType = Context.getTypeDeclType(StdBadAlloc);
+    BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
   }
   
   QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
@@ -1267,23 +1283,23 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
                                             FunctionType::ExtInfo());
   FunctionDecl *Alloc =
     FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
-                         FnType, /*TInfo=*/0, FunctionDecl::None,
-                         FunctionDecl::None, false, true);
+                         FnType, /*TInfo=*/0, SC_None,
+                         SC_None, false, true);
   Alloc->setImplicit();
   
   if (AddMallocAttr)
-    Alloc->addAttr(::new (Context) MallocAttr());
+    Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
   
   ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
                                            0, Argument, /*TInfo=*/0,
-                                           VarDecl::None,
-                                           VarDecl::None, 0);
+                                           SC_None,
+                                           SC_None, 0);
   Alloc->setParams(&Param, 1);
 
   // FIXME: Also add this declaration to the IdentifierResolver, but
   // make sure it is at the end of the chain to coincide with the
   // global scope.
-  ((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
+  Context.getTranslationUnitDecl()->addDecl(Alloc);
 }
 
 bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
@@ -1298,15 +1314,37 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
 
   Found.suppressDiagnostics();
 
+  llvm::SmallVector<DeclAccessPair,4> Matches;
   for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
        F != FEnd; ++F) {
-    if (CXXMethodDecl *Delete = dyn_cast<CXXMethodDecl>(*F))
-      if (Delete->isUsualDeallocationFunction()) {
-        Operator = Delete;
-        CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
-                              F.getPair());
-        return false;
-      }
+    NamedDecl *ND = (*F)->getUnderlyingDecl();
+
+    // Ignore template operator delete members from the check for a usual
+    // deallocation function.
+    if (isa<FunctionTemplateDecl>(ND))
+      continue;
+
+    if (cast<CXXMethodDecl>(ND)->isUsualDeallocationFunction())
+      Matches.push_back(F.getPair());
+  }
+
+  // There's exactly one suitable operator;  pick it.
+  if (Matches.size() == 1) {
+    Operator = cast<CXXMethodDecl>(Matches[0]->getUnderlyingDecl());
+    CheckAllocationAccess(StartLoc, SourceRange(), Found.getNamingClass(),
+                          Matches[0]);
+    return false;
+
+  // We found multiple suitable operators;  complain about the ambiguity.
+  } else if (!Matches.empty()) {
+    Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
+      << Name << RD;
+
+    for (llvm::SmallVectorImpl<DeclAccessPair>::iterator
+           F = Matches.begin(), FEnd = Matches.end(); F != FEnd; ++F)
+      Diag((*F)->getUnderlyingDecl()->getLocation(),
+           diag::note_member_declared_here) << Name;
+    return true;
   }
 
   // We did find operator delete/operator delete[] declarations, but
@@ -1316,10 +1354,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
       << Name << RD;
         
     for (LookupResult::iterator F = Found.begin(), FEnd = Found.end();
-         F != FEnd; ++F) {
-      Diag((*F)->getLocation(), diag::note_member_declared_here)
-        << Name;
-    }
+         F != FEnd; ++F)
+      Diag((*F)->getUnderlyingDecl()->getLocation(),
+           diag::note_member_declared_here) << Name;
 
     return true;
   }
@@ -1344,9 +1381,9 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
 /// @code ::delete ptr; @endcode
 /// or
 /// @code delete [] ptr; @endcode
-Action::OwningExprResult
+ExprResult
 Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
-                     bool ArrayForm, ExprArg Operand) {
+                     bool ArrayForm, Expr *Ex) {
   // C++ [expr.delete]p1:
   //   The operand shall have a pointer type, or a class type having a single
   //   conversion function to a pointer type. The result has type void.
@@ -1355,11 +1392,14 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
 
   FunctionDecl *OperatorDelete = 0;
 
-  Expr *Ex = (Expr *)Operand.get();
   if (!Ex->isTypeDependent()) {
     QualType Type = Ex->getType();
 
     if (const RecordType *Record = Type->getAs<RecordType>()) {
+      if (RequireCompleteType(StartLoc, Type, 
+                              PDiag(diag::err_delete_incomplete_class_type)))
+        return ExprError();
+      
       llvm::SmallVector<CXXConversionDecl*, 4> ObjectPtrConversions;
 
       CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
@@ -1378,18 +1418,16 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
         
         QualType ConvType = Conv->getConversionType().getNonReferenceType();
         if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
-          if (ConvPtrType->getPointeeType()->isObjectType())
+          if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
             ObjectPtrConversions.push_back(Conv);
       }
       if (ObjectPtrConversions.size() == 1) {
         // We have a single conversion to a pointer-to-object type. Perform
         // that conversion.
         // TODO: don't redo the conversion calculation.
-        Operand.release();
         if (!PerformImplicitConversion(Ex,
                             ObjectPtrConversions.front()->getConversionType(),
                                       AA_Converting)) {
-          Operand = Owned(Ex);
           Type = Ex->getType();
         }
       }
@@ -1428,16 +1466,13 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
     //   (5.2.11) of the pointer expression before it is used as the operand 
     //   of the delete-expression. ]
     ImpCastExprToType(Ex, Context.getPointerType(Context.VoidTy), 
-                      CastExpr::CK_NoOp);
-    
-    // Update the operand.
-    Operand.take();
-    Operand = ExprArg(*this, Ex);
+                      CK_NoOp);
     
     DeclarationName DeleteName = Context.DeclarationNames.getCXXOperatorName(
                                       ArrayForm ? OO_Array_Delete : OO_Delete);
 
-    if (const RecordType *RT = Pointee->getAs<RecordType>()) {
+    QualType PointeeElem = Context.getBaseElementType(Pointee);
+    if (const RecordType *RT = PointeeElem->getAs<RecordType>()) {
       CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
 
       if (!UseGlobal && 
@@ -1465,14 +1500,13 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
     // FIXME: Check access and ambiguity of operator delete and destructor.
   }
 
-  Operand.release();
   return Owned(new (Context) CXXDeleteExpr(Context.VoidTy, UseGlobal, ArrayForm,
                                            OperatorDelete, Ex, StartLoc));
 }
 
 /// \brief Check the use of the given variable as a C++ condition in an if,
 /// while, do-while, or switch statement.
-Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
+ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
                                                       SourceLocation StmtLoc,
                                                       bool ConvertToBoolean) {
   QualType T = ConditionVar->getType();
@@ -1491,10 +1525,8 @@ Action::OwningExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
   Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar,
                                         ConditionVar->getLocation(), 
                                  ConditionVar->getType().getNonReferenceType());
-  if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc)) {
-    Condition->Destroy(Context);
+  if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc))
     return ExprError();
-  }
   
   return Owned(Condition);
 }
@@ -1543,34 +1575,33 @@ Sema::IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType) {
   return false;
 }
 
-static Sema::OwningExprResult BuildCXXCastArgument(Sema &S, 
-                                                   SourceLocation CastLoc,
-                                                   QualType Ty,
-                                                   CastExpr::CastKind Kind,
-                                                   CXXMethodDecl *Method,
-                                                   Sema::ExprArg Arg) {
-  Expr *From = Arg.takeAs<Expr>();
-  
+static ExprResult BuildCXXCastArgument(Sema &S, 
+                                       SourceLocation CastLoc,
+                                       QualType Ty,
+                                       CastKind Kind,
+                                       CXXMethodDecl *Method,
+                                       Expr *From) {
   switch (Kind) {
   default: assert(0 && "Unhandled cast kind!");
-  case CastExpr::CK_ConstructorConversion: {
-    ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+  case CK_ConstructorConversion: {
+    ASTOwningVector<Expr*> ConstructorArgs(S);
     
     if (S.CompleteConstructorCall(cast<CXXConstructorDecl>(Method),
-                                  Sema::MultiExprArg(S, (void **)&From, 1),
+                                  MultiExprArg(&From, 1),
                                   CastLoc, ConstructorArgs))
-      return S.ExprError();
+      return ExprError();
     
-    Sema::OwningExprResult Result = 
+    ExprResult Result = 
     S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method), 
-                            move_arg(ConstructorArgs));
+                            move_arg(ConstructorArgs),
+                            /*ZeroInit*/ false, CXXConstructExpr::CK_Complete);
     if (Result.isInvalid())
-      return S.ExprError();
+      return ExprError();
     
     return S.MaybeBindToTemporary(Result.takeAs<Expr>());
   }
     
-  case CastExpr::CK_UserDefinedConversion: {
+  case CK_UserDefinedConversion: {
     assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
     
     // Create an implicit call expr that calls it.
@@ -1601,10 +1632,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
   case ImplicitConversionSequence::UserDefinedConversion: {
     
       FunctionDecl *FD = ICS.UserDefined.ConversionFunction;
-      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      CastKind CastKind = CK_Unknown;
       QualType BeforeToType;
       if (const CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(FD)) {
-        CastKind = CastExpr::CK_UserDefinedConversion;
+        CastKind = CK_UserDefinedConversion;
         
         // If the user-defined conversion is specified by a conversion function,
         // the initial standard conversion sequence converts the source type to
@@ -1612,7 +1643,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
         BeforeToType = Context.getTagDeclType(Conv->getParent());
       } else if (const CXXConstructorDecl *Ctor = 
                   dyn_cast<CXXConstructorDecl>(FD)) {
-        CastKind = CastExpr::CK_ConstructorConversion;
+        CastKind = CK_ConstructorConversion;
         // Do no conversion if dealing with ... for the first conversion.
         if (!ICS.UserDefined.EllipsisConversion) {
           // If the user-defined conversion is specified by a constructor, the 
@@ -1631,12 +1662,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
           return true;
       }
     
-      OwningExprResult CastArg 
+      ExprResult CastArg 
         = BuildCXXCastArgument(*this,
                                From->getLocStart(),
                                ToType.getNonReferenceType(),
                                CastKind, cast<CXXMethodDecl>(FD), 
-                               Owned(From));
+                               From);
 
       if (CastArg.isInvalid())
         return true;
@@ -1648,7 +1679,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
   }
 
   case ImplicitConversionSequence::AmbiguousConversion:
-    DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
+    ICS.DiagnoseAmbiguousConversion(*this, From->getExprLoc(),
                           PDiag(diag::err_typecheck_ambiguous_condition)
                             << From->getSourceRange());
      return true;
@@ -1685,25 +1716,29 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
     // FIXME: When can ToType be a reference type?
     assert(!ToType->isReferenceType());
     if (SCS.Second == ICK_Derived_To_Base) {
-      ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
+      ASTOwningVector<Expr*> ConstructorArgs(*this);
       if (CompleteConstructorCall(cast<CXXConstructorDecl>(SCS.CopyConstructor),
-                                  MultiExprArg(*this, (void **)&From, 1),
+                                  MultiExprArg(*this, &From, 1),
                                   /*FIXME:ConstructLoc*/SourceLocation(), 
                                   ConstructorArgs))
         return true;
-      OwningExprResult FromResult =
+      ExprResult FromResult =
         BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
                               ToType, SCS.CopyConstructor,
-                              move_arg(ConstructorArgs));
+                              move_arg(ConstructorArgs),
+                              /*ZeroInit*/ false,
+                              CXXConstructExpr::CK_Complete);
       if (FromResult.isInvalid())
         return true;
       From = FromResult.takeAs<Expr>();
       return false;
     }
-    OwningExprResult FromResult =
+    ExprResult FromResult =
       BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
                             ToType, SCS.CopyConstructor,
-                            MultiExprArg(*this, (void**)&From, 1));
+                            MultiExprArg(*this, &From, 1),
+                            /*ZeroInit*/ false,
+                            CXXConstructExpr::CK_Complete);
 
     if (FromResult.isInvalid())
       return true;
@@ -1736,12 +1771,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
 
   case ICK_Array_To_Pointer:
     FromType = Context.getArrayDecayedType(FromType);
-    ImpCastExprToType(From, FromType, CastExpr::CK_ArrayToPointerDecay);
+    ImpCastExprToType(From, FromType, CK_ArrayToPointerDecay);
     break;
 
   case ICK_Function_To_Pointer:
     FromType = Context.getPointerType(FromType);
-    ImpCastExprToType(From, FromType, CastExpr::CK_FunctionToPointerDecay);
+    ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay);
     break;
 
   default:
@@ -1766,33 +1801,33 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
       return true;      
       
     ImpCastExprToType(From, Context.getNoReturnType(From->getType(), false),
-                      CastExpr::CK_NoOp);
+                      CK_NoOp);
     break;
       
   case ICK_Integral_Promotion:
   case ICK_Integral_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_IntegralCast);
+    ImpCastExprToType(From, ToType, CK_IntegralCast);
     break;
 
   case ICK_Floating_Promotion:
   case ICK_Floating_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_FloatingCast);
+    ImpCastExprToType(From, ToType, CK_FloatingCast);
     break;
 
   case ICK_Complex_Promotion:
   case ICK_Complex_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+    ImpCastExprToType(From, ToType, CK_Unknown);
     break;
 
   case ICK_Floating_Integral:
     if (ToType->isRealFloatingType())
-      ImpCastExprToType(From, ToType, CastExpr::CK_IntegralToFloating);
+      ImpCastExprToType(From, ToType, CK_IntegralToFloating);
     else
-      ImpCastExprToType(From, ToType, CastExpr::CK_FloatingToIntegral);
+      ImpCastExprToType(From, ToType, CK_FloatingToIntegral);
     break;
 
   case ICK_Compatible_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_NoOp);
+    ImpCastExprToType(From, ToType, CK_NoOp);
     break;
 
   case ICK_Pointer_Conversion: {
@@ -1805,36 +1840,36 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
     }
 
     
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckPointerConversion(From, ToType, Kind, BasePath, IgnoreBaseAccess))
       return true;
-    ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+    ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
     break;
   }
   
   case ICK_Pointer_Member: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
-    CXXBaseSpecifierArray BasePath;
+    CastKind Kind = CK_Unknown;
+    CXXCastPath BasePath;
     if (CheckMemberPointerConversion(From, ToType, Kind, BasePath,
                                      IgnoreBaseAccess))
       return true;
     if (CheckExceptionSpecCompatibility(From, ToType))
       return true;
-    ImpCastExprToType(From, ToType, Kind, /*isLvalue=*/false, BasePath);
+    ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath);
     break;
   }
   case ICK_Boolean_Conversion: {
-    CastExpr::CastKind Kind = CastExpr::CK_Unknown;
+    CastKind Kind = CK_Unknown;
     if (FromType->isMemberPointerType())
-      Kind = CastExpr::CK_MemberPointerToBoolean;
+      Kind = CK_MemberPointerToBoolean;
     
     ImpCastExprToType(From, Context.BoolTy, Kind);
     break;
   }
 
   case ICK_Derived_To_Base: {
-    CXXBaseSpecifierArray BasePath;
+    CXXCastPath BasePath;
     if (CheckDerivedToBaseConversion(From->getType(), 
                                      ToType.getNonReferenceType(),
                                      From->getLocStart(),
@@ -1843,24 +1878,22 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
                                      IgnoreBaseAccess))
       return true;
 
-    ImpCastExprToType(From, ToType.getNonReferenceType(), 
-                      CastExpr::CK_DerivedToBase, 
-                      /*isLvalue=*/(From->getType()->isRecordType() &&
-                                    From->isLvalue(Context) == Expr::LV_Valid),
-                      BasePath);
+    ImpCastExprToType(From, ToType.getNonReferenceType(),
+                      CK_DerivedToBase, CastCategory(From),
+                      &BasePath);
     break;
   }
 
   case ICK_Vector_Conversion:
-    ImpCastExprToType(From, ToType, CastExpr::CK_BitCast);
+    ImpCastExprToType(From, ToType, CK_BitCast);
     break;
 
   case ICK_Vector_Splat:
-    ImpCastExprToType(From, ToType, CastExpr::CK_VectorSplat);
+    ImpCastExprToType(From, ToType, CK_VectorSplat);
     break;
       
   case ICK_Complex_Real:
-    ImpCastExprToType(From, ToType, CastExpr::CK_Unknown);
+    ImpCastExprToType(From, ToType, CK_Unknown);
     break;
       
   case ICK_Lvalue_To_Rvalue:
@@ -1877,18 +1910,21 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
     // Nothing to do.
     break;
 
-  case ICK_Qualification:
-    // FIXME: Not sure about lvalue vs rvalue here in the presence of rvalue
-    // references.
+  case ICK_Qualification: {
+    // The qualification keeps the category of the inner expression, unless the
+    // target type isn't a reference.
+    ExprValueKind VK = ToType->isReferenceType() ?
+                                  CastCategory(From) : VK_RValue;
     ImpCastExprToType(From, ToType.getNonLValueExprType(Context),
-                      CastExpr::CK_NoOp, ToType->isLValueReferenceType());
+                      CK_NoOp, VK);
 
     if (SCS.DeprecatedStringLiteralToCharPtr)
       Diag(From->getLocStart(), diag::warn_deprecated_string_literal_conversion)
         << ToType.getNonReferenceType();
 
     break;
-      
+    }
+
   default:
     assert(false && "Improper third standard conversion");
     break;
@@ -1897,10 +1933,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
   return false;
 }
 
-Sema::OwningExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
+ExprResult Sema::ActOnUnaryTypeTrait(UnaryTypeTrait OTT,
                                                  SourceLocation KWLoc,
                                                  SourceLocation LParen,
-                                                 TypeTy *Ty,
+                                                 ParsedType Ty,
                                                  SourceLocation RParen) {
   QualType T = GetTypeFromParser(Ty);
 
@@ -1974,12 +2010,12 @@ QualType Sema::CheckPointerToMemberOperands(
     }
     // Cast LHS to type of use.
     QualType UseType = isIndirect ? Context.getPointerType(Class) : Class;
-    bool isLValue = !isIndirect && lex->isLvalue(Context) == Expr::LV_Valid;
-    
-    CXXBaseSpecifierArray BasePath;
+    ExprValueKind VK =
+        isIndirect ? VK_RValue : CastCategory(lex);
+
+    CXXCastPath BasePath;
     BuildBasePathArray(Paths, BasePath);
-    ImpCastExprToType(lex, UseType, CastExpr::CK_DerivedToBase, isLValue,
-                      BasePath);
+    ImpCastExprToType(lex, UseType, CK_DerivedToBase, VK, &BasePath);
   }
 
   if (isa<CXXScalarValueInitExpr>(rex->IgnoreParens())) {
@@ -2108,7 +2144,7 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
   Self.AddBuiltinOperatorCandidates(OO_Conditional, Loc, Args, 2, CandidateSet);
 
   OverloadCandidateSet::iterator Best;
-  switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
+  switch (CandidateSet.BestViableFunction(Self, Loc, Best)) {
     case OR_Success:
       // We found a match. Perform the conversions on the arguments and move on.
       if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
@@ -2146,8 +2182,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E, QualType T) {
   InitializationKind Kind = InitializationKind::CreateCopy(E->getLocStart(),
                                                            SourceLocation());
   InitializationSequence InitSeq(Self, Entity, Kind, &E, 1);
-  Sema::OwningExprResult Result = InitSeq.Perform(Self, Entity, Kind, 
-                                    Sema::MultiExprArg(Self, (void **)&E, 1));
+  ExprResult Result = InitSeq.Perform(Self, Entity, Kind, MultiExprArg(&E, 1));
   if (Result.isInvalid())
     return true;
   
@@ -2286,13 +2321,13 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
     if (LTy->isRecordType()) {
       // The operands have class type. Make a temporary copy.
       InitializedEntity Entity = InitializedEntity::InitializeTemporary(LTy);
-      OwningExprResult LHSCopy = PerformCopyInitialization(Entity, 
+      ExprResult LHSCopy = PerformCopyInitialization(Entity, 
                                                            SourceLocation(), 
                                                            Owned(LHS));
       if (LHSCopy.isInvalid())
         return QualType();
         
-      OwningExprResult RHSCopy = PerformCopyInitialization(Entity, 
+      ExprResult RHSCopy = PerformCopyInitialization(Entity, 
                                                            SourceLocation(), 
                                                            Owned(RHS));
       if (RHSCopy.isInvalid())
@@ -2385,16 +2420,16 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
   //   the type of the other operand.
   if (E1->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T2->isMemberPointerType())
-      ImpCastExprToType(E1, T2, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(E1, T2, CK_NullToMemberPointer);
     else
-      ImpCastExprToType(E1, T2, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(E1, T2, CK_IntegralToPointer);
     return T2;
   }
   if (E2->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
     if (T1->isMemberPointerType())
-      ImpCastExprToType(E2, T1, CastExpr::CK_NullToMemberPointer);
+      ImpCastExprToType(E2, T1, CK_NullToMemberPointer);
     else
-      ImpCastExprToType(E2, T1, CastExpr::CK_IntegralToPointer);
+      ImpCastExprToType(E2, T1, CK_IntegralToPointer);
     return T1;
   }
 
@@ -2528,15 +2563,15 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
     }
 
     // Convert E1 to Composite1
-    OwningExprResult E1Result
-      = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E1,1));
+    ExprResult E1Result
+      = E1ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E1,1));
     if (E1Result.isInvalid())
       return QualType();
     E1 = E1Result.takeAs<Expr>();
 
     // Convert E2 to Composite1
-    OwningExprResult E2Result
-      = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,(void**)&E2,1));
+    ExprResult E2Result
+      = E2ToC1.Perform(*this, Entity1, Kind, MultiExprArg(*this,&E2,1));
     if (E2Result.isInvalid())
       return QualType();
     E2 = E2Result.takeAs<Expr>();
@@ -2553,15 +2588,15 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
     return QualType();
   
   // Convert E1 to Composite2
-  OwningExprResult E1Result
-    = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E1, 1));
+  ExprResult E1Result
+    = E1ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E1, 1));
   if (E1Result.isInvalid())
     return QualType();
   E1 = E1Result.takeAs<Expr>();
   
   // Convert E2 to Composite2
-  OwningExprResult E2Result
-    = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, (void**)&E2, 1));
+  ExprResult E2Result
+    = E2ToC2.Perform(*this, Entity2, Kind, MultiExprArg(*this, &E2, 1));
   if (E2Result.isInvalid())
     return QualType();
   E2 = E2Result.takeAs<Expr>();
@@ -2569,7 +2604,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
   return Composite2;
 }
 
-Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
+ExprResult Sema::MaybeBindToTemporary(Expr *E) {
   if (!Context.getLangOptions().CPlusPlus)
     return Owned(E);
 
@@ -2579,34 +2614,22 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
   if (!RT)
     return Owned(E);
 
-  // If this is the result of a call expression, our source might
-  // actually be a reference, in which case we shouldn't bind.
+  // If this is the result of a call or an Objective-C message send expression,
+  // our source might actually be a reference, in which case we shouldn't bind.
   if (CallExpr *CE = dyn_cast<CallExpr>(E)) {
-    QualType Ty = CE->getCallee()->getType();
-    if (const PointerType *PT = Ty->getAs<PointerType>())
-      Ty = PT->getPointeeType();
-    else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
-      Ty = BPT->getPointeeType();
-
-    const FunctionType *FTy = Ty->getAs<FunctionType>();
-    if (FTy->getResultType()->isReferenceType())
+    if (CE->getCallReturnType()->isReferenceType())
       return Owned(E);
+  } else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
+    if (const ObjCMethodDecl *MD = ME->getMethodDecl()) {
+      if (MD->getResultType()->isReferenceType())
+        return Owned(E);    
+    }
   }
-  else if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
-    QualType Ty = ME->getType();
-    if (const PointerType *PT = Ty->getAs<PointerType>())
-      Ty = PT->getPointeeType();
-    else if (const BlockPointerType *BPT = Ty->getAs<BlockPointerType>())
-      Ty = BPT->getPointeeType();
-    if (Ty->isReferenceType())
-      return Owned(E);    
-  }
-
 
   // That should be enough to guarantee that this type is complete.
   // If it has a trivial destructor, we can avoid the extra copy.
   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
-  if (RD->hasTrivialDestructor())
+  if (RD->isInvalidDecl() || RD->hasTrivialDestructor())
     return Owned(E);
 
   CXXTemporary *Temp = CXXTemporary::Create(Context, LookupDestructor(RD));
@@ -2641,8 +2664,8 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) {
   return E;
 }
 
-Sema::OwningExprResult 
-Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) {
+ExprResult 
+Sema::MaybeCreateCXXExprWithTemporaries(ExprResult SubExpr) {
   if (SubExpr.isInvalid())
     return ExprError();
   
@@ -2665,17 +2688,16 @@ FullExpr Sema::CreateFullExpr(Expr *SubExpr) {
   return E;
 }
 
-Sema::OwningExprResult
-Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
-                                   tok::TokenKind OpKind, TypeTy *&ObjectType,
+ExprResult
+Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc,
+                                   tok::TokenKind OpKind, ParsedType &ObjectType,
                                    bool &MayBePseudoDestructor) {
   // Since this might be a postfix expression, get rid of ParenListExprs.
-  Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+  ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+  if (Result.isInvalid()) return ExprError();
+  Base = Result.get();
 
-  Expr *BaseExpr = (Expr*)Base.get();
-  assert(BaseExpr && "no record expansion");
-
-  QualType BaseType = BaseExpr->getType();
+  QualType BaseType = Base->getType();
   MayBePseudoDestructor = false;
   if (BaseType->isDependentType()) {
     // If we have a pointer to a dependent type and are using the -> operator,
@@ -2685,9 +2707,9 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
       if (const PointerType *Ptr = BaseType->getAs<PointerType>())
         BaseType = Ptr->getPointeeType();
     
-    ObjectType = BaseType.getAsOpaquePtr();
+    ObjectType = ParsedType::make(BaseType);
     MayBePseudoDestructor = true;
-    return move(Base);
+    return Owned(Base);
   }
 
   // C++ [over.match.oper]p8:
@@ -2700,13 +2722,13 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
     CTypes.insert(Context.getCanonicalType(BaseType));
     
     while (BaseType->isRecordType()) {
-      Base = BuildOverloadedArrowExpr(S, move(Base), OpLoc);
-      BaseExpr = (Expr*)Base.get();
-      if (BaseExpr == NULL)
+      Result = BuildOverloadedArrowExpr(S, Base, OpLoc);
+      if (Result.isInvalid())
         return ExprError();
-      if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(BaseExpr))
+      Base = Result.get();
+      if (CXXOperatorCallExpr *OpCall = dyn_cast<CXXOperatorCallExpr>(Base))
         Locations.push_back(OpCall->getDirectCallee()->getLocation());
-      BaseType = BaseExpr->getType();
+      BaseType = Base->getType();
       CanQualType CBaseType = Context.getCanonicalType(BaseType);
       if (!CTypes.insert(CBaseType)) {
         Diag(OpLoc, diag::err_operator_arrow_circular);
@@ -2731,9 +2753,9 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
     //
     // This also indicates that we should be parsing a
     // pseudo-destructor-name.
-    ObjectType = 0;
+    ObjectType = ParsedType();
     MayBePseudoDestructor = true;
-    return move(Base);
+    return Owned(Base);
   }
 
   // The object type must be complete (or dependent).
@@ -2747,27 +2769,26 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
   //   unqualified-id, and the type of the object expression is of a class
   //   type C (or of pointer to a class type C), the unqualified-id is looked
   //   up in the scope of class C. [...]
-  ObjectType = BaseType.getAsOpaquePtr();
+  ObjectType = ParsedType::make(BaseType);
   return move(Base);
 }
 
-Sema::OwningExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
-                                                   ExprArg MemExpr) {
-  Expr *E = (Expr *) MemExpr.get();
+ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc,
+                                                   Expr *MemExpr) {
   SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(NameLoc);
-  Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
-    << isa<CXXPseudoDestructorExpr>(E)
+  Diag(MemExpr->getLocStart(), diag::err_dtor_expr_without_call)
+    << isa<CXXPseudoDestructorExpr>(MemExpr)
     << FixItHint::CreateInsertion(ExpectedLParenLoc, "()");
   
   return ActOnCallExpr(/*Scope*/ 0,
-                       move(MemExpr),
+                       MemExpr,
                        /*LPLoc*/ ExpectedLParenLoc,
-                       Sema::MultiExprArg(*this, 0, 0),
+                       MultiExprArg(),
                        /*CommaLocs*/ 0,
                        /*RPLoc*/ ExpectedLParenLoc);
 }
 
-Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
+ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
                                                        SourceLocation OpLoc,
                                                        tok::TokenKind OpKind,
                                                        const CXXScopeSpec &SS,
@@ -2782,12 +2803,11 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
   //   The left-hand side of the dot operator shall be of scalar type. The 
   //   left-hand side of the arrow operator shall be of pointer to scalar type.
   //   This scalar type is the object type. 
-  Expr *BaseE = (Expr *)Base.get();
-  QualType ObjectType = BaseE->getType();
+  QualType ObjectType = Base->getType();
   if (OpKind == tok::arrow) {
     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
       ObjectType = Ptr->getPointeeType();
-    } else if (!BaseE->isTypeDependent()) {
+    } else if (!Base->isTypeDependent()) {
       // The user wrote "p->" when she probably meant "p."; fix it.
       Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
         << ObjectType << true
@@ -2801,7 +2821,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
   
   if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
     Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
-      << ObjectType << BaseE->getSourceRange();
+      << ObjectType << Base->getSourceRange();
     return ExprError();
   }
 
@@ -2815,7 +2835,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
     if (!DestructedType->isDependentType() && !ObjectType->isDependentType() &&
         !Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
       Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
-        << ObjectType << DestructedType << BaseE->getSourceRange()
+        << ObjectType << DestructedType << Base->getSourceRange()
         << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
       
       // Recover by setting the destructed type to the object type.
@@ -2840,7 +2860,7 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
       
       Diag(ScopeTypeInfo->getTypeLoc().getLocalSourceRange().getBegin(),
            diag::err_pseudo_dtor_type_mismatch)
-        << ObjectType << ScopeType << BaseE->getSourceRange()
+        << ObjectType << ScopeType << Base->getSourceRange()
         << ScopeTypeInfo->getTypeLoc().getLocalSourceRange();
   
       ScopeType = QualType();
@@ -2848,25 +2868,22 @@ Sema::OwningExprResult Sema::BuildPseudoDestructorExpr(ExprArg Base,
     }
   }
   
-  OwningExprResult Result
-    = Owned(new (Context) CXXPseudoDestructorExpr(Context, 
-                                                  Base.takeAs<Expr>(),
-                                                  OpKind == tok::arrow,
-                                                  OpLoc,
-                                       (NestedNameSpecifier *) SS.getScopeRep(),
-                                                  SS.getRange(),
-                                                  ScopeTypeInfo,
-                                                  CCLoc,
-                                                  TildeLoc,
-                                                  Destructed));
+  Expr *Result
+    = new (Context) CXXPseudoDestructorExpr(Context, Base,
+                                            OpKind == tok::arrow, OpLoc,
+                                            SS.getScopeRep(), SS.getRange(),
+                                            ScopeTypeInfo,
+                                            CCLoc,
+                                            TildeLoc,
+                                            Destructed);
             
   if (HasTrailingLParen)
-    return move(Result);
+    return Owned(Result);
   
-  return DiagnoseDtorReference(Destructed.getLocation(), move(Result));
+  return DiagnoseDtorReference(Destructed.getLocation(), Result);
 }
 
-Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
+ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
                                                        SourceLocation OpLoc,
                                                        tok::TokenKind OpKind,
                                                        CXXScopeSpec &SS,
@@ -2882,13 +2899,11 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
           SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
          "Invalid second type name in pseudo-destructor");
 
-  Expr *BaseE = (Expr *)Base.get();
-  
   // C++ [expr.pseudo]p2:
   //   The left-hand side of the dot operator shall be of scalar type. The 
   //   left-hand side of the arrow operator shall be of pointer to scalar type.
   //   This scalar type is the object type. 
-  QualType ObjectType = BaseE->getType();
+  QualType ObjectType = Base->getType();
   if (OpKind == tok::arrow) {
     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
       ObjectType = Ptr->getPointeeType();
@@ -2906,12 +2921,12 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
 
   // Compute the object type that we should use for name lookup purposes. Only
   // record types and dependent types matter.
-  void *ObjectTypePtrForLookup = 0;
+  ParsedType ObjectTypePtrForLookup;
   if (!SS.isSet()) {
-    ObjectTypePtrForLookup = const_cast<RecordType*>(
-                                               ObjectType->getAs<RecordType>());
-    if (!ObjectTypePtrForLookup && ObjectType->isDependentType())
-      ObjectTypePtrForLookup = Context.DependentTy.getAsOpaquePtr();
+    if (const Type *T = ObjectType->getAs<RecordType>())
+      ObjectTypePtrForLookup = ParsedType::make(QualType(T, 0));
+    else if (ObjectType->isDependentType())
+      ObjectTypePtrForLookup = ParsedType::make(Context.DependentTy);
   }
   
   // Convert the name of the type being destructed (following the ~) into a 
@@ -2920,9 +2935,9 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
   TypeSourceInfo *DestructedTypeInfo = 0;
   PseudoDestructorTypeStorage Destructed;
   if (SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) {
-    TypeTy *T = getTypeName(*SecondTypeName.Identifier, 
-                            SecondTypeName.StartLocation,
-                            S, &SS, true, ObjectTypePtrForLookup);
+    ParsedType T = getTypeName(*SecondTypeName.Identifier, 
+                               SecondTypeName.StartLocation,
+                               S, &SS, true, ObjectTypePtrForLookup);
     if (!T && 
         ((SS.isSet() && !computeDeclContext(SS, false)) ||
          (!SS.isSet() && ObjectType->isDependentType()))) {
@@ -2949,7 +2964,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
     ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                        TemplateId->getTemplateArgs(),
                                        TemplateId->NumArgs);
-    TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+    TypeResult T = ActOnTemplateIdType(TemplateId->Template,
                                        TemplateId->TemplateNameLoc,
                                        TemplateId->LAngleLoc,
                                        TemplateArgsPtr,
@@ -2976,9 +2991,9 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
   if (FirstTypeName.getKind() == UnqualifiedId::IK_TemplateId || 
       FirstTypeName.Identifier) {
     if (FirstTypeName.getKind() == UnqualifiedId::IK_Identifier) {
-      TypeTy *T = getTypeName(*FirstTypeName.Identifier, 
-                              FirstTypeName.StartLocation,
-                              S, &SS, false, ObjectTypePtrForLookup);
+      ParsedType T = getTypeName(*FirstTypeName.Identifier, 
+                                 FirstTypeName.StartLocation,
+                                 S, &SS, false, ObjectTypePtrForLookup);
       if (!T) {
         Diag(FirstTypeName.StartLocation, 
              diag::err_pseudo_dtor_destructor_non_type)
@@ -2997,7 +3012,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
       ASTTemplateArgsPtr TemplateArgsPtr(*this,
                                          TemplateId->getTemplateArgs(),
                                          TemplateId->NumArgs);
-      TypeResult T = ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+      TypeResult T = ActOnTemplateIdType(TemplateId->Template,
                                          TemplateId->TemplateNameLoc,
                                          TemplateId->LAngleLoc,
                                          TemplateArgsPtr,
@@ -3015,7 +3030,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
                                                   FirstTypeName.StartLocation);
 
     
-  return BuildPseudoDestructorExpr(move(Base), OpLoc, OpKind, SS,
+  return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, SS,
                                    ScopeTypeInfo, CCLoc, TildeLoc,
                                    Destructed, HasTrailingLParen);
 }
@@ -3028,7 +3043,7 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
     assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
 
   MemberExpr *ME = 
-      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, 
+      new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method,
                                SourceLocation(), Method->getType());
   QualType ResultType = Method->getCallResultType();
   MarkDeclarationReferenced(Exp->getLocStart(), Method);
@@ -3038,12 +3053,7 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
   return CE;
 }
 
-Sema::OwningExprResult Sema::ActOnFinishFullExpr(ExprArg Arg) {
-  Expr *FullExpr = Arg.takeAs<Expr>();
-  if (FullExpr)
-    FullExpr = MaybeCreateCXXExprWithTemporaries(FullExpr);
-  else
-    return ExprError();
-  
-  return Owned(FullExpr);
+ExprResult Sema::ActOnFinishFullExpr(Expr *FullExpr) {
+  if (!FullExpr) return ExprError();
+  return MaybeCreateCXXExprWithTemporaries(FullExpr);
 }
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 9f43471..b56159c 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -11,9 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Initialization.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprObjC.h"
@@ -23,9 +24,9 @@
 
 using namespace clang;
 
-Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
-                                              ExprTy **strings,
-                                              unsigned NumStrings) {
+ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
+                                        Expr **strings,
+                                        unsigned NumStrings) {
   StringLiteral **Strings = reinterpret_cast<StringLiteral**>(strings);
 
   // Most ObjC strings are formed out of a single piece.  However, we *can*
@@ -50,14 +51,11 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
         return true;
       }
 
-      // Get the string data.
-      StrBuf.append(S->getStrData(), S->getStrData()+S->getByteLength());
+      // Append the string.
+      StrBuf += S->getString();
 
       // Get the locations of the string tokens.
       StrLocs.append(S->tokloc_begin(), S->tokloc_end());
-
-      // Free the temporary string.
-      S->Destroy(Context);
     }
 
     // Create the aggregate string with the appropriate content and location
@@ -135,11 +133,11 @@ Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
   return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc);
 }
 
-Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
-                                                 SourceLocation EncodeLoc,
-                                                 SourceLocation LParenLoc,
-                                                 TypeTy *ty,
-                                                 SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
+                                           SourceLocation EncodeLoc,
+                                           SourceLocation LParenLoc,
+                                           ParsedType ty,
+                                           SourceLocation RParenLoc) {
   // FIXME: Preserve type source info ?
   TypeSourceInfo *TInfo;
   QualType EncodedType = GetTypeFromParser(ty, &TInfo);
@@ -150,28 +148,33 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
   return BuildObjCEncodeExpression(AtLoc, TInfo, RParenLoc);
 }
 
-Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
-                                                   SourceLocation AtLoc,
-                                                   SourceLocation SelLoc,
-                                                   SourceLocation LParenLoc,
-                                                   SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
+                                             SourceLocation AtLoc,
+                                             SourceLocation SelLoc,
+                                             SourceLocation LParenLoc,
+                                             SourceLocation RParenLoc) {
   ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(Sel,
-                             SourceRange(LParenLoc, RParenLoc), false);
+                             SourceRange(LParenLoc, RParenLoc), false, false);
   if (!Method)
     Method = LookupFactoryMethodInGlobalPool(Sel,
                                           SourceRange(LParenLoc, RParenLoc));
   if (!Method)
     Diag(SelLoc, diag::warn_undeclared_selector) << Sel;
 
+  llvm::DenseMap<Selector, SourceLocation>::iterator Pos
+    = ReferencedSelectors.find(Sel);
+  if (Pos == ReferencedSelectors.end())
+    ReferencedSelectors.insert(std::make_pair(Sel, SelLoc));
+
   QualType Ty = Context.getObjCSelType();
   return new (Context) ObjCSelectorExpr(Ty, Sel, AtLoc, RParenLoc);
 }
 
-Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
-                                                   SourceLocation AtLoc,
-                                                   SourceLocation ProtoLoc,
-                                                   SourceLocation LParenLoc,
-                                                   SourceLocation RParenLoc) {
+ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
+                                             SourceLocation AtLoc,
+                                             SourceLocation ProtoLoc,
+                                             SourceLocation LParenLoc,
+                                             SourceLocation RParenLoc) {
   ObjCProtocolDecl* PDecl = LookupProtocol(ProtocolId, ProtoLoc);
   if (!PDecl) {
     Diag(ProtoLoc, diag::err_undeclared_protocol) << ProtocolId;
@@ -239,7 +242,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
       return true;
 
     InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
-    OwningExprResult ArgE = PerformCopyInitialization(Entity,
+    ExprResult ArgE = PerformCopyInitialization(Entity,
                                                       SourceLocation(),
                                                       Owned(argExpr->Retain()));
     if (ArgE.isInvalid())
@@ -329,7 +332,7 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
 
 /// HandleExprPropertyRefExpr - Handle foo.bar where foo is a pointer to an
 /// objective C interface.  This is a property reference expression.
-Action::OwningExprResult Sema::
+ExprResult Sema::
 HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
                           Expr *BaseExpr, DeclarationName MemberName,
                           SourceLocation MemberLoc) {
@@ -431,7 +434,7 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
 
 
 
-Action::OwningExprResult Sema::
+ExprResult Sema::
 ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
                           IdentifierInfo &propertyName,
                           SourceLocation receiverNameLoc,
@@ -529,8 +532,8 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
                                                SourceLocation NameLoc,
                                                bool IsSuper,
                                                bool HasTrailingDot,
-                                               TypeTy *&ReceiverType) {
-  ReceiverType = 0;
+                                               ParsedType &ReceiverType) {
+  ReceiverType = ParsedType();
 
   // If the identifier is "super" and there is no trailing dot, we're
   // messaging super.
@@ -577,7 +580,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
     //  We have a class message, and T is the type we're
     //  messaging. Build source-location information for it.
     TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
-    ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+    ReceiverType = CreateParsedType(T, TSInfo);
     return ObjCClassMessage;
   }
   }
@@ -604,7 +607,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
 
         QualType T = Context.getObjCInterfaceType(Class);
         TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
-        ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+        ReceiverType = CreateParsedType(T, TSInfo);
         return ObjCClassMessage;
       }
     } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
@@ -622,7 +625,7 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
   return ObjCInstanceMessage;
 }
 
-Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S, 
+ExprResult Sema::ActOnSuperMessage(Scope *S, 
                                                SourceLocation SuperLoc,
                                                Selector Sel,
                                                SourceLocation LBracLoc,
@@ -657,7 +660,7 @@ Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S,
     // message to the superclass instance.
     QualType SuperTy = Context.getObjCInterfaceType(Super);
     SuperTy = Context.getObjCObjectPointerType(SuperTy);
-    return BuildInstanceMessage(ExprArg(*this), SuperTy, SuperLoc,
+    return BuildInstanceMessage(0, SuperTy, SuperLoc,
                                 Sel, /*Method=*/0, LBracLoc, RBracLoc, 
                                 move(Args));
   }
@@ -698,7 +701,7 @@ Sema::OwningExprResult Sema::ActOnSuperMessage(Scope *S,
 /// \param RBrac The location of the closing square bracket ']'.
 ///
 /// \param Args The message arguments.
-Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
+ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
                                                QualType ReceiverType,
                                                SourceLocation SuperLoc,
                                                Selector Sel,
@@ -757,11 +760,8 @@ Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
   unsigned NumArgs = ArgsIn.size();
   Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release());
   if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, true,
-                                LBracLoc, RBracLoc, ReturnType)) {
-    for (unsigned I = 0; I != NumArgs; ++I)
-      Args[I]->Destroy(Context);
+                                LBracLoc, RBracLoc, ReturnType))
     return ExprError();
-  }
 
   // Construct the appropriate ObjCMessageExpr.
   Expr *Result;
@@ -780,8 +780,8 @@ Sema::OwningExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo,
 // ActOnClassMessage - used for both unary and keyword messages.
 // ArgExprs is optional - if it is present, the number of expressions
 // is obtained from Sel.getNumArgs().
-Sema::OwningExprResult Sema::ActOnClassMessage(Scope *S, 
-                                               TypeTy *Receiver,
+ExprResult Sema::ActOnClassMessage(Scope *S, 
+                                               ParsedType Receiver,
                                                Selector Sel,
                                                SourceLocation LBracLoc,
                                                SourceLocation SelectorLoc,
@@ -829,7 +829,7 @@ Sema::OwningExprResult Sema::ActOnClassMessage(Scope *S,
 /// \param RBrac The location of the closing square bracket ']'.
 ///
 /// \param Args The message arguments.
-Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
+ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
                                                   QualType ReceiverType,
                                                   SourceLocation SuperLoc,
                                                   Selector Sel,
@@ -839,7 +839,6 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
                                                   MultiExprArg ArgsIn) {
   // If we have a receiver expression, perform appropriate promotions
   // and determine receiver type.
-  Expr *Receiver = ReceiverE.takeAs<Expr>();
   if (Receiver) {
     if (Receiver->isTypeDependent()) {
       // If the receiver is type-dependent, we can't type-check anything
@@ -864,13 +863,16 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
 
   if (!Method) {
     // Handle messages to id.
-    if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType() ||
+    bool receiverIsId = ReceiverType->isObjCIdType();
+    if (receiverIsId || ReceiverType->isBlockPointerType() ||
         (Receiver && Context.isObjCNSObjectType(Receiver->getType()))) {
       Method = LookupInstanceMethodInGlobalPool(Sel, 
-                                              SourceRange(LBracLoc, RBracLoc));
+                                                SourceRange(LBracLoc, RBracLoc),
+                                                receiverIsId);
       if (!Method)
         Method = LookupFactoryMethodInGlobalPool(Sel, 
-                                               SourceRange(LBracLoc, RBracLoc));
+                                                 SourceRange(LBracLoc, RBracLoc),
+                                                 receiverIsId);
     } else if (ReceiverType->isObjCClassType() ||
                ReceiverType->isObjCQualifiedClassType()) {
       // Handle messages to Class.
@@ -892,12 +894,14 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
         // If not messaging 'self', look for any factory method named 'Sel'.
         if (!Receiver || !isSelfExpr(Receiver)) {
           Method = LookupFactoryMethodInGlobalPool(Sel, 
-                                               SourceRange(LBracLoc, RBracLoc));
+                                               SourceRange(LBracLoc, RBracLoc),
+                                                   true);
           if (!Method) {
             // If no class (factory) method was found, check if an _instance_
             // method of the same name exists in the root class only.
             Method = LookupInstanceMethodInGlobalPool(Sel,
-                                               SourceRange(LBracLoc, RBracLoc));
+                                               SourceRange(LBracLoc, RBracLoc),
+                                                      true);
             if (Method)
                 if (const ObjCInterfaceDecl *ID =
                   dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) {
@@ -931,7 +935,7 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
         ClassDecl = OCIType->getInterfaceDecl();
         // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
         // faster than the following method (which can do *many* linear searches).
-        // The idea is to add class info to InstanceMethodPool.
+        // The idea is to add class info to MethodPool.
         Method = ClassDecl->lookupInstanceMethod(Sel);
 
         if (!Method) {
@@ -952,7 +956,7 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
             // compatibility. FIXME: should we deviate??
             if (OCIType->qual_empty()) {
               Method = LookupInstanceMethodInGlobalPool(Sel,
-                                                 SourceRange(LBracLoc, RBracLoc));
+                                                 SourceRange(LBracLoc, RBracLoc)); 
               if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
                 Diag(Loc, diag::warn_maynot_respond)
                   << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
@@ -962,19 +966,18 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
         if (Method && DiagnoseUseOfDecl(Method, Loc))
           return ExprError();
       } else if (!Context.getObjCIdType().isNull() &&
-                 (ReceiverType->isPointerType() ||
-                  (ReceiverType->isIntegerType() &&
-                   ReceiverType->isScalarType()))) {
+                 (ReceiverType->isPointerType() || 
+                  ReceiverType->isIntegerType())) {
         // Implicitly convert integers and pointers to 'id' but emit a warning.
         Diag(Loc, diag::warn_bad_receiver_type)
           << ReceiverType 
           << Receiver->getSourceRange();
         if (ReceiverType->isPointerType())
           ImpCastExprToType(Receiver, Context.getObjCIdType(), 
-                            CastExpr::CK_BitCast);
+                            CK_BitCast);
         else
           ImpCastExprToType(Receiver, Context.getObjCIdType(),
-                            CastExpr::CK_IntegralToPointer);
+                            CK_IntegralToPointer);
         ReceiverType = Receiver->getType();
       } 
       else if (getLangOptions().CPlusPlus &&
@@ -983,7 +986,7 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
           Receiver = ICE->getSubExpr();
           ReceiverType = Receiver->getType();
         }
-        return BuildInstanceMessage(Owned(Receiver),
+        return BuildInstanceMessage(Receiver,
                                     ReceiverType,
                                     SuperLoc,
                                     Sel,
@@ -1030,18 +1033,17 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
 // ActOnInstanceMessage - used for both unary and keyword messages.
 // ArgExprs is optional - if it is present, the number of expressions
 // is obtained from Sel.getNumArgs().
-Sema::OwningExprResult Sema::ActOnInstanceMessage(Scope *S,
-                                                  ExprArg ReceiverE, 
-                                                  Selector Sel,
-                                                  SourceLocation LBracLoc,
-                                                  SourceLocation SelectorLoc,
-                                                  SourceLocation RBracLoc,
-                                                  MultiExprArg Args) {
-  Expr *Receiver = static_cast<Expr *>(ReceiverE.get());
+ExprResult Sema::ActOnInstanceMessage(Scope *S,
+                                      Expr *Receiver, 
+                                      Selector Sel,
+                                      SourceLocation LBracLoc,
+                                      SourceLocation SelectorLoc,
+                                      SourceLocation RBracLoc,
+                                      MultiExprArg Args) {
   if (!Receiver)
     return ExprError();
 
-  return BuildInstanceMessage(move(ReceiverE), Receiver->getType(),
+  return BuildInstanceMessage(Receiver, Receiver->getType(),
                               /*SuperLoc=*/SourceLocation(), Sel, /*Method=*/0, 
                               LBracLoc, RBracLoc, move(Args));
 }
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 7ad1775..a28fd7f 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -15,12 +15,13 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "Sema.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/TypeLoc.h"
@@ -263,9 +264,8 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field,
       return;
     }
     
-    Sema::OwningExprResult MemberInit
-      = InitSeq.Perform(SemaRef, MemberEntity, Kind, 
-                        Sema::MultiExprArg(SemaRef, 0, 0));
+    ExprResult MemberInit
+      = InitSeq.Perform(SemaRef, MemberEntity, Kind, MultiExprArg());
     if (MemberInit.isInvalid()) {
       hadError = true;
       return;
@@ -373,9 +373,8 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity,
         return;
       }
 
-      Sema::OwningExprResult ElementInit
-        = InitSeq.Perform(SemaRef, ElementEntity, Kind, 
-                          Sema::MultiExprArg(SemaRef, 0, 0));
+      ExprResult ElementInit
+        = InitSeq.Perform(SemaRef, ElementEntity, Kind, MultiExprArg());
       if (ElementInit.isInvalid()) {
         hadError = true;
         return;
@@ -678,9 +677,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
       InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1);
       
       if (Seq) {
-        Sema::OwningExprResult Result = 
-          Seq.Perform(SemaRef, Entity, Kind,
-                      Sema::MultiExprArg(SemaRef, (void **)&expr, 1));
+        ExprResult Result = 
+          Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
         if (Result.isInvalid())
           hadError = true;
         
@@ -740,13 +738,13 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
                                       unsigned &StructuredIndex) {
   if (Index < IList->getNumInits()) {
     Expr *expr = IList->getInit(Index);
-    if (isa<InitListExpr>(expr)) {
-      SemaRef.Diag(IList->getLocStart(),
-                    diag::err_many_braces_around_scalar_init)
-        << IList->getSourceRange();
-      hadError = true;
-      ++Index;
-      ++StructuredIndex;
+    if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) {
+      SemaRef.Diag(SubIList->getLocStart(),
+                    diag::warn_many_braces_around_scalar_init)
+        << SubIList->getSourceRange();
+
+      CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList,
+                      StructuredIndex);
       return;
     } else if (isa<DesignatedInitExpr>(expr)) {
       SemaRef.Diag(expr->getSourceRange().getBegin(),
@@ -758,7 +756,7 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
       return;
     }
 
-    Sema::OwningExprResult Result =
+    ExprResult Result =
       SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
                                         SemaRef.Owned(expr));
 
@@ -805,7 +803,7 @@ void InitListChecker::CheckReferenceType(const InitializedEntity &Entity,
       return;
     }
 
-    Sema::OwningExprResult Result =
+    ExprResult Result =
       SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(),
                                         SemaRef.Owned(expr));
 
@@ -1367,7 +1365,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
         if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false,
                                 Sema::CTC_NoKeywords) && 
             (ReplacementField = R.getAsSingle<FieldDecl>()) &&
-            ReplacementField->getDeclContext()->getLookupContext()
+            ReplacementField->getDeclContext()->getRedeclContext()
                                                       ->Equals(RT->getDecl())) {
           SemaRef.Diag(D->getFieldLoc(), 
                        diag::err_field_designator_unknown_suggest)
@@ -1813,10 +1811,10 @@ CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
   return false;
 }
 
-Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
+ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
                                                         SourceLocation Loc,
                                                         bool GNUSyntax,
-                                                        OwningExprResult Init) {
+                                                        ExprResult Init) {
   typedef DesignatedInitExpr::Designator ASTDesignator;
 
   bool Invalid = false;
@@ -2021,18 +2019,21 @@ void InitializationSequence::Step::Destroy() {
   switch (Kind) {
   case SK_ResolveAddressOfOverloadedFunction:
   case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseXValue:
   case SK_CastDerivedToBaseLValue:
   case SK_BindReference:
   case SK_BindReferenceToTemporary:
   case SK_ExtraneousCopyToTemporary:
   case SK_UserConversion:
   case SK_QualificationConversionRValue:
+  case SK_QualificationConversionXValue:
   case SK_QualificationConversionLValue:
   case SK_ListInitialization:
   case SK_ConstructorInitialization:
   case SK_ZeroInitialization:
   case SK_CAssignment:
   case SK_StringInit:
+  case SK_ObjCObjectConversion:
     break;
     
   case SK_ConversionSequence:
@@ -2091,9 +2092,14 @@ void InitializationSequence::AddAddressOverloadResolutionStep(
 }
 
 void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, 
-                                                      bool IsLValue) {
+                                                      ExprValueKind VK) {
   Step S;
-  S.Kind = IsLValue? SK_CastDerivedToBaseLValue : SK_CastDerivedToBaseRValue;
+  switch (VK) {
+  case VK_RValue: S.Kind = SK_CastDerivedToBaseRValue; break;
+  case VK_XValue: S.Kind = SK_CastDerivedToBaseXValue; break;
+  case VK_LValue: S.Kind = SK_CastDerivedToBaseLValue; break;
+  default: llvm_unreachable("No such category");
+  }
   S.Type = BaseType;
   Steps.push_back(S);
 }
@@ -2125,10 +2131,20 @@ void InitializationSequence::AddUserConversionStep(FunctionDecl *Function,
 }
 
 void InitializationSequence::AddQualificationConversionStep(QualType Ty,
-                                                            bool IsLValue) {
+                                                            ExprValueKind VK) {
   Step S;
-  S.Kind = IsLValue? SK_QualificationConversionLValue 
-                   : SK_QualificationConversionRValue;
+  S.Kind = SK_QualificationConversionRValue; // work around a gcc warning
+  switch (VK) {
+  case VK_RValue:
+    S.Kind = SK_QualificationConversionRValue;
+    break;
+  case VK_XValue:
+    S.Kind = SK_QualificationConversionXValue;
+    break;
+  case VK_LValue:
+    S.Kind = SK_QualificationConversionLValue;
+    break;
+  }
   S.Type = Ty;
   Steps.push_back(S);
 }
@@ -2184,6 +2200,13 @@ void InitializationSequence::AddStringInitStep(QualType T) {
   Steps.push_back(S);
 }
 
+void InitializationSequence::AddObjCObjectConversionStep(QualType T) {
+  Step S;
+  S.Kind = SK_ObjCObjectConversion;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
 void InitializationSequence::SetOverloadFailure(FailureKind Failure, 
                                                 OverloadingResult Result) {
   SequenceKind = FailedSequence;
@@ -2258,10 +2281,13 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
   QualType T2 = cv2T2.getUnqualifiedType();
 
   bool DerivedToBase;
+  bool ObjCConversion;
   assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), 
-                                         T1, T2, DerivedToBase) &&
+                                         T1, T2, DerivedToBase,
+                                         ObjCConversion) &&
          "Must have incompatible references when binding via conversion");
   (void)DerivedToBase;
+  (void)ObjCConversion;
 
   // Build the candidate set directly in the initialization sequence
   // structure, so that it will persist if we fail.
@@ -2278,6 +2304,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
     // The type we're converting to is a class type. Enumerate its constructors
     // to see if there is a suitable conversion.
     CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
+
     DeclContext::lookup_iterator Con, ConEnd;
     for (llvm::tie(Con, ConEnd) = S.LookupConstructors(T1RecordDecl);
          Con != ConEnd; ++Con) {
@@ -2305,6 +2332,8 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
       }
     }    
   }
+  if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
+    return OR_No_Viable_Function;
   
   const RecordType *T2RecordType = 0;
   if ((T2RecordType = T2->getAs<RecordType>()) &&
@@ -2352,13 +2381,15 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
       }
     }
   }
+  if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
+    return OR_No_Viable_Function;
   
   SourceLocation DeclLoc = Initializer->getLocStart();
 
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result 
-        = S.BestViableFunction(CandidateSet, DeclLoc, Best))
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best))
     return Result;
 
   FunctionDecl *Function = Best->Function;
@@ -2375,11 +2406,18 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
 
   // Determine whether we need to perform derived-to-base or 
   // cv-qualification adjustments.
+  ExprValueKind VK = VK_RValue;
+  if (T2->isLValueReferenceType())
+    VK = VK_LValue;
+  else if (const RValueReferenceType *RRef = T2->getAs<RValueReferenceType>())
+    VK = RRef->getPointeeType()->isFunctionType() ? VK_LValue : VK_XValue;
+
   bool NewDerivedToBase = false;
+  bool NewObjCConversion = false;
   Sema::ReferenceCompareResult NewRefRelationship
     = S.CompareReferenceRelationship(DeclLoc, T1, 
                                      T2.getNonLValueExprType(S.Context),
-                                     NewDerivedToBase);
+                                     NewDerivedToBase, NewObjCConversion);
   if (NewRefRelationship == Sema::Ref_Incompatible) {
     // If the type we've converted to is not reference-related to the
     // type we're looking for, then there is another conversion step
@@ -2394,10 +2432,14 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
     Sequence.AddDerivedToBaseCastStep(
                                 S.Context.getQualifiedType(T1,
                                   T2.getNonReferenceType().getQualifiers()), 
-                                  /*isLValue=*/true);
-  
+                                      VK);
+  else if (NewObjCConversion)
+    Sequence.AddObjCObjectConversionStep(
+                                S.Context.getQualifiedType(T1,
+                                  T2.getNonReferenceType().getQualifiers()));
+
   if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
-    Sequence.AddQualificationConversionStep(cv1T1, T2->isReferenceType());
+    Sequence.AddQualificationConversionStep(cv1T1, VK);
   
   Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
   return OR_Success;
@@ -2443,9 +2485,11 @@ static void TryReferenceInitialization(Sema &S,
   bool isLValueRef = DestType->isLValueReferenceType();
   bool isRValueRef = !isLValueRef;
   bool DerivedToBase = false;
+  bool ObjCConversion = false;
   Expr::Classification InitCategory = Initializer->Classify(S.Context);
   Sema::ReferenceCompareResult RefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase);
+    = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase,
+                                     ObjCConversion);
 
   // C++0x [dcl.init.ref]p5:
   //   A reference to type "cv1 T1" is initialized by an expression of type 
@@ -2472,9 +2516,13 @@ static void TryReferenceInitialization(Sema &S,
       if (DerivedToBase)
         Sequence.AddDerivedToBaseCastStep(
                          S.Context.getQualifiedType(T1, T2Quals), 
-                         /*isLValue=*/true);
+                         VK_LValue);
+      else if (ObjCConversion)
+        Sequence.AddObjCObjectConversionStep(
+                                     S.Context.getQualifiedType(T1, T2Quals));
+
       if (T1Quals != T2Quals)
-        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
+        Sequence.AddQualificationConversionStep(cv1T1, VK_LValue);
       bool BindingTemporary = T1Quals.hasConst() && !T1Quals.hasVolatile() &&
         (Initializer->getBitField() || Initializer->refersToVectorElement());
       Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary);
@@ -2531,6 +2579,7 @@ static void TryReferenceInitialization(Sema &S,
 
   //       - [If T1 is not a function type], if T2 is a class type and
   if (!T1Function && T2->isRecordType()) {
+    bool isXValue = InitCategory.isXValue();
     //       - the initializer expression is an rvalue and "cv1 T1" is 
     //         reference-compatible with "cv2 T2", or
     if (InitCategory.isRValue() && 
@@ -2550,10 +2599,15 @@ static void TryReferenceInitialization(Sema &S,
       if (DerivedToBase)
         Sequence.AddDerivedToBaseCastStep(
                          S.Context.getQualifiedType(T1, T2Quals), 
-                         /*isLValue=*/false);
+                         isXValue ? VK_XValue : VK_RValue);
+      else if (ObjCConversion)
+        Sequence.AddObjCObjectConversionStep(
+                                     S.Context.getQualifiedType(T1, T2Quals));
+
       if (T1Quals != T2Quals)
-        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
-      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+        Sequence.AddQualificationConversionStep(cv1T1,
+                                            isXValue ? VK_XValue : VK_RValue);
+      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue);
       return;
     }
 
@@ -2717,7 +2771,7 @@ static void TryConstructorInitialization(Sema &S,
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result 
-        = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
     Sequence.SetOverloadFailure(
                           InitializationSequence::FK_ConstructorOverloadFailed, 
                                 Result);
@@ -2803,8 +2857,8 @@ static void TryDefaultInitialization(Sema &S,
   //       constructor for T is called (and the initialization is ill-formed if
   //       T has no accessible default constructor);
   if (DestType->isRecordType() && S.getLangOptions().CPlusPlus) {
-    return TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType,
-                                        Sequence);
+    TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, Sequence);
+    return;
   }
   
   //     - otherwise, no initialization is performed.
@@ -2927,7 +2981,7 @@ static void TryUserDefinedConversion(Sema &S,
   // Perform overload resolution. If it fails, return the failed result.  
   OverloadCandidateSet::iterator Best;
   if (OverloadingResult Result
-        = S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+        = CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
     Sequence.SetOverloadFailure(
                         InitializationSequence::FK_UserConversionOverloadFailed, 
                                 Result);
@@ -2969,24 +3023,6 @@ static void TryUserDefinedConversion(Sema &S,
   }
 }
 
-bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
-                                 const InitializedEntity &Entity,
-                                 Expr *Initializer,
-                                 bool SuppressUserConversions,
-                                 bool AllowExplicitConversions,
-                                 bool InOverloadResolution) {
-  ImplicitConversionSequence ICS
-    = TryImplicitConversion(Initializer, Entity.getType(),
-                            SuppressUserConversions,
-                            AllowExplicitConversions, 
-                            InOverloadResolution);
-  if (ICS.isBad()) return true;
-
-  // Perform the actual conversion.
-  Sequence.AddConversionSequenceStep(ICS, Entity.getType());
-  return false;
-}
-
 InitializationSequence::InitializationSequence(Sema &S,
                                                const InitializedEntity &Entity,
                                                const InitializationKind &Kind,
@@ -3239,10 +3275,10 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) {
 /// \returns An expression that copies the initializer expression into
 /// a temporary object, or an error expression if a copy could not be
 /// created.
-static Sema::OwningExprResult CopyObject(Sema &S,
+static ExprResult CopyObject(Sema &S,
                                          QualType T,
                                          const InitializedEntity &Entity,
-                                         Sema::OwningExprResult CurInit,
+                                         ExprResult CurInit,
                                          bool IsExtraneousCopy) {
   // Determine which class type we're copying to.
   Expr *CurInitExpr = (Expr *)CurInit.get();
@@ -3318,7 +3354,7 @@ static Sema::OwningExprResult CopyObject(Sema &S,
   }
   
   OverloadCandidateSet::iterator Best;
-  switch (S.BestViableFunction(CandidateSet, Loc, Best)) {
+  switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
   case OR_Success:
     break;
       
@@ -3328,19 +3364,17 @@ static Sema::OwningExprResult CopyObject(Sema &S,
            : diag::err_temp_copy_no_viable)
       << (int)Entity.getKind() << CurInitExpr->getType()
       << CurInitExpr->getSourceRange();
-    S.PrintOverloadCandidates(CandidateSet, Sema::OCD_AllCandidates,
-                              &CurInitExpr, 1);
+    CandidateSet.NoteCandidates(S, OCD_AllCandidates, &CurInitExpr, 1);
     if (!IsExtraneousCopy || S.isSFINAEContext())
-      return S.ExprError();
+      return ExprError();
     return move(CurInit);
       
   case OR_Ambiguous:
     S.Diag(Loc, diag::err_temp_copy_ambiguous)
       << (int)Entity.getKind() << CurInitExpr->getType()
       << CurInitExpr->getSourceRange();
-    S.PrintOverloadCandidates(CandidateSet, Sema::OCD_ViableCandidates,
-                              &CurInitExpr, 1);
-    return S.ExprError();
+    CandidateSet.NoteCandidates(S, OCD_ViableCandidates, &CurInitExpr, 1);
+    return ExprError();
     
   case OR_Deleted:
     S.Diag(Loc, diag::err_temp_copy_deleted)
@@ -3348,11 +3382,11 @@ static Sema::OwningExprResult CopyObject(Sema &S,
       << CurInitExpr->getSourceRange();
     S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
       << Best->Function->isDeleted();
-    return S.ExprError();
+    return ExprError();
   }
 
   CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
-  ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+  ASTOwningVector<Expr*> ConstructorArgs(S);
   CurInit.release(); // Ownership transferred into MultiExprArg, below.
 
   S.CheckConstructorAccess(Loc, Constructor, Entity,
@@ -3387,16 +3421,15 @@ static Sema::OwningExprResult CopyObject(Sema &S,
   // Determine the arguments required to actually perform the
   // constructor call (we might have derived-to-base conversions, or
   // the copy constructor may have default arguments).
-  if (S.CompleteConstructorCall(Constructor,
-                                Sema::MultiExprArg(S, 
-                                                   (void **)&CurInitExpr,
-                                                   1),
+  if (S.CompleteConstructorCall(Constructor, MultiExprArg(&CurInitExpr, 1),
                                 Loc, ConstructorArgs))
-    return S.ExprError();
+    return ExprError();
 
   // Actually perform the constructor call.
   CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
-                                    move_arg(ConstructorArgs));
+                                    move_arg(ConstructorArgs),
+                                    /*ZeroInit*/ false,
+                                    CXXConstructExpr::CK_Complete);
   
   // If we're supposed to bind temporaries, do so.
   if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity))
@@ -3418,16 +3451,16 @@ void InitializationSequence::PrintInitLocationNote(Sema &S,
   }
 }
 
-Action::OwningExprResult 
+ExprResult 
 InitializationSequence::Perform(Sema &S,
                                 const InitializedEntity &Entity,
                                 const InitializationKind &Kind,
-                                Action::MultiExprArg Args,
+                                MultiExprArg Args,
                                 QualType *ResultType) {
   if (SequenceKind == FailedSequence) {
     unsigned NumArgs = Args.size();
     Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs);
-    return S.ExprError();
+    return ExprError();
   }
   
   if (SequenceKind == DependentSequence) {
@@ -3471,7 +3504,7 @@ InitializationSequence::Perform(Sema &S,
     }
 
     if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast())
-      return Sema::OwningExprResult(S, Args.release()[0]);
+      return ExprResult(Args.release()[0]);
 
     if (Args.size() == 0)
       return S.Owned((Expr *)0);
@@ -3495,7 +3528,7 @@ InitializationSequence::Perform(Sema &S,
     *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :
                                      Entity.getType();
 
-  Sema::OwningExprResult CurInit = S.Owned((Expr *)0);
+  ExprResult CurInit = S.Owned((Expr *)0);
   
   assert(!Steps.empty() && "Cannot have an empty initialization sequence");
   
@@ -3505,21 +3538,24 @@ InitializationSequence::Perform(Sema &S,
   switch (Steps.front().Kind) {
   case SK_ResolveAddressOfOverloadedFunction:
   case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseXValue:
   case SK_CastDerivedToBaseLValue:
   case SK_BindReference:
   case SK_BindReferenceToTemporary:
   case SK_ExtraneousCopyToTemporary:
   case SK_UserConversion:
   case SK_QualificationConversionLValue:
+  case SK_QualificationConversionXValue:
   case SK_QualificationConversionRValue:
   case SK_ConversionSequence:
   case SK_ListInitialization:
   case SK_CAssignment:
   case SK_StringInit:
+  case SK_ObjCObjectConversion:
     assert(Args.size() == 1);
-    CurInit = Sema::OwningExprResult(S, ((Expr **)(Args.get()))[0]->Retain());
+    CurInit = ExprResult(((Expr **)(Args.get()))[0]->Retain());
     if (CurInit.isInvalid())
-      return S.ExprError();
+      return ExprError();
     break;
     
   case SK_ConstructorInitialization:
@@ -3533,7 +3569,7 @@ InitializationSequence::Perform(Sema &S,
   for (step_iterator Step = step_begin(), StepEnd = step_end();
        Step != StepEnd; ++Step) {
     if (CurInit.isInvalid())
-      return S.ExprError();
+      return ExprError();
     
     Expr *CurInitExpr = (Expr *)CurInit.get();
     QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType();
@@ -3550,11 +3586,12 @@ InitializationSequence::Perform(Sema &S,
       break;
         
     case SK_CastDerivedToBaseRValue:
+    case SK_CastDerivedToBaseXValue:
     case SK_CastDerivedToBaseLValue: {
       // We have a derived-to-base cast that produces either an rvalue or an
       // lvalue. Perform that cast.
       
-      CXXBaseSpecifierArray BasePath;
+      CXXCastPath BasePath;
 
       // Casts to inaccessible base classes are allowed with C-style casts.
       bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
@@ -3562,7 +3599,7 @@ InitializationSequence::Perform(Sema &S,
                                          CurInitExpr->getLocStart(),
                                          CurInitExpr->getSourceRange(), 
                                          &BasePath, IgnoreBaseAccess))
-        return S.ExprError();
+        return ExprError();
         
       if (S.BasePathInvolvesVirtualBase(BasePath)) {
         QualType T = SourceType;
@@ -3573,11 +3610,17 @@ InitializationSequence::Perform(Sema &S,
                            cast<CXXRecordDecl>(RecordTy->getDecl()));
       }
 
-      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
-                                                    CastExpr::CK_DerivedToBase,
-                                                    (Expr*)CurInit.release(),
-                                                    BasePath,
-                                     Step->Kind == SK_CastDerivedToBaseLValue));
+      ExprValueKind VK =
+          Step->Kind == SK_CastDerivedToBaseLValue ?
+              VK_LValue :
+              (Step->Kind == SK_CastDerivedToBaseXValue ?
+                   VK_XValue :
+                   VK_RValue);
+      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+                                                 Step->Type,
+                                                 CK_DerivedToBase,
+                                                 CurInit.get(),
+                                                 &BasePath, VK));
       break;
     }
         
@@ -3589,7 +3632,7 @@ InitializationSequence::Perform(Sema &S,
           << BitField->getDeclName()
           << CurInitExpr->getSourceRange();
         S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
-        return S.ExprError();
+        return ExprError();
       }
 
       if (CurInitExpr->refersToVectorElement()) {
@@ -3598,14 +3641,14 @@ InitializationSequence::Perform(Sema &S,
           << Entity.getType().isVolatileQualified()
           << CurInitExpr->getSourceRange();
         PrintInitLocationNote(S, Entity);
-        return S.ExprError();
+        return ExprError();
       }
         
       // Reference binding does not have any corresponding ASTs.
 
       // Check exception specifications
       if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
-        return S.ExprError();
+        return ExprError();
 
       break;
 
@@ -3614,7 +3657,7 @@ InitializationSequence::Perform(Sema &S,
 
       // Check exception specifications
       if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
-        return S.ExprError();
+        return ExprError();
 
       break;
         
@@ -3626,7 +3669,7 @@ InitializationSequence::Perform(Sema &S,
     case SK_UserConversion: {
       // We have a user-defined conversion that invokes either a constructor
       // or a conversion function.
-      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      CastKind CastKind = CK_Unknown;
       bool IsCopy = false;
       FunctionDecl *Fn = Step->Function.Function;
       DeclAccessPair FoundFn = Step->Function.FoundDecl;
@@ -3634,30 +3677,30 @@ InitializationSequence::Perform(Sema &S,
       bool IsLvalue = false;
       if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
         // Build a call to the selected constructor.
-        ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+        ASTOwningVector<Expr*> ConstructorArgs(S);
         SourceLocation Loc = CurInitExpr->getLocStart();
         CurInit.release(); // Ownership transferred into MultiExprArg, below.
 
         // Determine the arguments required to actually perform the constructor
         // call.
         if (S.CompleteConstructorCall(Constructor,
-                                      Sema::MultiExprArg(S, 
-                                                         (void **)&CurInitExpr,
-                                                         1),
+                                      MultiExprArg(&CurInitExpr, 1),
                                       Loc, ConstructorArgs))
-          return S.ExprError();
+          return ExprError();
         
         // Build the an expression that constructs a temporary.
         CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor, 
-                                          move_arg(ConstructorArgs));
+                                          move_arg(ConstructorArgs),
+                                          /*ZeroInit*/ false,
+                                          CXXConstructExpr::CK_Complete);
         if (CurInit.isInvalid())
-          return S.ExprError();
+          return ExprError();
 
         S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity,
                                  FoundFn.getAccess());
         S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation());
         
-        CastKind = CastExpr::CK_ConstructorConversion;
+        CastKind = CK_ConstructorConversion;
         QualType Class = S.Context.getTypeDeclType(Constructor->getParent());
         if (S.Context.hasSameUnqualifiedType(SourceType, Class) ||
             S.IsDerivedFrom(SourceType, Class))
@@ -3677,7 +3720,7 @@ InitializationSequence::Perform(Sema &S,
         // we don't want to turn off access control here for c-style casts.
         if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
                                                   FoundFn, Conversion))
-          return S.ExprError();
+          return ExprError();
 
         // Do a little dance to make sure that CurInit has the proper
         // pointer.
@@ -3687,9 +3730,9 @@ InitializationSequence::Perform(Sema &S,
         CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn,
                                                    Conversion));
         if (CurInit.isInvalid() || !CurInit.get())
-          return S.ExprError();
+          return ExprError();
         
-        CastKind = CastExpr::CK_UserDefinedConversion;
+        CastKind = CK_UserDefinedConversion;
         
         CreatedObject = Conversion->getResultType()->isRecordType();
       }
@@ -3711,35 +3754,41 @@ InitializationSequence::Perform(Sema &S,
       }
       
       CurInitExpr = CurInit.takeAs<Expr>();
-      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
-                                                         CastKind, 
-                                                         CurInitExpr,
-                                                        CXXBaseSpecifierArray(),
-                                                         IsLvalue));
+      // FIXME: xvalues
+      CurInit = S.Owned(ImplicitCastExpr::Create(S.Context,
+                                                 CurInitExpr->getType(),
+                                                 CastKind, CurInitExpr, 0,
+                                           IsLvalue ? VK_LValue : VK_RValue));
       
       if (RequiresCopy)
         CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity,
                              move(CurInit), /*IsExtraneousCopy=*/false);
-      
+
       break;
     }
-        
+
     case SK_QualificationConversionLValue:
-    case SK_QualificationConversionRValue:
+    case SK_QualificationConversionXValue:
+    case SK_QualificationConversionRValue: {
       // Perform a qualification conversion; these can never go wrong.
-      S.ImpCastExprToType(CurInitExpr, Step->Type,
-                          CastExpr::CK_NoOp,
-                          Step->Kind == SK_QualificationConversionLValue);
+      ExprValueKind VK =
+          Step->Kind == SK_QualificationConversionLValue ?
+              VK_LValue :
+              (Step->Kind == SK_QualificationConversionXValue ?
+                   VK_XValue :
+                   VK_RValue);
+      S.ImpCastExprToType(CurInitExpr, Step->Type, CK_NoOp, VK);
       CurInit.release();
       CurInit = S.Owned(CurInitExpr);
       break;
-        
+    }
+
     case SK_ConversionSequence: {
       bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
 
       if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS,
                                       Sema::AA_Converting, IgnoreBaseAccess))
-        return S.ExprError();
+        return ExprError();
         
       CurInit.release();
       CurInit = S.Owned(CurInitExpr);
@@ -3750,7 +3799,7 @@ InitializationSequence::Perform(Sema &S,
       InitListExpr *InitList = cast<InitListExpr>(CurInitExpr);
       QualType Ty = Step->Type;
       if (S.CheckInitList(Entity, InitList, ResultType? *ResultType : Ty))
-        return S.ExprError();
+        return ExprError();
 
       CurInit.release();
       CurInit = S.Owned(InitList);
@@ -3763,16 +3812,29 @@ InitializationSequence::Perform(Sema &S,
         = cast<CXXConstructorDecl>(Step->Function.Function);
       
       // Build a call to the selected constructor.
-      ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
-      SourceLocation Loc = Kind.getLocation();
-          
+      ASTOwningVector<Expr*> ConstructorArgs(S);
+      SourceLocation Loc = (Kind.isCopyInit() && Kind.getEqualLoc().isValid())
+                             ? Kind.getEqualLoc()
+                             : Kind.getLocation();
+
+      if (Kind.getKind() == InitializationKind::IK_Default) {
+        // Force even a trivial, implicit default constructor to be
+        // semantically checked. We do this explicitly because we don't build
+        // the definition for completely trivial constructors.
+        CXXRecordDecl *ClassDecl = Constructor->getParent();
+        assert(ClassDecl && "No parent class for constructor.");
+        if (Constructor->isImplicit() && Constructor->isDefaultConstructor() &&
+            ClassDecl->hasTrivialConstructor() && !Constructor->isUsed(false))
+          S.DefineImplicitDefaultConstructor(Loc, Constructor);
+      }
+
       // Determine the arguments required to actually perform the constructor
       // call.
       if (S.CompleteConstructorCall(Constructor, move(Args), 
                                     Loc, ConstructorArgs))
-        return S.ExprError();
+        return ExprError();
           
-      // Build the expression that constructs a temporary.
+      
       if (Entity.getKind() == InitializedEntity::EK_Temporary &&
           NumArgs != 1 && // FIXME: Hack to work around cast weirdness
           (Kind.getKind() == InitializationKind::IK_Direct ||
@@ -3780,11 +3842,11 @@ InitializationSequence::Perform(Sema &S,
         // An explicitly-constructed temporary, e.g., X(1, 2).
         unsigned NumExprs = ConstructorArgs.size();
         Expr **Exprs = (Expr **)ConstructorArgs.take();
-        S.MarkDeclarationReferenced(Kind.getLocation(), Constructor);
+        S.MarkDeclarationReferenced(Loc, Constructor);
         CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
                                                                  Constructor,
                                                               Entity.getType(),
-                                                            Kind.getLocation(),
+                                                                 Loc,
                                                                  Exprs, 
                                                                  NumExprs,
                                                 Kind.getParenRange().getEnd(),
@@ -3815,7 +3877,7 @@ InitializationSequence::Perform(Sema &S,
                                             ConstructKind);
       }
       if (CurInit.isInvalid())
-        return S.ExprError();
+        return ExprError();
 
       // Only check access if all of that succeeded.
       S.CheckConstructorAccess(Loc, Constructor, Entity,
@@ -3867,7 +3929,7 @@ InitializationSequence::Perform(Sema &S,
                                      getAssignmentAction(Entity),
                                      &Complained)) {
         PrintInitLocationNote(S, Entity);
-        return S.ExprError();
+        return ExprError();
       } else if (Complained)
         PrintInitLocationNote(S, Entity);
 
@@ -3881,6 +3943,14 @@ InitializationSequence::Perform(Sema &S,
       CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, S);
       break;
     }
+
+    case SK_ObjCObjectConversion:
+      S.ImpCastExprToType(CurInitExpr, Step->Type, 
+                          CK_ObjCObjectLValueCast,
+                          S.CastCategory(CurInitExpr));
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);
+      break;
     }
   }
   
@@ -3937,16 +4007,14 @@ bool InitializationSequence::Diagnose(Sema &S,
           << DestType << Args[0]->getType()
           << Args[0]->getSourceRange();
 
-      S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_ViableCandidates,
-                                Args, NumArgs);
+      FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args, NumArgs);
       break;
         
     case OR_No_Viable_Function:
       S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
         << Args[0]->getType() << DestType.getNonReferenceType()
         << Args[0]->getSourceRange();
-      S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
-                                Args, NumArgs);
+      FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
       break;
         
     case OR_Deleted: {
@@ -3954,9 +4022,8 @@ bool InitializationSequence::Diagnose(Sema &S,
         << Args[0]->getType() << DestType.getNonReferenceType()
         << Args[0]->getSourceRange();
       OverloadCandidateSet::iterator Best;
-      OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
-                                                   Kind.getLocation(),
-                                                   Best);
+      OverloadingResult Ovl
+        = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
       if (Ovl == OR_Deleted) {
         S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
           << Best->Function->isDeleted();
@@ -4049,8 +4116,8 @@ bool InitializationSequence::Diagnose(Sema &S,
       case OR_Ambiguous:
         S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init)
           << DestType << ArgsRange;
-        S.PrintOverloadCandidates(FailedCandidateSet,
-                                  Sema::OCD_ViableCandidates, Args, NumArgs);
+        FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates,
+                                          Args, NumArgs);
         break;
         
       case OR_No_Viable_Function:
@@ -4095,17 +4162,15 @@ bool InitializationSequence::Diagnose(Sema &S,
 
         S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init)
           << DestType << ArgsRange;
-        S.PrintOverloadCandidates(FailedCandidateSet, Sema::OCD_AllCandidates,
-                                  Args, NumArgs);
+        FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs);
         break;
         
       case OR_Deleted: {
         S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
           << true << DestType << ArgsRange;
         OverloadCandidateSet::iterator Best;
-        OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
-                                                     Kind.getLocation(),
-                                                     Best);
+        OverloadingResult Ovl
+          = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
         if (Ovl == OR_Deleted) {
           S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
             << Best->Function->isDeleted();
@@ -4288,6 +4353,10 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
       OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")";
       break;
       
+    case SK_CastDerivedToBaseXValue:
+      OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")";
+      break;
+      
     case SK_CastDerivedToBaseLValue:
       OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")";
       break;
@@ -4307,10 +4376,13 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
     case SK_UserConversion:
       OS << "user-defined conversion via " << S->Function.Function;
       break;
-      
+
     case SK_QualificationConversionRValue:
       OS << "qualification conversion (rvalue)";
 
+    case SK_QualificationConversionXValue:
+      OS << "qualification conversion (xvalue)";
+
     case SK_QualificationConversionLValue:
       OS << "qualification conversion (lvalue)";
       break;
@@ -4340,6 +4412,10 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const {
     case SK_StringInit:
       OS << "string initialization";
       break;
+
+    case SK_ObjCObjectConversion:
+      OS << "Objective-C object conversion";
+      break;
     }
   }
 }
@@ -4351,10 +4427,10 @@ void InitializationSequence::dump() const {
 //===----------------------------------------------------------------------===//
 // Initialization helper functions
 //===----------------------------------------------------------------------===//
-Sema::OwningExprResult 
+ExprResult 
 Sema::PerformCopyInitialization(const InitializedEntity &Entity,
                                 SourceLocation EqualLoc,
-                                OwningExprResult Init) {
+                                ExprResult Init) {
   if (Init.isInvalid())
     return ExprError();
 
@@ -4368,6 +4444,5 @@ Sema::PerformCopyInitialization(const InitializedEntity &Entity,
                                                            EqualLoc);
   InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);
   Init.release();
-  return Seq.Perform(*this, Entity, Kind, 
-                     MultiExprArg(*this, (void**)&InitE, 1));
+  return Seq.Perform(*this, Entity, Kind, MultiExprArg(&InitE, 1));
 }
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
deleted file mode 100644
index 44c36a7..0000000
--- a/lib/Sema/SemaInit.h
+++ /dev/null
@@ -1,765 +0,0 @@
-//===--- SemaInit.h - Semantic Analysis for Initializers --------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides supporting data types for initialization of objects.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_CLANG_SEMA_INIT_H
-#define LLVM_CLANG_SEMA_INIT_H
-
-#include "SemaOverload.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "clang/Parse/Action.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-
-namespace llvm {
-  class raw_ostream;
-}
-
-namespace clang {
-  
-class CXXBaseSpecifier;
-class DeclaratorDecl;
-class DeclaratorInfo;
-class FieldDecl;
-class FunctionDecl;
-class ParmVarDecl;
-class Sema;
-class TypeLoc;
-class VarDecl;
-  
-/// \brief Describes an entity that is being initialized.
-class InitializedEntity {
-public:
-  /// \brief Specifies the kind of entity being initialized.
-  enum EntityKind {
-    /// \brief The entity being initialized is a variable.
-    EK_Variable,
-    /// \brief The entity being initialized is a function parameter.
-    EK_Parameter,
-    /// \brief The entity being initialized is the result of a function call.
-    EK_Result,
-    /// \brief The entity being initialized is an exception object that
-    /// is being thrown.
-    EK_Exception,
-    /// \brief The entity being initialized is a non-static data member 
-    /// subobject.
-    EK_Member,
-    /// \brief The entity being initialized is an element of an array.
-    EK_ArrayElement,
-    /// \brief The entity being initialized is an object (or array of
-    /// objects) allocated via new.
-    EK_New,
-    /// \brief The entity being initialized is a temporary object.
-    EK_Temporary,
-    /// \brief The entity being initialized is a base member subobject.
-    EK_Base,
-    /// \brief The entity being initialized is an element of a vector.
-    /// or vector.
-    EK_VectorElement,
-    /// \brief The entity being initialized is a field of block descriptor for
-    /// the copied-in c++ object.
-    EK_BlockElement
-  };
-  
-private:
-  /// \brief The kind of entity being initialized.
-  EntityKind Kind;
-
-  /// \brief If non-NULL, the parent entity in which this
-  /// initialization occurs.
-  const InitializedEntity *Parent;
-
-  /// \brief The type of the object or reference being initialized.
-  QualType Type;
-  
-  union {
-    /// \brief When Kind == EK_Variable, EK_Parameter, or EK_Member, 
-    /// the VarDecl, ParmVarDecl, or FieldDecl, respectively.
-    DeclaratorDecl *VariableOrMember;
-    
-    struct {
-      /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the
-      /// location of the 'return', 'throw', or 'new' keyword,
-      /// respectively. When Kind == EK_Temporary, the location where
-      /// the temporary is being created.
-      unsigned Location;
-      
-      /// \brief Whether the 
-      bool NRVO;
-    } LocAndNRVO;
-    
-    /// \brief When Kind == EK_Base, the base specifier that provides the 
-    /// base class. The lower bit specifies whether the base is an inherited
-    /// virtual base.
-    uintptr_t Base;
-
-    /// \brief When Kind == EK_ArrayElement or EK_VectorElement, the
-    /// index of the array or vector element being initialized. 
-    unsigned Index;
-  };
-
-  InitializedEntity() { }
-
-  /// \brief Create the initialization entity for a variable.
-  InitializedEntity(VarDecl *Var)
-    : Kind(EK_Variable), Parent(0), Type(Var->getType()),
-      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Var)) { }
-  
-  /// \brief Create the initialization entity for a parameter.
-  InitializedEntity(ParmVarDecl *Parm)
-    : Kind(EK_Parameter), Parent(0), Type(Parm->getType().getUnqualifiedType()),
-      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Parm)) { }
-  
-  /// \brief Create the initialization entity for the result of a
-  /// function, throwing an object, performing an explicit cast, or
-  /// initializing a parameter for which there is no declaration.
-  InitializedEntity(EntityKind Kind, SourceLocation Loc, QualType Type,
-                    bool NRVO = false)
-    : Kind(Kind), Parent(0), Type(Type)
-  {
-    LocAndNRVO.Location = Loc.getRawEncoding();
-    LocAndNRVO.NRVO = NRVO;
-  }
-  
-  /// \brief Create the initialization entity for a member subobject.
-  InitializedEntity(FieldDecl *Member, const InitializedEntity *Parent) 
-    : Kind(EK_Member), Parent(Parent), Type(Member->getType()),
-      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Member)) { }
-  
-  /// \brief Create the initialization entity for an array element.
-  InitializedEntity(ASTContext &Context, unsigned Index, 
-                    const InitializedEntity &Parent);
-
-public:
-  /// \brief Create the initialization entity for a variable.
-  static InitializedEntity InitializeVariable(VarDecl *Var) {
-    return InitializedEntity(Var);
-  }
-  
-  /// \brief Create the initialization entity for a parameter.
-  static InitializedEntity InitializeParameter(ParmVarDecl *Parm) {
-    return InitializedEntity(Parm);
-  }
-
-  /// \brief Create the initialization entity for a parameter that is
-  /// only known by its type.
-  static InitializedEntity InitializeParameter(QualType Type) {
-    InitializedEntity Entity;
-    Entity.Kind = EK_Parameter;
-    Entity.Type = Type;
-    Entity.Parent = 0;
-    Entity.VariableOrMember = 0;
-    return Entity;
-  }
-
-  /// \brief Create the initialization entity for the result of a function.
-  static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
-                                            QualType Type, bool NRVO) {
-    return InitializedEntity(EK_Result, ReturnLoc, Type, NRVO);
-  }
-
-  static InitializedEntity InitializeBlock(SourceLocation BlockVarLoc,
-                                           QualType Type, bool NRVO) {
-    return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
-  }
-  
-  /// \brief Create the initialization entity for an exception object.
-  static InitializedEntity InitializeException(SourceLocation ThrowLoc,
-                                               QualType Type, bool NRVO) {
-    return InitializedEntity(EK_Exception, ThrowLoc, Type, NRVO);
-  }
-
-  /// \brief Create the initialization entity for an object allocated via new.
-  static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type) {
-    return InitializedEntity(EK_New, NewLoc, Type);
-  }
-  
-  /// \brief Create the initialization entity for a temporary.
-  static InitializedEntity InitializeTemporary(QualType Type) {
-    return InitializedEntity(EK_Temporary, SourceLocation(), Type);
-  }
-  
-  /// \brief Create the initialization entity for a base class subobject.
-  static InitializedEntity InitializeBase(ASTContext &Context,
-                                          CXXBaseSpecifier *Base,
-                                          bool IsInheritedVirtualBase);
-  
-  /// \brief Create the initialization entity for a member subobject.
-  static InitializedEntity InitializeMember(FieldDecl *Member,
-                                          const InitializedEntity *Parent = 0) {
-    return InitializedEntity(Member, Parent);
-  }
-  
-  /// \brief Create the initialization entity for an array element.
-  static InitializedEntity InitializeElement(ASTContext &Context, 
-                                             unsigned Index, 
-                                             const InitializedEntity &Parent) {
-    return InitializedEntity(Context, Index, Parent);
-  }
-
-  /// \brief Determine the kind of initialization.
-  EntityKind getKind() const { return Kind; }
-  
-  /// \brief Retrieve the parent of the entity being initialized, when
-  /// the initialization itself is occuring within the context of a
-  /// larger initialization.
-  const InitializedEntity *getParent() const { return Parent; }
-
-  /// \brief Retrieve type being initialized.
-  QualType getType() const { return Type; }
-  
-  /// \brief Retrieve the name of the entity being initialized.
-  DeclarationName getName() const;
-
-  /// \brief Retrieve the variable, parameter, or field being
-  /// initialized.
-  DeclaratorDecl *getDecl() const;
-
-  /// \brief Determine whether this initialization allows the named return 
-  /// value optimization, which also applies to thrown objects.
-  bool allowsNRVO() const;
-                                  
-  /// \brief Retrieve the base specifier.
-  CXXBaseSpecifier *getBaseSpecifier() const {
-    assert(getKind() == EK_Base && "Not a base specifier");
-    return reinterpret_cast<CXXBaseSpecifier *>(Base & ~0x1);
-  }
-
-  /// \brief Return whether the base is an inherited virtual base.
-  bool isInheritedVirtualBase() const {
-    assert(getKind() == EK_Base && "Not a base specifier");
-    return Base & 0x1;
-  }
-
-  /// \brief Determine the location of the 'return' keyword when initializing
-  /// the result of a function call.
-  SourceLocation getReturnLoc() const {
-    assert(getKind() == EK_Result && "No 'return' location!");
-    return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
-  }
-  
-  /// \brief Determine the location of the 'throw' keyword when initializing
-  /// an exception object.
-  SourceLocation getThrowLoc() const {
-    assert(getKind() == EK_Exception && "No 'throw' location!");
-    return SourceLocation::getFromRawEncoding(LocAndNRVO.Location);
-  }
-
-  /// \brief If this is already the initializer for an array or vector
-  /// element, sets the element index.
-  void setElementIndex(unsigned Index) {
-    assert(getKind() == EK_ArrayElement || getKind() == EK_VectorElement);
-    this->Index = Index;
-  }
-};
-  
-/// \brief Describes the kind of initialization being performed, along with 
-/// location information for tokens related to the initialization (equal sign,
-/// parentheses).
-class InitializationKind {
-public:
-  /// \brief The kind of initialization being performed.
-  enum InitKind {
-    IK_Direct,  ///< Direct initialization
-    IK_Copy,    ///< Copy initialization
-    IK_Default, ///< Default initialization
-    IK_Value    ///< Value initialization
-  };
-  
-private:
-  /// \brief The kind of initialization that we're storing.
-  enum StoredInitKind {
-    SIK_Direct = IK_Direct,   ///< Direct initialization
-    SIK_Copy = IK_Copy,       ///< Copy initialization
-    SIK_Default = IK_Default, ///< Default initialization
-    SIK_Value = IK_Value,     ///< Value initialization
-    SIK_ImplicitValue,        ///< Implicit value initialization
-    SIK_DirectCast,  ///< Direct initialization due to a cast
-    /// \brief Direct initialization due to a C-style or functional cast.
-    SIK_DirectCStyleOrFunctionalCast
-  };
-  
-  /// \brief The kind of initialization being performed.
-  StoredInitKind Kind;
-  
-  /// \brief The source locations involved in the initialization.
-  SourceLocation Locations[3];
-  
-  InitializationKind(StoredInitKind Kind, SourceLocation Loc1, 
-                     SourceLocation Loc2, SourceLocation Loc3)
-    : Kind(Kind) 
-  {
-    Locations[0] = Loc1;
-    Locations[1] = Loc2;
-    Locations[2] = Loc3;
-  }
-  
-public:
-  /// \brief Create a direct initialization.
-  static InitializationKind CreateDirect(SourceLocation InitLoc,
-                                         SourceLocation LParenLoc,
-                                         SourceLocation RParenLoc) {
-    return InitializationKind(SIK_Direct, InitLoc, LParenLoc, RParenLoc);
-  }
-
-  /// \brief Create a direct initialization due to a cast.
-  static InitializationKind CreateCast(SourceRange TypeRange,
-                                       bool IsCStyleCast) {
-    return InitializationKind(IsCStyleCast? SIK_DirectCStyleOrFunctionalCast
-                                          : SIK_DirectCast,
-                              TypeRange.getBegin(), TypeRange.getBegin(), 
-                              TypeRange.getEnd());
-  }
-  
-  /// \brief Create a copy initialization.
-  static InitializationKind CreateCopy(SourceLocation InitLoc,
-                                       SourceLocation EqualLoc) {
-    return InitializationKind(SIK_Copy, InitLoc, EqualLoc, EqualLoc);
-  }
-  
-  /// \brief Create a default initialization.
-  static InitializationKind CreateDefault(SourceLocation InitLoc) {
-    return InitializationKind(SIK_Default, InitLoc, InitLoc, InitLoc);
-  }
-  
-  /// \brief Create a value initialization.
-  static InitializationKind CreateValue(SourceLocation InitLoc,
-                                        SourceLocation LParenLoc,
-                                        SourceLocation RParenLoc,
-                                        bool isImplicit = false) {
-    return InitializationKind(isImplicit? SIK_ImplicitValue : SIK_Value, 
-                              InitLoc, LParenLoc, RParenLoc);
-  }
-  
-  /// \brief Determine the initialization kind.
-  InitKind getKind() const {
-    if (Kind > SIK_ImplicitValue)
-      return IK_Direct;
-    if (Kind == SIK_ImplicitValue)
-      return IK_Value;
-
-    return (InitKind)Kind;
-  }
-  
-  /// \brief Determine whether this initialization is an explicit cast.
-  bool isExplicitCast() const {
-    return Kind == SIK_DirectCast || Kind == SIK_DirectCStyleOrFunctionalCast;
-  }
-  
-  /// \brief Determine whether this initialization is a C-style cast.
-  bool isCStyleOrFunctionalCast() const { 
-    return Kind == SIK_DirectCStyleOrFunctionalCast; 
-  }
-
-  /// \brief Determine whether this initialization is an implicit
-  /// value-initialization, e.g., as occurs during aggregate
-  /// initialization.
-  bool isImplicitValueInit() const { return Kind == SIK_ImplicitValue; }
-
-  /// \brief Retrieve the location at which initialization is occurring.
-  SourceLocation getLocation() const { return Locations[0]; }
-  
-  /// \brief Retrieve the source range that covers the initialization.
-  SourceRange getRange() const { 
-    return SourceRange(Locations[0], Locations[2]);
-  }
-  
-  /// \brief Retrieve the location of the equal sign for copy initialization
-  /// (if present).
-  SourceLocation getEqualLoc() const {
-    assert(Kind == SIK_Copy && "Only copy initialization has an '='");
-    return Locations[1];
-  }
-  
-  /// \brief Retrieve the source range containing the locations of the open
-  /// and closing parentheses for value and direct initializations.
-  SourceRange getParenRange() const {
-    assert((getKind() == IK_Direct || Kind == SIK_Value) &&
-           "Only direct- and value-initialization have parentheses");
-    return SourceRange(Locations[1], Locations[2]);
-  }
-};
-
-/// \brief Describes the sequence of initializations required to initialize
-/// a given object or reference with a set of arguments.
-class InitializationSequence {
-public:
-  /// \brief Describes the kind of initialization sequence computed.
-  ///
-  /// FIXME: Much of this information is in the initialization steps... why is
-  /// it duplicated here?
-  enum SequenceKind {
-    /// \brief A failed initialization sequence. The failure kind tells what
-    /// happened.
-    FailedSequence = 0,
-    
-    /// \brief A dependent initialization, which could not be
-    /// type-checked due to the presence of dependent types or
-    /// dependently-type expressions.
-    DependentSequence,
-
-    /// \brief A user-defined conversion sequence.
-    UserDefinedConversion,
-    
-    /// \brief A constructor call.
-    ConstructorInitialization,
-    
-    /// \brief A reference binding.
-    ReferenceBinding,
-
-    /// \brief List initialization
-    ListInitialization,
-    
-    /// \brief Zero-initialization.
-    ZeroInitialization,
-    
-    /// \brief No initialization required.
-    NoInitialization,
-    
-    /// \brief Standard conversion sequence.
-    StandardConversion,
-
-    /// \brief C conversion sequence.
-    CAssignment,
-
-    /// \brief String initialization
-    StringInit
-  };
-  
-  /// \brief Describes the kind of a particular step in an initialization
-  /// sequence.
-  enum StepKind {
-    /// \brief Resolve the address of an overloaded function to a specific
-    /// function declaration.
-    SK_ResolveAddressOfOverloadedFunction,
-    /// \brief Perform a derived-to-base cast, producing an rvalue.
-    SK_CastDerivedToBaseRValue,
-    /// \brief Perform a derived-to-base cast, producing an lvalue.
-    SK_CastDerivedToBaseLValue,
-    /// \brief Reference binding to an lvalue.
-    SK_BindReference,
-    /// \brief Reference binding to a temporary.
-    SK_BindReferenceToTemporary,
-    /// \brief An optional copy of a temporary object to another
-    /// temporary object, which is permitted (but not required) by
-    /// C++98/03 but not C++0x.
-    SK_ExtraneousCopyToTemporary,
-    /// \brief Perform a user-defined conversion, either via a conversion
-    /// function or via a constructor.
-    SK_UserConversion,
-    /// \brief Perform a qualification conversion, producing an rvalue.
-    SK_QualificationConversionRValue,
-    /// \brief Perform a qualification conversion, producing an lvalue.
-    SK_QualificationConversionLValue,
-    /// \brief Perform an implicit conversion sequence.
-    SK_ConversionSequence,
-    /// \brief Perform list-initialization
-    SK_ListInitialization,
-    /// \brief Perform initialization via a constructor.
-    SK_ConstructorInitialization,
-    /// \brief Zero-initialize the object
-    SK_ZeroInitialization,
-    /// \brief C assignment
-    SK_CAssignment,
-    /// \brief Initialization by string
-    SK_StringInit
-  };
-  
-  /// \brief A single step in the initialization sequence.
-  class Step {
-  public:
-    /// \brief The kind of conversion or initialization step we are taking.
-    StepKind Kind;
-    
-    // \brief The type that results from this initialization.
-    QualType Type;
-    
-    union {
-      /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==
-      /// SK_UserConversion, the function that the expression should be 
-      /// resolved to or the conversion function to call, respectively.
-      ///
-      /// Always a FunctionDecl.
-      /// For conversion decls, the naming class is the source type.
-      /// For construct decls, the naming class is the target type.
-      struct {
-        FunctionDecl *Function;
-        DeclAccessPair FoundDecl;
-      } Function;
-      
-      /// \brief When Kind = SK_ConversionSequence, the implicit conversion
-      /// sequence 
-      ImplicitConversionSequence *ICS;
-    };
-    
-    void Destroy();
-  };
-  
-private:
-  /// \brief The kind of initialization sequence computed.
-  enum SequenceKind SequenceKind;
-  
-  /// \brief Steps taken by this initialization.
-  llvm::SmallVector<Step, 4> Steps;
-  
-public:
-  /// \brief Describes why initialization failed.
-  enum FailureKind {
-    /// \brief Too many initializers provided for a reference.
-    FK_TooManyInitsForReference,
-    /// \brief Array must be initialized with an initializer list.
-    FK_ArrayNeedsInitList,
-    /// \brief Array must be initialized with an initializer list or a 
-    /// string literal.
-    FK_ArrayNeedsInitListOrStringLiteral,
-    /// \brief Cannot resolve the address of an overloaded function.
-    FK_AddressOfOverloadFailed,
-    /// \brief Overloading due to reference initialization failed.
-    FK_ReferenceInitOverloadFailed,
-    /// \brief Non-const lvalue reference binding to a temporary.
-    FK_NonConstLValueReferenceBindingToTemporary,
-    /// \brief Non-const lvalue reference binding to an lvalue of unrelated
-    /// type.
-    FK_NonConstLValueReferenceBindingToUnrelated,
-    /// \brief Rvalue reference binding to an lvalue.
-    FK_RValueReferenceBindingToLValue,
-    /// \brief Reference binding drops qualifiers.
-    FK_ReferenceInitDropsQualifiers,
-    /// \brief Reference binding failed.
-    FK_ReferenceInitFailed,
-    /// \brief Implicit conversion failed.
-    FK_ConversionFailed,
-    /// \brief Too many initializers for scalar
-    FK_TooManyInitsForScalar,
-    /// \brief Reference initialization from an initializer list
-    FK_ReferenceBindingToInitList,
-    /// \brief Initialization of some unused destination type with an
-    /// initializer list.
-    FK_InitListBadDestinationType,
-    /// \brief Overloading for a user-defined conversion failed.
-    FK_UserConversionOverloadFailed,
-    /// \brief Overloaded for initialization by constructor failed.
-    FK_ConstructorOverloadFailed,
-    /// \brief Default-initialization of a 'const' object.
-    FK_DefaultInitOfConst,
-    /// \brief Initialization of an incomplete type.
-    FK_Incomplete
-  };
-  
-private:
-  /// \brief The reason why initialization failued.
-  FailureKind Failure;
-
-  /// \brief The failed result of overload resolution.
-  OverloadingResult FailedOverloadResult;
-  
-  /// \brief The candidate set created when initialization failed.
-  OverloadCandidateSet FailedCandidateSet;
-
-  /// \brief Prints a follow-up note that highlights the location of
-  /// the initialized entity, if it's remote.
-  void PrintInitLocationNote(Sema &S, const InitializedEntity &Entity);
-
-public:
-  /// \brief Try to perform initialization of the given entity, creating a 
-  /// record of the steps required to perform the initialization.
-  ///
-  /// The generated initialization sequence will either contain enough
-  /// information to diagnose 
-  ///
-  /// \param S the semantic analysis object.
-  ///
-  /// \param Entity the entity being initialized.
-  ///
-  /// \param Kind the kind of initialization being performed.
-  ///
-  /// \param Args the argument(s) provided for initialization.
-  ///
-  /// \param NumArgs the number of arguments provided for initialization.
-  InitializationSequence(Sema &S, 
-                         const InitializedEntity &Entity,
-                         const InitializationKind &Kind,
-                         Expr **Args,
-                         unsigned NumArgs);
-  
-  ~InitializationSequence();
-  
-  /// \brief Perform the actual initialization of the given entity based on
-  /// the computed initialization sequence.
-  ///
-  /// \param S the semantic analysis object.
-  ///
-  /// \param Entity the entity being initialized.
-  ///
-  /// \param Kind the kind of initialization being performed.
-  ///
-  /// \param Args the argument(s) provided for initialization, ownership of
-  /// which is transfered into the routine.
-  ///
-  /// \param ResultType if non-NULL, will be set to the type of the
-  /// initialized object, which is the type of the declaration in most
-  /// cases. However, when the initialized object is a variable of
-  /// incomplete array type and the initializer is an initializer
-  /// list, this type will be set to the completed array type.
-  ///
-  /// \returns an expression that performs the actual object initialization, if
-  /// the initialization is well-formed. Otherwise, emits diagnostics
-  /// and returns an invalid expression.
-  Action::OwningExprResult Perform(Sema &S,
-                                   const InitializedEntity &Entity,
-                                   const InitializationKind &Kind,
-                                   Action::MultiExprArg Args,
-                                   QualType *ResultType = 0);
-  
-  /// \brief Diagnose an potentially-invalid initialization sequence.
-  ///
-  /// \returns true if the initialization sequence was ill-formed, 
-  /// false otherwise.
-  bool Diagnose(Sema &S, 
-                const InitializedEntity &Entity,
-                const InitializationKind &Kind,
-                Expr **Args, unsigned NumArgs);
-  
-  /// \brief Determine the kind of initialization sequence computed.
-  enum SequenceKind getKind() const { return SequenceKind; }
-  
-  /// \brief Set the kind of sequence computed.
-  void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; }
-  
-  /// \brief Determine whether the initialization sequence is valid.
-  operator bool() const { return SequenceKind != FailedSequence; }
-  
-  typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator;
-  step_iterator step_begin() const { return Steps.begin(); }
-  step_iterator step_end()   const { return Steps.end(); }
-
-  /// \brief Determine whether this initialization is a direct reference 
-  /// binding (C++ [dcl.init.ref]).
-  bool isDirectReferenceBinding() const;
-  
-  /// \brief Determine whether this initialization failed due to an ambiguity.
-  bool isAmbiguous() const;
-  
-  /// \brief Determine whether this initialization is direct call to a 
-  /// constructor.
-  bool isConstructorInitialization() const;
-  
-  /// \brief Add a new step in the initialization that resolves the address
-  /// of an overloaded function to a specific function declaration.
-  ///
-  /// \param Function the function to which the overloaded function reference
-  /// resolves.
-  void AddAddressOverloadResolutionStep(FunctionDecl *Function,
-                                        DeclAccessPair Found);
-  
-  /// \brief Add a new step in the initialization that performs a derived-to-
-  /// base cast.
-  ///
-  /// \param BaseType the base type to which we will be casting.
-  ///
-  /// \param IsLValue true if the result of this cast will be treated as 
-  /// an lvalue.
-  void AddDerivedToBaseCastStep(QualType BaseType, bool IsLValue);
-     
-  /// \brief Add a new step binding a reference to an object.
-  ///
-  /// \param BindingTemporary True if we are binding a reference to a temporary
-  /// object (thereby extending its lifetime); false if we are binding to an
-  /// lvalue or an lvalue treated as an rvalue.
-  ///
-  /// \param UnnecessaryCopy True if we should check for a copy
-  /// constructor for a completely unnecessary but
-  void AddReferenceBindingStep(QualType T, bool BindingTemporary);
-
-  /// \brief Add a new step that makes an extraneous copy of the input
-  /// to a temporary of the same class type.
-  ///
-  /// This extraneous copy only occurs during reference binding in
-  /// C++98/03, where we are permitted (but not required) to introduce
-  /// an extra copy. At a bare minimum, we must check that we could
-  /// call the copy constructor, and produce a diagnostic if the copy
-  /// constructor is inaccessible or no copy constructor matches.
-  //
-  /// \param T The type of the temporary being created.
-  void AddExtraneousCopyToTemporary(QualType T);
-
-  /// \brief Add a new step invoking a conversion function, which is either
-  /// a constructor or a conversion function.
-  void AddUserConversionStep(FunctionDecl *Function,
-                             DeclAccessPair FoundDecl,
-                             QualType T);
-  
-  /// \brief Add a new step that performs a qualification conversion to the
-  /// given type.
-  void AddQualificationConversionStep(QualType Ty, bool IsLValue);
-  
-  /// \brief Add a new step that applies an implicit conversion sequence.
-  void AddConversionSequenceStep(const ImplicitConversionSequence &ICS,
-                                 QualType T);
-
-  /// \brief Add a list-initialiation step  
-  void AddListInitializationStep(QualType T);
-
-  /// \brief Add a constructor-initialization step.
-  void AddConstructorInitializationStep(CXXConstructorDecl *Constructor,
-                                        AccessSpecifier Access,
-                                        QualType T);
-
-  /// \brief Add a zero-initialization step.
-  void AddZeroInitializationStep(QualType T);
-  
-  /// \brief Add a C assignment step.
-  //
-  // FIXME: It isn't clear whether this should ever be needed;
-  // ideally, we would handle everything needed in C in the common
-  // path. However, that isn't the case yet.
-  void AddCAssignmentStep(QualType T);
-
-  /// \brief Add a string init step.
-  void AddStringInitStep(QualType T);
-
-  /// \brief Note that this initialization sequence failed.
-  void SetFailed(FailureKind Failure) {
-    SequenceKind = FailedSequence;
-    this->Failure = Failure;
-  }
-  
-  /// \brief Note that this initialization sequence failed due to failed
-  /// overload resolution.
-  void SetOverloadFailure(FailureKind Failure, OverloadingResult Result);
-  
-  /// \brief Retrieve a reference to the candidate set when overload
-  /// resolution fails.
-  OverloadCandidateSet &getFailedCandidateSet() {
-    return FailedCandidateSet;
-  }
-
-  /// \brief Determine why initialization failed.
-  FailureKind getFailureKind() const {
-    assert(getKind() == FailedSequence && "Not an initialization failure!");
-    return Failure;
-  }
-  
-  /// \brief Dump a representation of this initialization sequence to 
-  /// the given stream, for debugging purposes.
-  void dump(llvm::raw_ostream &OS) const;
-  
-  /// \brief Dump a representation of this initialization sequence to 
-  /// standard error, for debugging purposes.
-  void dump() const;
-};
-  
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_INIT_H
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 2e65183..306e95a 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -11,8 +11,13 @@
 //  Objective-C++.
 //
 //===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
@@ -21,9 +26,9 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/Parse/DeclSpec.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/LangOptions.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -35,6 +40,7 @@
 #include <algorithm>
 
 using namespace clang;
+using namespace sema;
 
 namespace {
   class UnqualUsingEntry {
@@ -100,7 +106,7 @@ namespace {
                              End = S->using_directives_end();
           
           for (; I != End; ++I)
-            visit(I->getAs<UsingDirectiveDecl>(), InnermostFileDC);
+            visit(*I, InnermostFileDC);
         }
       }
     }
@@ -254,6 +260,12 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
   case Sema::LookupObjCProtocolName:
     IDNS = Decl::IDNS_ObjCProtocol;
     break;
+      
+  case Sema::LookupAnyName:
+    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member 
+      | Decl::IDNS_Using | Decl::IDNS_Namespace | Decl::IDNS_ObjCProtocol
+      | Decl::IDNS_Type;
+    break;
   }
   return IDNS;
 }
@@ -267,7 +279,7 @@ void LookupResult::configure() {
   // operators, make sure that the implicitly-declared new and delete
   // operators can be found.
   if (!isForRedeclaration()) {
-    switch (Name.getCXXOverloadedOperator()) {
+    switch (NameInfo.getName().getCXXOverloadedOperator()) {
     case OO_New:
     case OO_Delete:
     case OO_Array_New:
@@ -281,6 +293,22 @@ void LookupResult::configure() {
   }
 }
 
+#ifndef NDEBUG
+void LookupResult::sanity() const {
+  assert(ResultKind != NotFound || Decls.size() == 0);
+  assert(ResultKind != Found || Decls.size() == 1);
+  assert(ResultKind != FoundOverloaded || Decls.size() > 1 ||
+         (Decls.size() == 1 &&
+          isa<FunctionTemplateDecl>((*begin())->getUnderlyingDecl())));
+  assert(ResultKind != FoundUnresolvedValue || sanityCheckUnresolved());
+  assert(ResultKind != Ambiguous || Decls.size() > 1 ||
+         (Decls.size() == 1 && Ambiguity == AmbiguousBaseSubobjects));
+  assert((Paths != NULL) == (ResultKind == Ambiguous &&
+                             (Ambiguity == AmbiguousBaseSubobjectTypes ||
+                              Ambiguity == AmbiguousBaseSubobjects)));
+}
+#endif
+
 // Necessary because CXXBasePaths is not complete in Sema.h
 void LookupResult::deletePaths(CXXBasePaths *Paths) {
   delete Paths;
@@ -311,7 +339,8 @@ void LookupResult::resolveKind() {
   if (ResultKind == Ambiguous) return;
 
   llvm::SmallPtrSet<NamedDecl*, 16> Unique;
-
+  llvm::SmallPtrSet<QualType, 16> UniqueTypes;
+  
   bool Ambiguous = false;
   bool HasTag = false, HasFunction = false, HasNonFunction = false;
   bool HasFunctionTemplate = false, HasUnresolved = false;
@@ -323,32 +352,49 @@ void LookupResult::resolveKind() {
     NamedDecl *D = Decls[I]->getUnderlyingDecl();
     D = cast<NamedDecl>(D->getCanonicalDecl());
 
+    // Redeclarations of types via typedef can occur both within a scope
+    // and, through using declarations and directives, across scopes. There is
+    // no ambiguity if they all refer to the same type, so unique based on the
+    // canonical type.
+    if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
+      if (!TD->getDeclContext()->isRecord()) {
+        QualType T = SemaRef.Context.getTypeDeclType(TD);
+        if (!UniqueTypes.insert(SemaRef.Context.getCanonicalType(T))) {
+          // The type is not unique; pull something off the back and continue
+          // at this index.
+          Decls[I] = Decls[--N];
+          continue;
+        }
+      }
+    }
+    
     if (!Unique.insert(D)) {
       // If it's not unique, pull something off the back (and
       // continue at this index).
       Decls[I] = Decls[--N];
+      continue;
+    } 
+    
+    // Otherwise, do some decl type analysis and then continue.
+
+    if (isa<UnresolvedUsingValueDecl>(D)) {
+      HasUnresolved = true;
+    } else if (isa<TagDecl>(D)) {
+      if (HasTag)
+        Ambiguous = true;
+      UniqueTagIndex = I;
+      HasTag = true;
+    } else if (isa<FunctionTemplateDecl>(D)) {
+      HasFunction = true;
+      HasFunctionTemplate = true;
+    } else if (isa<FunctionDecl>(D)) {
+      HasFunction = true;
     } else {
-      // Otherwise, do some decl type analysis and then continue.
-
-      if (isa<UnresolvedUsingValueDecl>(D)) {
-        HasUnresolved = true;
-      } else if (isa<TagDecl>(D)) {
-        if (HasTag)
-          Ambiguous = true;
-        UniqueTagIndex = I;
-        HasTag = true;
-      } else if (isa<FunctionTemplateDecl>(D)) {
-        HasFunction = true;
-        HasFunctionTemplate = true;
-      } else if (isa<FunctionDecl>(D)) {
-        HasFunction = true;
-      } else {
-        if (HasNonFunction)
-          Ambiguous = true;
-        HasNonFunction = true;
-      }
-      I++;
+      if (HasNonFunction)
+        Ambiguous = true;
+      HasNonFunction = true;
     }
+    I++;
   }
 
   // C++ [basic.scope.hiding]p2:
@@ -451,6 +497,10 @@ static bool LookupBuiltin(Sema &S, LookupResult &R) {
 /// the class at this point.
 static bool CanDeclareSpecialMemberFunction(ASTContext &Context,
                                             const CXXRecordDecl *Class) {
+  // Don't do it if the class is invalid.
+  if (Class->isInvalidDecl())
+    return false;
+  
   // We need to have a definition for the class.
   if (!Class->getDefinition() || Class->isDependentContext())
     return false;
@@ -608,7 +658,7 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) {
     // result), perform template argument deduction and place the 
     // specialization into the result set. We do this to avoid forcing all
     // callers to perform special deduction for conversion functions.
-    Sema::TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
+    TemplateDeductionInfo Info(R.getSema().Context, R.getNameLoc());
     FunctionDecl *Specialization = 0;
     
     const FunctionProtoType *ConvProto        
@@ -783,7 +833,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
 
     // Check whether the IdResolver has anything in this scope.
     bool Found = false;
-    for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+    for (; I != IEnd && S->isDeclScope(*I); ++I) {
       if (R.isAcceptableDecl(*I)) {
         Found = true;
         R.addDecl(*I);
@@ -881,7 +931,7 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) {
   for (; S; S = S->getParent()) {
     // Check whether the IdResolver has anything in this scope.
     bool Found = false;
-    for (; I != IEnd && S->isDeclScope(DeclPtrTy::make(*I)); ++I) {
+    for (; I != IEnd && S->isDeclScope(*I); ++I) {
       if (R.isAcceptableDecl(*I)) {
         // We found something.  Look for anything else in our scope
         // with this same name and in an acceptable identifier
@@ -1017,7 +1067,7 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
         if (NameKind == LookupRedeclarationWithLinkage) {
           // Determine whether this (or a previous) declaration is
           // out-of-scope.
-          if (!LeftStartingScope && !S->isDeclScope(DeclPtrTy::make(*I)))
+          if (!LeftStartingScope && !S->isDeclScope(*I))
             LeftStartingScope = true;
 
           // If we found something outside of our starting scope that
@@ -1034,14 +1084,14 @@ bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation) {
 
           // Figure out what scope the identifier is in.
           while (!(S->getFlags() & Scope::DeclScope) ||
-                 !S->isDeclScope(DeclPtrTy::make(*I)))
+                 !S->isDeclScope(*I))
             S = S->getParent();
 
           // Find the last declaration in this scope (with the same
           // name, naturally).
           IdentifierResolver::iterator LastI = I;
           for (++LastI; LastI != IEnd; ++LastI) {
-            if (!S->isDeclScope(DeclPtrTy::make(*LastI)))
+            if (!S->isDeclScope(*LastI))
               break;
             R.addDecl(*LastI);
           }
@@ -1177,6 +1227,17 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R,
   return Found;
 }
 
+/// \brief Callback that looks for any member of a class with the given name.
+static bool LookupAnyMember(const CXXBaseSpecifier *Specifier, 
+                            CXXBasePath &Path,
+                            void *Name) {
+  RecordDecl *BaseRecord = Specifier->getType()->getAs<RecordType>()->getDecl();
+  
+  DeclarationName N = DeclarationName::getFromOpaquePtr(Name);
+  Path.Decls = BaseRecord->lookup(N);
+  return Path.Decls.first != Path.Decls.second;
+}
+
 /// \brief Perform qualified name lookup into a given context.
 ///
 /// Qualified name lookup (C++ [basic.lookup.qual]) is used to find
@@ -1272,6 +1333,10 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
       BaseCallback = &CXXRecordDecl::FindTagMember;
       break;
 
+    case LookupAnyName:
+      BaseCallback = &LookupAnyMember;
+      break;
+      
     case LookupUsingDeclName:
       // This lookup is for redeclarations only.
       
@@ -1554,7 +1619,11 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
   // We don't use DeclContext::getEnclosingNamespaceContext() as this may
   // be a locally scoped record.
 
-  while (Ctx->isRecord() || Ctx->isTransparentContext())
+  // We skip out of inline namespaces. The innermost non-inline namespace
+  // contains all names of all its nested inline namespaces anyway, so we can
+  // replace the entire inline namespace tree with its root.
+  while (Ctx->isRecord() || Ctx->isTransparentContext() ||
+         Ctx->isInlineNamespace())
     Ctx = Ctx->getParent();
 
   if (Ctx->isFileContext())
@@ -1894,7 +1963,7 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
     // parameter types and return type.
     Arg = Arg->IgnoreParens();
     if (UnaryOperator *unaryOp = dyn_cast<UnaryOperator>(Arg))
-      if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
+      if (unaryOp->getOpcode() == UO_AddrOf)
         Arg = unaryOp->getSubExpr();
 
     UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
@@ -2201,6 +2270,10 @@ public:
     return !VisitedContexts.insert(Ctx);
   }
 
+  bool alreadyVisitedContext(DeclContext *Ctx) {
+    return VisitedContexts.count(Ctx);
+  }
+
   /// \brief Determine whether the given declaration is hidden in the
   /// current scope.
   ///
@@ -2354,9 +2427,9 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
           Visited.add(ND);
         }
 
-      // Visit transparent contexts inside this context.
+      // Visit transparent contexts and inline namespaces inside this context.
       if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
-        if (InnerCtx->isTransparentContext())
+        if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace())
           LookupVisibleDecls(InnerCtx, Result, QualifiedNameLookup, InBaseClass,
                              Consumer, Visited);
       }
@@ -2429,8 +2502,9 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
     }
 
     // Traverse protocols.
-    for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
-         E = IFace->protocol_end(); I != E; ++I) {
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         I = IFace->all_referenced_protocol_begin(),
+         E = IFace->all_referenced_protocol_end(); I != E; ++I) {
       ShadowContextRAII Shadow(Visited);
       LookupVisibleDecls(*I, Result, QualifiedNameLookup, false, Consumer, 
                          Visited);
@@ -2481,12 +2555,14 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,
   if (!S)
     return;
 
-  if (!S->getEntity() || !S->getParent() ||
+  if (!S->getEntity() || 
+      (!S->getParent() && 
+       !Visited.alreadyVisitedContext((DeclContext *)S->getEntity())) ||
       ((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
     // Walk through the declarations in this Scope.
     for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
          D != DEnd; ++D) {
-      if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
+      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
         if (Result.isAcceptableDecl(ND)) {
           Consumer.FoundDecl(ND, Visited.checkHidden(ND), false);
           Visited.add(ND);
@@ -2559,7 +2635,8 @@ static void LookupVisibleDecls(Scope *S, LookupResult &Result,
 }
 
 void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
-                              VisibleDeclConsumer &Consumer) {
+                              VisibleDeclConsumer &Consumer,
+                              bool IncludeGlobalScope) {
   // Determine the set of using directives available during
   // unqualified name lookup.
   Scope *Initial = S;
@@ -2576,14 +2653,19 @@ void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
   // Look for visible declarations.
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
+  if (!IncludeGlobalScope)
+    Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Initial, Result, UDirs, Consumer, Visited);
 }
 
 void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
-                              VisibleDeclConsumer &Consumer) {
+                              VisibleDeclConsumer &Consumer,
+                              bool IncludeGlobalScope) {
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   VisibleDeclsRecord Visited;
+  if (!IncludeGlobalScope)
+    Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true, 
                        /*InBaseClass=*/false, Consumer, Visited);
@@ -2911,7 +2993,7 @@ DeclarationName Sema::CorrectTypo(LookupResult &Res, Scope *S, CXXScopeSpec *SS,
       if (S && S->getContinueParent())
         Consumer.addKeywordResult(Context, "continue");
       
-      if (!getSwitchStack().empty()) {
+      if (!getCurFunction()->SwitchStack.empty()) {
         Consumer.addKeywordResult(Context, "case");
         Consumer.addKeywordResult(Context, "default");
       }
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index ff60599..7181d58 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -12,9 +12,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/ExprObjC.h"
+#include "llvm/ADT/DenseSet.h"
 
 using namespace clang;
 
@@ -22,14 +24,14 @@ using namespace clang;
 // Grammar actions.
 //===----------------------------------------------------------------------===//
 
-Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
-                                    FieldDeclarator &FD,
-                                    ObjCDeclSpec &ODS,
-                                    Selector GetterSel,
-                                    Selector SetterSel,
-                                    DeclPtrTy ClassCategory,
-                                    bool *isOverridingProperty,
-                                    tok::ObjCKeywordKind MethodImplKind) {
+Decl *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
+                          FieldDeclarator &FD,
+                          ObjCDeclSpec &ODS,
+                          Selector GetterSel,
+                          Selector SetterSel,
+                          Decl *ClassCategory,
+                          bool *isOverridingProperty,
+                          tok::ObjCKeywordKind MethodImplKind) {
   unsigned Attributes = ODS.getPropertyAttributes();
   bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
                       // default is readwrite!
@@ -45,15 +47,15 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
   QualType T = TSI->getType();
   if (T->isReferenceType()) {
     Diag(AtLoc, diag::error_reference_property);
-    return DeclPtrTy();
+    return 0;
   }
   // Proceed with constructing the ObjCPropertDecls.
   ObjCContainerDecl *ClassDecl =
-    cast<ObjCContainerDecl>(ClassCategory.getAs<Decl>());
+    cast<ObjCContainerDecl>(ClassCategory);
 
   if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
     if (CDecl->IsClassExtension()) {
-      DeclPtrTy Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
+      Decl *Res = HandlePropertyInClassExtension(S, CDecl, AtLoc,
                                            FD, GetterSel, SetterSel,
                                            isAssign, isReadWrite,
                                            Attributes,
@@ -64,16 +66,16 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
       return Res;
     }
   
-  DeclPtrTy Res =  DeclPtrTy::make(CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
-                                              GetterSel, SetterSel,
-                                              isAssign, isReadWrite,
-                                              Attributes, TSI, MethodImplKind));
+  Decl *Res = CreatePropertyDecl(S, ClassDecl, AtLoc, FD,
+                                 GetterSel, SetterSel,
+                                 isAssign, isReadWrite,
+                                 Attributes, TSI, MethodImplKind);
   // Validate the attributes on the @property.
   CheckObjCPropertyAttributes(Res, AtLoc, Attributes);
   return Res;
 }
 
-Sema::DeclPtrTy
+Decl *
 Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
                                      SourceLocation AtLoc, FieldDeclarator &FD,
                                      Selector GetterSel, Selector SetterSel,
@@ -92,7 +94,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
         ObjCPropertyDecl::findPropertyDecl(DC, PropertyId)) {
     Diag(AtLoc, diag::err_duplicate_property);
     Diag(prevDecl->getLocation(), diag::note_property_declare);
-    return DeclPtrTy();
+    return 0;
   }
 
   // Create a new ObjCPropertyDecl with the DeclContext being
@@ -113,7 +115,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
   if (!CCPrimary) {
     Diag(CDecl->getLocation(), diag::err_continuation_class);
     *isOverridingProperty = true;
-    return DeclPtrTy();
+    return 0;
   }
 
   // Find the property in continuation class's primary class only.
@@ -136,7 +138,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
     // is not what it was meant for. However, gcc supports it and so should we.
     // Make sure setter/getters are declared here.
     ProcessPropertyDecl(PDecl, CCPrimary);
-    return DeclPtrTy::make(PDecl);
+    return PDecl;
 
   }
 
@@ -165,13 +167,13 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
       setPropertyAttributes((ObjCDeclSpec::ObjCPropertyAttributeKind)
                             PIkind);
 
-      DeclPtrTy ProtocolPtrTy =
+      Decl *ProtocolPtrTy =
         ActOnProperty(S, AtLoc, FD, ProtocolPropertyODS,
                       PIDecl->getGetterName(),
                       PIDecl->getSetterName(),
-                      DeclPtrTy::make(CCPrimary), isOverridingProperty,
+                      CCPrimary, isOverridingProperty,
                       MethodImplKind);
-      PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy.getAs<Decl>());
+      PIDecl = cast<ObjCPropertyDecl>(ProtocolPtrTy);
     }
     PIDecl->makeitReadWriteAttribute();
     if (Attributes & ObjCDeclSpec::DQ_PR_retain)
@@ -187,7 +189,7 @@ Sema::HandlePropertyInClassExtension(Scope *S, ObjCCategoryDecl *CDecl,
   *isOverridingProperty = true;
   // Make sure setter decl is synthesized, and added to primary class's list.
   ProcessPropertyDecl(PIDecl, CCPrimary);
-  return DeclPtrTy();
+  return 0;
 }
 
 ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
@@ -289,19 +291,19 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
 /// builds the AST node for a property implementation declaration; declared
 /// as @synthesize or @dynamic.
 ///
-Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
-                                            SourceLocation AtLoc,
-                                            SourceLocation PropertyLoc,
-                                            bool Synthesize,
-                                            DeclPtrTy ClassCatImpDecl,
-                                            IdentifierInfo *PropertyId,
-                                            IdentifierInfo *PropertyIvar) {
+Decl *Sema::ActOnPropertyImplDecl(Scope *S,
+                                  SourceLocation AtLoc,
+                                  SourceLocation PropertyLoc,
+                                  bool Synthesize,
+                                  Decl *ClassCatImpDecl,
+                                  IdentifierInfo *PropertyId,
+                                  IdentifierInfo *PropertyIvar) {
   ObjCContainerDecl *ClassImpDecl =
-    cast_or_null<ObjCContainerDecl>(ClassCatImpDecl.getAs<Decl>());
+    cast_or_null<ObjCContainerDecl>(ClassCatImpDecl);
   // Make sure we have a context for the property implementation declaration.
   if (!ClassImpDecl) {
     Diag(AtLoc, diag::error_missing_property_context);
-    return DeclPtrTy();
+    return 0;
   }
   ObjCPropertyDecl *property = 0;
   ObjCInterfaceDecl* IDecl = 0;
@@ -320,25 +322,25 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
     property = IDecl->FindPropertyDeclaration(PropertyId);
     if (!property) {
       Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
-      return DeclPtrTy();
+      return 0;
     }
     if (const ObjCCategoryDecl *CD =
         dyn_cast<ObjCCategoryDecl>(property->getDeclContext())) {
       if (!CD->IsClassExtension()) {
         Diag(PropertyLoc, diag::error_category_property) << CD->getDeclName();
         Diag(property->getLocation(), diag::note_property_declare);
-        return DeclPtrTy();
+        return 0;
       }
     }
   } else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
     if (Synthesize) {
       Diag(AtLoc, diag::error_synthesize_category_decl);
-      return DeclPtrTy();
+      return 0;
     }
     IDecl = CatImplClass->getClassInterface();
     if (!IDecl) {
       Diag(AtLoc, diag::error_missing_property_interface);
-      return DeclPtrTy();
+      return 0;
     }
     ObjCCategoryDecl *Category =
     IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
@@ -346,17 +348,17 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
     // If category for this implementation not found, it is an error which
     // has already been reported eralier.
     if (!Category)
-      return DeclPtrTy();
+      return 0;
     // Look for this property declaration in @implementation's category
     property = Category->FindPropertyDeclaration(PropertyId);
     if (!property) {
       Diag(PropertyLoc, diag::error_bad_category_property_decl)
       << Category->getDeclName();
-      return DeclPtrTy();
+      return 0;
     }
   } else {
     Diag(AtLoc, diag::error_bad_property_context);
-    return DeclPtrTy();
+    return 0;
   }
   ObjCIvarDecl *Ivar = 0;
   // Check that we have a valid, previously declared ivar for @synthesize
@@ -372,7 +374,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
       Ivar = ObjCIvarDecl::Create(Context, ClassImpDecl, PropertyLoc,
                                   PropertyIvar, PropType, /*Dinfo=*/0,
                                   ObjCIvarDecl::Protected,
-                                  (Expr *)0);
+                                  (Expr *)0, true);
       ClassImpDecl->addDecl(Ivar);
       IDecl->makeDeclVisibleInContext(Ivar, false);
       property->setPropertyIvarDecl(Ivar);
@@ -387,7 +389,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
       << property->getDeclName() << Ivar->getDeclName()
       << ClassDeclared->getDeclName();
       Diag(Ivar->getLocation(), diag::note_previous_access_declaration)
-      << Ivar << Ivar->getNameAsCString();
+      << Ivar << Ivar->getName();
       // Note! I deliberately want it to fall thru so more errors are caught.
     }
     QualType IvarType = Context.getCanonicalType(Ivar->getType());
@@ -464,7 +466,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
       Expr *IvarRefExpr =
         new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
                                       SelfExpr, true, true);
-      OwningExprResult Res = 
+      ExprResult Res = 
         PerformCopyInitialization(InitializedEntity::InitializeResult(
                                     SourceLocation(),
                                     getterMethod->getResultType(),
@@ -494,8 +496,8 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
       ParmVarDecl *Param = (*P);
       Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(),
                                             SourceLocation());
-      OwningExprResult Res = BuildBinOp(S, SourceLocation(), 
-                                        BinaryOperator::Assign, lhs, rhs);
+      ExprResult Res = BuildBinOp(S, SourceLocation(), 
+                                  BO_Assign, lhs, rhs);
       PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>());
     }
   }
@@ -514,9 +516,29 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
         = IC->FindPropertyImplDecl(PropertyId)) {
       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
-      return DeclPtrTy();
+      return 0;
     }
     IC->addPropertyImplementation(PIDecl);
+    if (getLangOptions().ObjCNonFragileABI2) {
+      // Diagnose if an ivar was lazily synthesdized due to a previous
+      // use and if 1) property is @dynamic or 2) property is synthesized
+      // but it requires an ivar of different name.
+      ObjCInterfaceDecl *ClassDeclared;
+      ObjCIvarDecl *Ivar = 0;
+      if (!Synthesize)
+        Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+      else {
+        if (PropertyIvar && PropertyIvar != PropertyId)
+          Ivar = IDecl->lookupInstanceVariable(PropertyId, ClassDeclared);
+      }
+      // Issue diagnostics only if Ivar belongs to current class.
+      if (Ivar && Ivar->getSynthesize() && 
+          IC->getClassInterface() == ClassDeclared) {
+        Diag(Ivar->getLocation(), diag::err_undeclared_var_use) 
+        << PropertyId;
+        Ivar->setInvalidDecl();
+      }
+    }
   } else {
     if (Synthesize)
       if (ObjCPropertyImplDecl *PPIDecl =
@@ -531,12 +553,12 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(Scope *S,
         CatImplClass->FindPropertyImplDecl(PropertyId)) {
       Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
       Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
-      return DeclPtrTy();
+      return 0;
     }
     CatImplClass->addPropertyImplementation(PIDecl);
   }
 
-  return DeclPtrTy::make(PIDecl);
+  return PIDecl;
 }
 
 //===----------------------------------------------------------------------===//
@@ -680,9 +702,8 @@ Sema::MatchOneProtocolPropertiesInClass(Decl *CDecl,
 /// declared in 'ClassOrProtocol' objects (which can be a class or an
 /// inherited protocol with the list of properties for class/category 'CDecl'
 ///
-void Sema::CompareProperties(Decl *CDecl,
-                             DeclPtrTy ClassOrProtocol) {
-  Decl *ClassDecl = ClassOrProtocol.getAs<Decl>();
+void Sema::CompareProperties(Decl *CDecl, Decl *ClassOrProtocol) {
+  Decl *ClassDecl = ClassOrProtocol;
   ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
 
   if (!IDecl) {
@@ -699,7 +720,7 @@ void Sema::CompareProperties(Decl *CDecl,
       // their properties with those in the category.
       for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
            E = CatDecl->protocol_end(); P != E; ++P)
-        CompareProperties(CatDecl, DeclPtrTy::make(*P));
+        CompareProperties(CatDecl, *P);
     } else {
       ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
       for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
@@ -710,16 +731,18 @@ void Sema::CompareProperties(Decl *CDecl,
   }
 
   if (ObjCInterfaceDecl *MDecl = dyn_cast<ObjCInterfaceDecl>(ClassDecl)) {
-    for (ObjCInterfaceDecl::protocol_iterator P = MDecl->protocol_begin(),
-         E = MDecl->protocol_end(); P != E; ++P)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          P = MDecl->all_referenced_protocol_begin(),
+          E = MDecl->all_referenced_protocol_end(); P != E; ++P)
       // Match properties of class IDecl with those of protocol (*P).
       MatchOneProtocolPropertiesInClass(IDecl, *P);
 
     // Go thru the list of protocols for this class and recursively match
     // their properties with those declared in the class.
-    for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); P != E; ++P)
-      CompareProperties(IDecl, DeclPtrTy::make(*P));
+    for (ObjCInterfaceDecl::all_protocol_iterator
+          P = IDecl->all_referenced_protocol_begin(),
+          E = IDecl->all_referenced_protocol_end(); P != E; ++P)
+      CompareProperties(IDecl, *P);
   } else {
     ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
     for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
@@ -791,8 +814,9 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
       PropMap[Prop->getIdentifier()] = Prop;
     }
     // scan through class's protocols.
-    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         PI = IDecl->all_referenced_protocol_begin(),
+         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
         CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
   if (ObjCCategoryDecl *CATDecl = dyn_cast<ObjCCategoryDecl>(CDecl)) {
@@ -803,7 +827,7 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl,
         PropMap[Prop->getIdentifier()] = Prop;
       }
     // scan through class's protocols.
-    for (ObjCInterfaceDecl::protocol_iterator PI = CATDecl->protocol_begin(),
+    for (ObjCCategoryDecl::protocol_iterator PI = CATDecl->protocol_begin(),
          E = CATDecl->protocol_end(); PI != E; ++PI)
       CollectImmediateProperties((*PI), PropMap, SuperPropMap);
   }
@@ -838,8 +862,9 @@ static void CollectClassPropertyImplementations(ObjCContainerDecl *CDecl,
       ObjCPropertyDecl *Prop = (*P);
       PropMap[Prop->getIdentifier()] = Prop;
     }
-    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); PI != E; ++PI)
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         PI = IDecl->all_referenced_protocol_begin(),
+         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI)
       CollectClassPropertyImplementations((*PI), PropMap);
   }
   else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(CDecl)) {
@@ -881,8 +906,9 @@ ObjCPropertyDecl *Sema::LookupPropertyDecl(const ObjCContainerDecl *CDecl,
         return Prop;
     }
     // scan through class's protocols.
-    for (ObjCInterfaceDecl::protocol_iterator PI = IDecl->protocol_begin(),
-         E = IDecl->protocol_end(); PI != E; ++PI) {
+    for (ObjCInterfaceDecl::all_protocol_iterator
+         PI = IDecl->all_referenced_protocol_begin(),
+         E = IDecl->all_referenced_protocol_end(); PI != E; ++PI) {
       ObjCPropertyDecl *Prop = LookupPropertyDecl((*PI), II);
       if (Prop)
         return Prop;
@@ -933,9 +959,15 @@ void Sema::DefaultSynthesizeProperties (Scope *S, ObjCImplDecl* IMPDecl,
     // Property may have been synthesized by user.
     if (IMPDecl->FindPropertyImplDecl(Prop->getIdentifier()))
       continue;
+    if (IMPDecl->getInstanceMethod(Prop->getGetterName())) {
+      if (Prop->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_readonly)
+        continue;
+      if (IMPDecl->getInstanceMethod(Prop->getSetterName()))
+        continue;
+    }
 
     ActOnPropertyImplDecl(S, IMPDecl->getLocation(), IMPDecl->getLocation(),
-                          true, DeclPtrTy::make(IMPDecl),
+                          true, IMPDecl,
                           Prop->getIdentifier(), Prop->getIdentifier());
   }    
 }
@@ -1066,7 +1098,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
     // for this class.
     GetterMethod = ObjCMethodDecl::Create(Context, property->getLocation(),
                              property->getLocation(), property->getGetterName(),
-                             property->getType(), 0, CD, true, false, true,
+                             property->getType(), 0, CD, true, false, true, 
+                             false,
                              (property->getPropertyImplementation() ==
                               ObjCPropertyDecl::Optional) ?
                              ObjCMethodDecl::Optional :
@@ -1094,6 +1127,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
                                property->getLocation(),
                                property->getSetterName(),
                                Context.VoidTy, 0, CD, true, false, true,
+                               false,
                                (property->getPropertyImplementation() ==
                                 ObjCPropertyDecl::Optional) ?
                                ObjCMethodDecl::Optional :
@@ -1105,8 +1139,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
                                                   property->getIdentifier(),
                                                   property->getType(),
                                                   /*TInfo=*/0,
-                                                  VarDecl::None,
-                                                  VarDecl::None,
+                                                  SC_None,
+                                                  SC_None,
                                                   0);
       SetterMethod->setMethodParams(Context, &Argument, 1, 1);
       CD->addDecl(SetterMethod);
@@ -1138,11 +1172,10 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
     AddInstanceMethodToGlobalPool(SetterMethod);
 }
 
-void Sema::CheckObjCPropertyAttributes(DeclPtrTy PropertyPtrTy,
+void Sema::CheckObjCPropertyAttributes(Decl *PDecl,
                                        SourceLocation Loc,
                                        unsigned &Attributes) {
   // FIXME: Improve the reported location.
-  Decl *PDecl = PropertyPtrTy.getAs<Decl>();
   if (!PDecl)
     return;
 
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index c4ab906..11b4bb3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -11,13 +11,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "Lookup.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeOrdering.h"
@@ -27,6 +30,34 @@
 #include <algorithm>
 
 namespace clang {
+using namespace sema;
+
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+                                 bool InOverloadResolution,
+                                 StandardConversionSequence &SCS);
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+                        UserDefinedConversionSequence& User,
+                        OverloadCandidateSet& Conversions,
+                        bool AllowExplicit);
+
+
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+                                   const StandardConversionSequence& SCS1,
+                                   const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareQualificationConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2);
+
+static ImplicitConversionSequence::CompareKind
+CompareDerivedToBaseConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2);
+
+
 
 /// GetConversionCategory - Retrieve the implicit conversion
 /// category corresponding to the given implicit conversion kind.
@@ -298,7 +329,7 @@ namespace {
 OverloadCandidate::DeductionFailureInfo
 static MakeDeductionFailureInfo(ASTContext &Context,
                                 Sema::TemplateDeductionResult TDK,
-                                Sema::TemplateDeductionInfo &Info) {
+                                TemplateDeductionInfo &Info) {
   OverloadCandidate::DeductionFailureInfo Result;
   Result.Result = static_cast<unsigned>(TDK);
   Result.Data = 0;
@@ -315,7 +346,7 @@ static MakeDeductionFailureInfo(ASTContext &Context,
     break;
       
   case Sema::TDK_Inconsistent:
-  case Sema::TDK_InconsistentQuals: {
+  case Sema::TDK_Underqualified: {
     // FIXME: Should allocate from normal heap so that we can free this later.
     DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
     Saved->Param = Info.Param;
@@ -348,7 +379,7 @@ void OverloadCandidate::DeductionFailureInfo::Destroy() {
     break;
       
   case Sema::TDK_Inconsistent:
-  case Sema::TDK_InconsistentQuals:
+  case Sema::TDK_Underqualified:
     // FIXME: Destroy the data?
     Data = 0;
     break;
@@ -380,7 +411,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
     return TemplateParameter::getFromOpaqueValue(Data);    
 
   case Sema::TDK_Inconsistent:
-  case Sema::TDK_InconsistentQuals:
+  case Sema::TDK_Underqualified:
     return static_cast<DFIParamWithArguments*>(Data)->Param;
       
   // Unhandled
@@ -402,7 +433,7 @@ OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
     case Sema::TDK_Incomplete:
     case Sema::TDK_InvalidExplicitArguments:
     case Sema::TDK_Inconsistent:
-    case Sema::TDK_InconsistentQuals:
+    case Sema::TDK_Underqualified:
       return 0;
 
     case Sema::TDK_SubstitutionFailure:
@@ -429,7 +460,7 @@ const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
     return 0;
 
   case Sema::TDK_Inconsistent:
-  case Sema::TDK_InconsistentQuals:
+  case Sema::TDK_Underqualified:
     return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;      
 
   // Unhandled
@@ -454,7 +485,7 @@ OverloadCandidate::DeductionFailureInfo::getSecondArg() {
     return 0;
 
   case Sema::TDK_Inconsistent:
-  case Sema::TDK_InconsistentQuals:
+  case Sema::TDK_Underqualified:
     return &static_cast<DFIParamWithArguments*>(Data)->SecondArg;
 
   // Unhandled
@@ -573,6 +604,11 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
 
 bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
                       bool UseUsingDeclRules) {
+  // If both of the functions are extern "C", then they are not
+  // overloads.
+  if (Old->isExternC() && New->isExternC())
+    return false;
+
   FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
   FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
 
@@ -669,40 +705,34 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
 /// not permitted.
 /// If @p AllowExplicit, then explicit user-defined conversions are
 /// permitted.
-ImplicitConversionSequence
-Sema::TryImplicitConversion(Expr* From, QualType ToType,
-                            bool SuppressUserConversions,
-                            bool AllowExplicit, 
-                            bool InOverloadResolution) {
+static ImplicitConversionSequence
+TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
+                      bool SuppressUserConversions,
+                      bool AllowExplicit, 
+                      bool InOverloadResolution) {
   ImplicitConversionSequence ICS;
-  if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard)) {
+  if (IsStandardConversion(S, From, ToType, InOverloadResolution,
+                           ICS.Standard)) {
     ICS.setStandard();
     return ICS;
   }
 
-  if (!getLangOptions().CPlusPlus) {
+  if (!S.getLangOptions().CPlusPlus) {
     ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
     return ICS;
   }
 
-  if (SuppressUserConversions) {
-    // C++ [over.ics.user]p4:
-    //   A conversion of an expression of class type to the same class
-    //   type is given Exact Match rank, and a conversion of an
-    //   expression of class type to a base class of that type is
-    //   given Conversion rank, in spite of the fact that a copy/move
-    //   constructor (i.e., a user-defined conversion function) is
-    //   called for those cases.
-    QualType FromType = From->getType();
-    if (!ToType->getAs<RecordType>() || !FromType->getAs<RecordType>() ||
-        !(Context.hasSameUnqualifiedType(FromType, ToType) ||
-          IsDerivedFrom(FromType, ToType))) {
-      // We're not in the case above, so there is no conversion that
-      // we can perform.
-      ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
-      return ICS;
-    }
-
+  // C++ [over.ics.user]p4:
+  //   A conversion of an expression of class type to the same class
+  //   type is given Exact Match rank, and a conversion of an
+  //   expression of class type to a base class of that type is
+  //   given Conversion rank, in spite of the fact that a copy/move
+  //   constructor (i.e., a user-defined conversion function) is
+  //   called for those cases.
+  QualType FromType = From->getType();
+  if (ToType->getAs<RecordType>() && FromType->getAs<RecordType>() &&
+      (S.Context.hasSameUnqualifiedType(FromType, ToType) ||
+       S.IsDerivedFrom(FromType, ToType))) {
     ICS.setStandard();
     ICS.Standard.setAsIdentityConversion();
     ICS.Standard.setFromType(FromType);
@@ -713,18 +743,25 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
     // exists. When we actually perform initialization, we'll find the
     // appropriate constructor to copy the returned object, if needed.
     ICS.Standard.CopyConstructor = 0;
-
+    
     // Determine whether this is considered a derived-to-base conversion.
-    if (!Context.hasSameUnqualifiedType(FromType, ToType))
+    if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
       ICS.Standard.Second = ICK_Derived_To_Base;
-
+    
+    return ICS;
+  }
+  
+  if (SuppressUserConversions) {
+    // We're not in the case above, so there is no conversion that
+    // we can perform.
+    ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
     return ICS;
   }
 
   // Attempt user-defined conversion.
   OverloadCandidateSet Conversions(From->getExprLoc());
   OverloadingResult UserDefResult
-    = IsUserDefinedConversion(From, ToType, ICS.UserDefined, Conversions,
+    = IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
                               AllowExplicit);
 
   if (UserDefResult == OR_Success) {
@@ -739,10 +776,11 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
     if (CXXConstructorDecl *Constructor
           = dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
       QualType FromCanon
-        = Context.getCanonicalType(From->getType().getUnqualifiedType());
-      QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
+        = S.Context.getCanonicalType(From->getType().getUnqualifiedType());
+      QualType ToCanon
+        = S.Context.getCanonicalType(ToType).getUnqualifiedType();
       if (Constructor->isCopyConstructor() &&
-          (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) {
+          (FromCanon == ToCanon || S.IsDerivedFrom(FromCanon, ToCanon))) {
         // Turn this into a "standard" conversion sequence, so that it
         // gets ranked with standard conversion sequences.
         ICS.setStandard();
@@ -780,6 +818,24 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
   return ICS;
 }
 
+bool Sema::TryImplicitConversion(InitializationSequence &Sequence,
+                                 const InitializedEntity &Entity,
+                                 Expr *Initializer,
+                                 bool SuppressUserConversions,
+                                 bool AllowExplicitConversions,
+                                 bool InOverloadResolution) {
+  ImplicitConversionSequence ICS
+    = clang::TryImplicitConversion(*this, Initializer, Entity.getType(),
+                                   SuppressUserConversions,
+                                   AllowExplicitConversions, 
+                                   InOverloadResolution);
+  if (ICS.isBad()) return true;
+
+  // Perform the actual conversion.
+  Sequence.AddConversionSequenceStep(ICS, Entity.getType());
+  return false;
+}
+
 /// PerformImplicitConversion - Perform an implicit conversion of the
 /// expression From to the type ToType. Returns true if there was an
 /// error, false otherwise. The expression From is replaced with the
@@ -797,10 +853,10 @@ bool
 Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
                                 AssignmentAction Action, bool AllowExplicit,
                                 ImplicitConversionSequence& ICS) {
-  ICS = TryImplicitConversion(From, ToType,
-                              /*SuppressUserConversions=*/false,
-                              AllowExplicit,
-                              /*InOverloadResolution=*/false);
+  ICS = clang::TryImplicitConversion(*this, From, ToType,
+                                     /*SuppressUserConversions=*/false,
+                                     AllowExplicit,
+                                     /*InOverloadResolution=*/false);
   return PerformImplicitConversion(From, ToType, ICS, Action);
 }
   
@@ -850,16 +906,20 @@ static bool IsVectorConversion(ASTContext &Context, QualType FromType,
       return true;
     }
   }
-  
-  // If lax vector conversions are permitted and the vector types are of the
-  // same size, we can perform the conversion.
-  if (Context.getLangOptions().LaxVectorConversions &&
-      FromType->isVectorType() && ToType->isVectorType() &&
-      Context.getTypeSize(FromType) == Context.getTypeSize(ToType)) {
-    ICK = ICK_Vector_Conversion;
-    return true;
+
+  // We can perform the conversion between vector types in the following cases:
+  // 1)vector types are equivalent AltiVec and GCC vector types
+  // 2)lax vector conversions are permitted and the vector types are of the
+  //   same size
+  if (ToType->isVectorType() && FromType->isVectorType()) {
+    if (Context.areCompatibleVectorTypes(FromType, ToType) ||
+        (Context.getLangOptions().LaxVectorConversions &&
+         (Context.getTypeSize(FromType) == Context.getTypeSize(ToType)))) {
+      ICK = ICK_Vector_Conversion;
+      return true;
+    }
   }
-  
+
   return false;
 }
   
@@ -871,12 +931,11 @@ static bool IsVectorConversion(ASTContext &Context, QualType FromType,
 /// contain the standard conversion sequence required to perform this
 /// conversion and this routine will return true. Otherwise, this
 /// routine will return false and the value of SCS is unspecified.
-bool
-Sema::IsStandardConversion(Expr* From, QualType ToType,
-                           bool InOverloadResolution,
-                           StandardConversionSequence &SCS) {
+static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
+                                 bool InOverloadResolution,
+                                 StandardConversionSequence &SCS) {
   QualType FromType = From->getType();
-
+  
   // Standard conversions (C++ [conv])
   SCS.setAsIdentityConversion();
   SCS.DeprecatedStringLiteralToCharPtr = false;
@@ -887,7 +946,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
   // There are no standard conversions for class types in C++, so
   // abort early. When overloading in C, however, we do permit
   if (FromType->isRecordType() || ToType->isRecordType()) {
-    if (getLangOptions().CPlusPlus)
+    if (S.getLangOptions().CPlusPlus)
       return false;
 
     // When we're overloading in C, we allow, as standard conversions,
@@ -897,19 +956,19 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
   // array-to-pointer conversion, or function-to-pointer conversion
   // (C++ 4p1).
 
-  if (FromType == Context.OverloadTy) {
+  if (FromType == S.Context.OverloadTy) {
     DeclAccessPair AccessPair;
     if (FunctionDecl *Fn
-          = ResolveAddressOfOverloadedFunction(From, ToType, false, 
-                                               AccessPair)) {
+          = S.ResolveAddressOfOverloadedFunction(From, ToType, false, 
+                                                 AccessPair)) {
       // We were able to resolve the address of the overloaded function,
       // so we can convert to the type of that function.
       FromType = Fn->getType();
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
         if (!Method->isStatic()) {
           Type *ClassType 
-            = Context.getTypeDeclType(Method->getParent()).getTypePtr();
-          FromType = Context.getMemberPointerType(FromType, ClassType);
+            = S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
+          FromType = S.Context.getMemberPointerType(FromType, ClassType);
         }
       }
       
@@ -917,12 +976,12 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
       // function, update the type of the resulting expression accordingly.
       if (FromType->getAs<FunctionType>())
         if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens()))
-          if (UnOp->getOpcode() == UnaryOperator::AddrOf)
-            FromType = Context.getPointerType(FromType);
+          if (UnOp->getOpcode() == UO_AddrOf)
+            FromType = S.Context.getPointerType(FromType);
  
       // Check that we've computed the proper type after overload resolution.
-      assert(Context.hasSameType(FromType,
-              FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
+      assert(S.Context.hasSameType(FromType,
+            S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
     } else {
       return false;
     }
@@ -930,10 +989,10 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
   // Lvalue-to-rvalue conversion (C++ 4.1):
   //   An lvalue (3.10) of a non-function, non-array type T can be
   //   converted to an rvalue.
-  Expr::isLvalueResult argIsLvalue = From->isLvalue(Context);
+  Expr::isLvalueResult argIsLvalue = From->isLvalue(S.Context);
   if (argIsLvalue == Expr::LV_Valid &&
       !FromType->isFunctionType() && !FromType->isArrayType() &&
-      Context.getCanonicalType(FromType) != Context.OverloadTy) {
+      S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
     SCS.First = ICK_Lvalue_To_Rvalue;
 
     // If T is a non-class type, the type of the rvalue is the
@@ -948,9 +1007,9 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
     // An lvalue or rvalue of type "array of N T" or "array of unknown
     // bound of T" can be converted to an rvalue of type "pointer to
     // T" (C++ 4.2p1).
-    FromType = Context.getArrayDecayedType(FromType);
+    FromType = S.Context.getArrayDecayedType(FromType);
 
-    if (IsStringLiteralToNonConstPointerConversion(From, ToType)) {
+    if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
       // This conversion is deprecated. (C++ D.4).
       SCS.DeprecatedStringLiteralToCharPtr = true;
 
@@ -970,7 +1029,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
     // An lvalue of function type T can be converted to an rvalue of
     // type "pointer to T." The result is a pointer to the
     // function. (C++ 4.3p1).
-    FromType = Context.getPointerType(FromType);
+    FromType = S.Context.getPointerType(FromType);
   } else {
     // We don't require any conversions for the first step.
     SCS.First = ICK_Identity;
@@ -985,24 +1044,24 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
   // conversion.
   bool IncompatibleObjC = false;
   ImplicitConversionKind SecondICK = ICK_Identity;
-  if (Context.hasSameUnqualifiedType(FromType, ToType)) {
+  if (S.Context.hasSameUnqualifiedType(FromType, ToType)) {
     // The unqualified versions of the types are the same: there's no
     // conversion to do.
     SCS.Second = ICK_Identity;
-  } else if (IsIntegralPromotion(From, FromType, ToType)) {
+  } else if (S.IsIntegralPromotion(From, FromType, ToType)) {
     // Integral promotion (C++ 4.5).
     SCS.Second = ICK_Integral_Promotion;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsFloatingPointPromotion(FromType, ToType)) {
+  } else if (S.IsFloatingPointPromotion(FromType, ToType)) {
     // Floating point promotion (C++ 4.6).
     SCS.Second = ICK_Floating_Promotion;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsComplexPromotion(FromType, ToType)) {
+  } else if (S.IsComplexPromotion(FromType, ToType)) {
     // Complex promotion (Clang extension)
     SCS.Second = ICK_Complex_Promotion;
     FromType = ToType.getUnqualifiedType();
   } else if (FromType->isIntegralOrEnumerationType() &&
-             ToType->isIntegralType(Context)) {
+             ToType->isIntegralType(S.Context)) {
     // Integral conversions (C++ 4.7).
     SCS.Second = ICK_Integral_Conversion;
     FromType = ToType.getUnqualifiedType();
@@ -1020,19 +1079,19 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
     SCS.Second = ICK_Floating_Conversion;
     FromType = ToType.getUnqualifiedType();
   } else if ((FromType->isRealFloatingType() && 
-              ToType->isIntegralType(Context) && !ToType->isBooleanType()) ||
+              ToType->isIntegralType(S.Context) && !ToType->isBooleanType()) ||
              (FromType->isIntegralOrEnumerationType() &&
               ToType->isRealFloatingType())) {
     // Floating-integral conversions (C++ 4.9).
     SCS.Second = ICK_Floating_Integral;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsPointerConversion(From, FromType, ToType, InOverloadResolution,
-                                 FromType, IncompatibleObjC)) {
+  } else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution,
+                                   FromType, IncompatibleObjC)) {
     // Pointer conversions (C++ 4.10).
     SCS.Second = ICK_Pointer_Conversion;
     SCS.IncompatibleObjC = IncompatibleObjC;
-  } else if (IsMemberPointerConversion(From, FromType, ToType, 
-                                       InOverloadResolution, FromType)) {
+  } else if (S.IsMemberPointerConversion(From, FromType, ToType, 
+                                         InOverloadResolution, FromType)) {
     // Pointer to member conversions (4.11).
     SCS.Second = ICK_Pointer_Member;
   } else if (ToType->isBooleanType() &&
@@ -1044,16 +1103,16 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
               FromType->isNullPtrType())) {
     // Boolean conversions (C++ 4.12).
     SCS.Second = ICK_Boolean_Conversion;
-    FromType = Context.BoolTy;
-  } else if (IsVectorConversion(Context, FromType, ToType, SecondICK)) {
+    FromType = S.Context.BoolTy;
+  } else if (IsVectorConversion(S.Context, FromType, ToType, SecondICK)) {
     SCS.Second = SecondICK;
     FromType = ToType.getUnqualifiedType();
-  } else if (!getLangOptions().CPlusPlus &&
-             Context.typesAreCompatible(ToType, FromType)) {
+  } else if (!S.getLangOptions().CPlusPlus &&
+             S.Context.typesAreCompatible(ToType, FromType)) {
     // Compatible conversions (Clang extension for C function overloading)
     SCS.Second = ICK_Compatible_Conversion;
     FromType = ToType.getUnqualifiedType();
-  } else if (IsNoReturnConversion(Context, FromType, ToType, FromType)) {
+  } else if (IsNoReturnConversion(S.Context, FromType, ToType, FromType)) {
     // Treat a conversion that strips "noreturn" as an identity conversion.
     SCS.Second = ICK_NoReturn_Adjustment;
   } else {
@@ -1065,11 +1124,11 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
   QualType CanonFrom;
   QualType CanonTo;
   // The third conversion can be a qualification conversion (C++ 4p1).
-  if (IsQualificationConversion(FromType, ToType)) {
+  if (S.IsQualificationConversion(FromType, ToType)) {
     SCS.Third = ICK_Qualification;
     FromType = ToType;
-    CanonFrom = Context.getCanonicalType(FromType);
-    CanonTo = Context.getCanonicalType(ToType);
+    CanonFrom = S.Context.getCanonicalType(FromType);
+    CanonTo = S.Context.getCanonicalType(ToType);
   } else {
     // No conversion required
     SCS.Third = ICK_Identity;
@@ -1078,8 +1137,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
     //   [...] Any difference in top-level cv-qualification is
     //   subsumed by the initialization itself and does not constitute
     //   a conversion. [...]
-    CanonFrom = Context.getCanonicalType(FromType);
-    CanonTo = Context.getCanonicalType(ToType);
+    CanonFrom = S.Context.getCanonicalType(FromType);
+    CanonTo = S.Context.getCanonicalType(ToType);
     if (CanonFrom.getLocalUnqualifiedType() 
                                        == CanonTo.getLocalUnqualifiedType() &&
         (CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()
@@ -1397,10 +1456,16 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
 
   QualType FromPointeeType = FromTypePtr->getPointeeType();
 
+  // If the unqualified pointee types are the same, this can't be a 
+  // pointer conversion, so don't do all of the work below.
+  if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType))
+    return false;
+
   // An rvalue of type "pointer to cv T," where T is an object type,
   // can be converted to an rvalue of type "pointer to cv void" (C++
   // 4.10p2).
-  if (FromPointeeType->isObjectType() && ToPointeeType->isVoidType()) {
+  if (FromPointeeType->isIncompleteOrObjectType() &&
+      ToPointeeType->isVoidType()) {
     ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
                                                        ToPointeeType,
                                                        ToType, Context);
@@ -1657,8 +1722,8 @@ bool Sema::FunctionArgTypesAreEqual(FunctionProtoType*  OldType,
 /// true. It returns true and produces a diagnostic if there was an
 /// error, or returns false otherwise.
 bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
-                                  CastExpr::CastKind &Kind,
-                                  CXXBaseSpecifierArray& BasePath,
+                                  CastKind &Kind,
+                                  CXXCastPath& BasePath,
                                   bool IgnoreBaseAccess) {
   QualType FromType = From->getType();
 
@@ -1684,7 +1749,7 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
           return true;
         
         // The conversion was successful.
-        Kind = CastExpr::CK_DerivedToBase;
+        Kind = CK_DerivedToBase;
       }
     }
   if (const ObjCObjectPointerType *FromPtrType =
@@ -1749,8 +1814,8 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
 /// true and produces a diagnostic if there was an error, or returns false
 /// otherwise.
 bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
-                                        CastExpr::CastKind &Kind,
-                                        CXXBaseSpecifierArray &BasePath,
+                                        CastKind &Kind,
+                                        CXXCastPath &BasePath,
                                         bool IgnoreBaseAccess) {
   QualType FromType = From->getType();
   const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
@@ -1759,7 +1824,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
     assert(From->isNullPointerConstant(Context, 
                                        Expr::NPC_ValueDependentIsNull) &&
            "Expr must be null pointer constant!");
-    Kind = CastExpr::CK_NullToMemberPointer;
+    Kind = CK_NullToMemberPointer;
     return false;
   }
 
@@ -1803,7 +1868,7 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
 
   // Must be a base to derived member conversion.
   BuildBasePathArray(Paths, BasePath);
-  Kind = CastExpr::CK_BaseToDerivedMemberPointer;
+  Kind = CK_BaseToDerivedMemberPointer;
   return false;
 }
 
@@ -1869,10 +1934,11 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
 /// \param AllowExplicit  true if the conversion should consider C++0x
 /// "explicit" conversion functions as well as non-explicit conversion
 /// functions (C++0x [class.conv.fct]p2).
-OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
-                                          UserDefinedConversionSequence& User,
-                                           OverloadCandidateSet& CandidateSet,
-                                                bool AllowExplicit) {
+static OverloadingResult
+IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
+                        UserDefinedConversionSequence& User,
+                        OverloadCandidateSet& CandidateSet,
+                        bool AllowExplicit) {
   // Whether we will only visit constructors.
   bool ConstructorsOnly = false;
 
@@ -1887,17 +1953,17 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
     //   functions are all the converting constructors (12.3.1) of
     //   that class. The argument list is the expression-list within
     //   the parentheses of the initializer.
-    if (Context.hasSameUnqualifiedType(ToType, From->getType()) ||
+    if (S.Context.hasSameUnqualifiedType(ToType, From->getType()) ||
         (From->getType()->getAs<RecordType>() &&
-         IsDerivedFrom(From->getType(), ToType)))
+         S.IsDerivedFrom(From->getType(), ToType)))
       ConstructorsOnly = true;
 
-    if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) {
+    if (S.RequireCompleteType(From->getLocStart(), ToType, S.PDiag())) {
       // We're not going to find any constructors.
     } else if (CXXRecordDecl *ToRecordDecl
                  = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
       DeclContext::lookup_iterator Con, ConEnd;
-      for (llvm::tie(Con, ConEnd) = LookupConstructors(ToRecordDecl);
+      for (llvm::tie(Con, ConEnd) = S.LookupConstructors(ToRecordDecl);
            Con != ConEnd; ++Con) {
         NamedDecl *D = *Con;
         DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
@@ -1915,16 +1981,18 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
         if (!Constructor->isInvalidDecl() &&
             Constructor->isConvertingConstructor(AllowExplicit)) {
           if (ConstructorTmpl)
-            AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
-                                         /*ExplicitArgs*/ 0,
-                                         &From, 1, CandidateSet, 
-                                 /*SuppressUserConversions=*/!ConstructorsOnly);
+            S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
+                                           /*ExplicitArgs*/ 0,
+                                           &From, 1, CandidateSet, 
+                                           /*SuppressUserConversions=*/
+                                             !ConstructorsOnly);
           else
             // Allow one user-defined conversion when user specifies a
             // From->ToType conversion via an static cast (c-style, etc).
-            AddOverloadCandidate(Constructor, FoundDecl,
-                                 &From, 1, CandidateSet,
-                                 /*SuppressUserConversions=*/!ConstructorsOnly);
+            S.AddOverloadCandidate(Constructor, FoundDecl,
+                                   &From, 1, CandidateSet,
+                                   /*SuppressUserConversions=*/
+                                     !ConstructorsOnly);
         }
       }
     }
@@ -1932,8 +2000,8 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
 
   // Enumerate conversion functions, if we're allowed to.
   if (ConstructorsOnly) {
-  } else if (RequireCompleteType(From->getLocStart(), From->getType(),
-                          PDiag(0) << From->getSourceRange())) {
+  } else if (S.RequireCompleteType(From->getLocStart(), From->getType(),
+                                   S.PDiag(0) << From->getSourceRange())) {
     // No conversion functions from incomplete types.
   } else if (const RecordType *FromRecordType
                                    = From->getType()->getAs<RecordType>()) {
@@ -1959,80 +2027,79 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
 
         if (AllowExplicit || !Conv->isExplicit()) {
           if (ConvTemplate)
-            AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
-                                           ActingContext, From, ToType,
-                                           CandidateSet);
+            S.AddTemplateConversionCandidate(ConvTemplate, FoundDecl,
+                                             ActingContext, From, ToType,
+                                             CandidateSet);
           else
-            AddConversionCandidate(Conv, FoundDecl, ActingContext,
-                                   From, ToType, CandidateSet);
+            S.AddConversionCandidate(Conv, FoundDecl, ActingContext,
+                                     From, ToType, CandidateSet);
         }
       }
     }
   }
 
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, From->getLocStart(), Best)) {
-    case OR_Success:
-      // Record the standard conversion we used and the conversion function.
-      if (CXXConstructorDecl *Constructor
-            = dyn_cast<CXXConstructorDecl>(Best->Function)) {
-        // C++ [over.ics.user]p1:
-        //   If the user-defined conversion is specified by a
-        //   constructor (12.3.1), the initial standard conversion
-        //   sequence converts the source type to the type required by
-        //   the argument of the constructor.
-        //
-        QualType ThisType = Constructor->getThisType(Context);
-        if (Best->Conversions[0].isEllipsis())
-          User.EllipsisConversion = true;
-        else {
-          User.Before = Best->Conversions[0].Standard;
-          User.EllipsisConversion = false;
-        }
-        User.ConversionFunction = Constructor;
-        User.After.setAsIdentityConversion();
-        User.After.setFromType(
-          ThisType->getAs<PointerType>()->getPointeeType());
-        User.After.setAllToTypes(ToType);
-        return OR_Success;
-      } else if (CXXConversionDecl *Conversion
-                   = dyn_cast<CXXConversionDecl>(Best->Function)) {
-        // C++ [over.ics.user]p1:
-        //
-        //   [...] If the user-defined conversion is specified by a
-        //   conversion function (12.3.2), the initial standard
-        //   conversion sequence converts the source type to the
-        //   implicit object parameter of the conversion function.
+  switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best)) {
+  case OR_Success:
+    // Record the standard conversion we used and the conversion function.
+    if (CXXConstructorDecl *Constructor
+          = dyn_cast<CXXConstructorDecl>(Best->Function)) {
+      // C++ [over.ics.user]p1:
+      //   If the user-defined conversion is specified by a
+      //   constructor (12.3.1), the initial standard conversion
+      //   sequence converts the source type to the type required by
+      //   the argument of the constructor.
+      //
+      QualType ThisType = Constructor->getThisType(S.Context);
+      if (Best->Conversions[0].isEllipsis())
+        User.EllipsisConversion = true;
+      else {
         User.Before = Best->Conversions[0].Standard;
-        User.ConversionFunction = Conversion;
         User.EllipsisConversion = false;
-
-        // C++ [over.ics.user]p2:
-        //   The second standard conversion sequence converts the
-        //   result of the user-defined conversion to the target type
-        //   for the sequence. Since an implicit conversion sequence
-        //   is an initialization, the special rules for
-        //   initialization by user-defined conversion apply when
-        //   selecting the best user-defined conversion for a
-        //   user-defined conversion sequence (see 13.3.3 and
-        //   13.3.3.1).
-        User.After = Best->FinalConversion;
-        return OR_Success;
-      } else {
-        assert(false && "Not a constructor or conversion function?");
-        return OR_No_Viable_Function;
       }
-
-    case OR_No_Viable_Function:
+      User.ConversionFunction = Constructor;
+      User.After.setAsIdentityConversion();
+      User.After.setFromType(ThisType->getAs<PointerType>()->getPointeeType());
+      User.After.setAllToTypes(ToType);
+      return OR_Success;
+    } else if (CXXConversionDecl *Conversion
+                 = dyn_cast<CXXConversionDecl>(Best->Function)) {
+      // C++ [over.ics.user]p1:
+      //
+      //   [...] If the user-defined conversion is specified by a
+      //   conversion function (12.3.2), the initial standard
+      //   conversion sequence converts the source type to the
+      //   implicit object parameter of the conversion function.
+      User.Before = Best->Conversions[0].Standard;
+      User.ConversionFunction = Conversion;
+      User.EllipsisConversion = false;
+
+      // C++ [over.ics.user]p2:
+      //   The second standard conversion sequence converts the
+      //   result of the user-defined conversion to the target type
+      //   for the sequence. Since an implicit conversion sequence
+      //   is an initialization, the special rules for
+      //   initialization by user-defined conversion apply when
+      //   selecting the best user-defined conversion for a
+      //   user-defined conversion sequence (see 13.3.3 and
+      //   13.3.3.1).
+      User.After = Best->FinalConversion;
+      return OR_Success;
+    } else {
+      llvm_unreachable("Not a constructor or conversion function?");
       return OR_No_Viable_Function;
-    case OR_Deleted:
-      // No conversion here! We're done.
-      return OR_Deleted;
-
-    case OR_Ambiguous:
-      return OR_Ambiguous;
     }
 
+  case OR_No_Viable_Function:
+    return OR_No_Viable_Function;
+  case OR_Deleted:
+    // No conversion here! We're done.
+    return OR_Deleted;
+    
+  case OR_Ambiguous:
+    return OR_Ambiguous;
+  }
+
   return OR_No_Viable_Function;
 }
   
@@ -2041,7 +2108,7 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
   ImplicitConversionSequence ICS;
   OverloadCandidateSet CandidateSet(From->getExprLoc());
   OverloadingResult OvResult = 
-    IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+    IsUserDefinedConversion(*this, From, ToType, ICS.UserDefined,
                             CandidateSet, false);
   if (OvResult == OR_Ambiguous)
     Diag(From->getSourceRange().getBegin(),
@@ -2053,16 +2120,17 @@ Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
     << From->getType() << ToType << From->getSourceRange();
   else
     return false;
-  PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &From, 1);
+  CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &From, 1);
   return true;  
 }
 
 /// CompareImplicitConversionSequences - Compare two implicit
 /// conversion sequences to determine whether one is better than the
 /// other or if they are indistinguishable (C++ 13.3.3.2).
-ImplicitConversionSequence::CompareKind
-Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
-                                         const ImplicitConversionSequence& ICS2)
+static ImplicitConversionSequence::CompareKind
+CompareImplicitConversionSequences(Sema &S,
+                                   const ImplicitConversionSequence& ICS1,
+                                   const ImplicitConversionSequence& ICS2)
 {
   // (C++ 13.3.3.2p2): When comparing the basic forms of implicit
   // conversion sequences (as defined in 13.3.3.1)
@@ -2092,7 +2160,7 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
   // indistinguishable conversion sequences unless one of the
   // following rules apply: (C++ 13.3.3.2p3):
   if (ICS1.isStandard())
-    return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
+    return CompareStandardConversionSequences(S, ICS1.Standard, ICS2.Standard);
   else if (ICS1.isUserDefined()) {
     // User-defined conversion sequence U1 is a better conversion
     // sequence than another user-defined conversion sequence U2 if
@@ -2102,7 +2170,8 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
     // U2 (C++ 13.3.3.2p3).
     if (ICS1.UserDefined.ConversionFunction ==
           ICS2.UserDefined.ConversionFunction)
-      return CompareStandardConversionSequences(ICS1.UserDefined.After,
+      return CompareStandardConversionSequences(S,
+                                                ICS1.UserDefined.After,
                                                 ICS2.UserDefined.After);
   }
 
@@ -2168,9 +2237,10 @@ compareStandardConversionSubsets(ASTContext &Context,
 /// CompareStandardConversionSequences - Compare two standard
 /// conversion sequences to determine whether one is better than the
 /// other or if they are indistinguishable (C++ 13.3.3.2p3).
-ImplicitConversionSequence::CompareKind
-Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
-                                         const StandardConversionSequence& SCS2)
+static ImplicitConversionSequence::CompareKind
+CompareStandardConversionSequences(Sema &S,
+                                   const StandardConversionSequence& SCS1,
+                                   const StandardConversionSequence& SCS2)
 {
   // Standard conversion sequence S1 is a better conversion sequence
   // than standard conversion sequence S2 if (C++ 13.3.3.2p3):
@@ -2181,7 +2251,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
   //     sequence is considered to be a subsequence of any
   //     non-identity conversion sequence) or, if not that,
   if (ImplicitConversionSequence::CompareKind CK
-        = compareStandardConversionSubsets(Context, SCS1, SCS2))
+        = compareStandardConversionSubsets(S.Context, SCS1, SCS2))
     return CK;
 
   //  -- the rank of S1 is better than the rank of S2 (by the rules
@@ -2212,9 +2282,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
   //   void*, and conversion of A* to void* is better than conversion
   //   of B* to void*.
   bool SCS1ConvertsToVoid
-    = SCS1.isPointerConversionToVoidPointer(Context);
+    = SCS1.isPointerConversionToVoidPointer(S.Context);
   bool SCS2ConvertsToVoid
-    = SCS2.isPointerConversionToVoidPointer(Context);
+    = SCS2.isPointerConversionToVoidPointer(S.Context);
   if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) {
     // Exactly one of the conversion sequences is a conversion to
     // a void pointer; it's the worse conversion.
@@ -2224,7 +2294,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
     // Neither conversion sequence converts to a void pointer; compare
     // their derived-to-base conversions.
     if (ImplicitConversionSequence::CompareKind DerivedCK
-          = CompareDerivedToBaseConversions(SCS1, SCS2))
+          = CompareDerivedToBaseConversions(S, SCS1, SCS2))
       return DerivedCK;
   } else if (SCS1ConvertsToVoid && SCS2ConvertsToVoid) {
     // Both conversion sequences are conversions to void
@@ -2236,18 +2306,18 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
     // Adjust the types we're converting from via the array-to-pointer
     // conversion, if we need to.
     if (SCS1.First == ICK_Array_To_Pointer)
-      FromType1 = Context.getArrayDecayedType(FromType1);
+      FromType1 = S.Context.getArrayDecayedType(FromType1);
     if (SCS2.First == ICK_Array_To_Pointer)
-      FromType2 = Context.getArrayDecayedType(FromType2);
+      FromType2 = S.Context.getArrayDecayedType(FromType2);
 
     QualType FromPointee1
       = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
     QualType FromPointee2
       = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
 
-    if (IsDerivedFrom(FromPointee2, FromPointee1))
+    if (S.IsDerivedFrom(FromPointee2, FromPointee1))
       return ImplicitConversionSequence::Better;
-    else if (IsDerivedFrom(FromPointee1, FromPointee2))
+    else if (S.IsDerivedFrom(FromPointee1, FromPointee2))
       return ImplicitConversionSequence::Worse;
 
     // Objective-C++: If one interface is more specific than the
@@ -2255,9 +2325,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
     const ObjCObjectType* FromIface1 = FromPointee1->getAs<ObjCObjectType>();
     const ObjCObjectType* FromIface2 = FromPointee2->getAs<ObjCObjectType>();
     if (FromIface1 && FromIface1) {
-      if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+      if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
         return ImplicitConversionSequence::Better;
-      else if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+      else if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
         return ImplicitConversionSequence::Worse;
     }
   }
@@ -2265,7 +2335,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
   // Compare based on qualification conversions (C++ 13.3.3.2p3,
   // bullet 3).
   if (ImplicitConversionSequence::CompareKind QualCK
-        = CompareQualificationConversions(SCS1, SCS2))
+        = CompareQualificationConversions(S, SCS1, SCS2))
     return QualCK;
 
   if (SCS1.ReferenceBinding && SCS2.ReferenceBinding) {
@@ -2289,18 +2359,18 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
     //      to which the reference initialized by S1 refers.
     QualType T1 = SCS1.getToType(2);
     QualType T2 = SCS2.getToType(2);
-    T1 = Context.getCanonicalType(T1);
-    T2 = Context.getCanonicalType(T2);
+    T1 = S.Context.getCanonicalType(T1);
+    T2 = S.Context.getCanonicalType(T2);
     Qualifiers T1Quals, T2Quals;
-    QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
-    QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+    QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+    QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
     if (UnqualT1 == UnqualT2) {
       // If the type is an array type, promote the element qualifiers to the type
       // for comparison.
       if (isa<ArrayType>(T1) && T1Quals)
-        T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+        T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
       if (isa<ArrayType>(T2) && T2Quals)
-        T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+        T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
       if (T2.isMoreQualifiedThan(T1))
         return ImplicitConversionSequence::Better;
       else if (T1.isMoreQualifiedThan(T2))
@@ -2315,8 +2385,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
 /// sequences to determine whether they can be ranked based on their
 /// qualification conversions (C++ 13.3.3.2p3 bullet 3).
 ImplicitConversionSequence::CompareKind
-Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
-                                      const StandardConversionSequence& SCS2) {
+CompareQualificationConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2) {
   // C++ 13.3.3.2p3:
   //  -- S1 and S2 differ only in their qualification conversion and
   //     yield similar types T1 and T2 (C++ 4.4), respectively, and the
@@ -2331,11 +2402,11 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
   // conversion (!)
   QualType T1 = SCS1.getToType(2);
   QualType T2 = SCS2.getToType(2);
-  T1 = Context.getCanonicalType(T1);
-  T2 = Context.getCanonicalType(T2);
+  T1 = S.Context.getCanonicalType(T1);
+  T2 = S.Context.getCanonicalType(T2);
   Qualifiers T1Quals, T2Quals;
-  QualType UnqualT1 = Context.getUnqualifiedArrayType(T1, T1Quals);
-  QualType UnqualT2 = Context.getUnqualifiedArrayType(T2, T2Quals);
+  QualType UnqualT1 = S.Context.getUnqualifiedArrayType(T1, T1Quals);
+  QualType UnqualT2 = S.Context.getUnqualifiedArrayType(T2, T2Quals);
 
   // If the types are the same, we won't learn anything by unwrapped
   // them.
@@ -2345,13 +2416,13 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
   // If the type is an array type, promote the element qualifiers to the type
   // for comparison.
   if (isa<ArrayType>(T1) && T1Quals)
-    T1 = Context.getQualifiedType(UnqualT1, T1Quals);
+    T1 = S.Context.getQualifiedType(UnqualT1, T1Quals);
   if (isa<ArrayType>(T2) && T2Quals)
-    T2 = Context.getQualifiedType(UnqualT2, T2Quals);
+    T2 = S.Context.getQualifiedType(UnqualT2, T2Quals);
 
   ImplicitConversionSequence::CompareKind Result
     = ImplicitConversionSequence::Indistinguishable;
-  while (Context.UnwrapSimilarPointerTypes(T1, T2)) {
+  while (S.Context.UnwrapSimilarPointerTypes(T1, T2)) {
     // Within each iteration of the loop, we check the qualifiers to
     // determine if this still looks like a qualification
     // conversion. Then, if all is well, we unwrap one more level of
@@ -2386,7 +2457,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
     }
 
     // If the types after this point are equivalent, we're done.
-    if (Context.hasSameUnqualifiedType(T1, T2))
+    if (S.Context.hasSameUnqualifiedType(T1, T2))
       break;
   }
 
@@ -2416,8 +2487,9 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
 /// [over.ics.rank]p4b3).  As part of these checks, we also look at
 /// conversions between Objective-C interface types.
 ImplicitConversionSequence::CompareKind
-Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
-                                      const StandardConversionSequence& SCS2) {
+CompareDerivedToBaseConversions(Sema &S,
+                                const StandardConversionSequence& SCS1,
+                                const StandardConversionSequence& SCS2) {
   QualType FromType1 = SCS1.getFromType();
   QualType ToType1 = SCS1.getToType(1);
   QualType FromType2 = SCS2.getFromType();
@@ -2426,15 +2498,15 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
   // Adjust the types we're converting from via the array-to-pointer
   // conversion, if we need to.
   if (SCS1.First == ICK_Array_To_Pointer)
-    FromType1 = Context.getArrayDecayedType(FromType1);
+    FromType1 = S.Context.getArrayDecayedType(FromType1);
   if (SCS2.First == ICK_Array_To_Pointer)
-    FromType2 = Context.getArrayDecayedType(FromType2);
+    FromType2 = S.Context.getArrayDecayedType(FromType2);
 
   // Canonicalize all of the types.
-  FromType1 = Context.getCanonicalType(FromType1);
-  ToType1 = Context.getCanonicalType(ToType1);
-  FromType2 = Context.getCanonicalType(FromType2);
-  ToType2 = Context.getCanonicalType(ToType2);
+  FromType1 = S.Context.getCanonicalType(FromType1);
+  ToType1 = S.Context.getCanonicalType(ToType1);
+  FromType2 = S.Context.getCanonicalType(FromType2);
+  ToType2 = S.Context.getCanonicalType(ToType2);
 
   // C++ [over.ics.rank]p4b3:
   //
@@ -2466,30 +2538,30 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
 
     //   -- conversion of C* to B* is better than conversion of C* to A*,
     if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
-      if (IsDerivedFrom(ToPointee1, ToPointee2))
+      if (S.IsDerivedFrom(ToPointee1, ToPointee2))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(ToPointee2, ToPointee1))
+      else if (S.IsDerivedFrom(ToPointee2, ToPointee1))
         return ImplicitConversionSequence::Worse;
 
       if (ToIface1 && ToIface2) {
-        if (Context.canAssignObjCInterfaces(ToIface2, ToIface1))
+        if (S.Context.canAssignObjCInterfaces(ToIface2, ToIface1))
           return ImplicitConversionSequence::Better;
-        else if (Context.canAssignObjCInterfaces(ToIface1, ToIface2))
+        else if (S.Context.canAssignObjCInterfaces(ToIface1, ToIface2))
           return ImplicitConversionSequence::Worse;
       }
     }
 
     //   -- conversion of B* to A* is better than conversion of C* to A*,
     if (FromPointee1 != FromPointee2 && ToPointee1 == ToPointee2) {
-      if (IsDerivedFrom(FromPointee2, FromPointee1))
+      if (S.IsDerivedFrom(FromPointee2, FromPointee1))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromPointee1, FromPointee2))
+      else if (S.IsDerivedFrom(FromPointee1, FromPointee2))
         return ImplicitConversionSequence::Worse;
 
       if (FromIface1 && FromIface2) {
-        if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
+        if (S.Context.canAssignObjCInterfaces(FromIface1, FromIface2))
           return ImplicitConversionSequence::Better;
-        else if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
+        else if (S.Context.canAssignObjCInterfaces(FromIface2, FromIface1))
           return ImplicitConversionSequence::Worse;
       }
     }
@@ -2517,16 +2589,16 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     QualType ToPointee2 = QualType(ToPointeeType2, 0).getUnqualifiedType();
     // conversion of A::* to B::* is better than conversion of A::* to C::*,
     if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
-      if (IsDerivedFrom(ToPointee1, ToPointee2))
+      if (S.IsDerivedFrom(ToPointee1, ToPointee2))
         return ImplicitConversionSequence::Worse;
-      else if (IsDerivedFrom(ToPointee2, ToPointee1))
+      else if (S.IsDerivedFrom(ToPointee2, ToPointee1))
         return ImplicitConversionSequence::Better;
     }
     // conversion of B::* to C::* is better than conversion of A::* to C::*
     if (ToPointee1 == ToPointee2 && FromPointee1 != FromPointee2) {
-      if (IsDerivedFrom(FromPointee1, FromPointee2))
+      if (S.IsDerivedFrom(FromPointee1, FromPointee2))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromPointee2, FromPointee1))
+      else if (S.IsDerivedFrom(FromPointee2, FromPointee1))
         return ImplicitConversionSequence::Worse;
     }
   }
@@ -2536,11 +2608,11 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     //   -- binding of an expression of type C to a reference of type
     //      B& is better than binding an expression of type C to a
     //      reference of type A&,
-    if (Context.hasSameUnqualifiedType(FromType1, FromType2) &&
-        !Context.hasSameUnqualifiedType(ToType1, ToType2)) {
-      if (IsDerivedFrom(ToType1, ToType2))
+    if (S.Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        !S.Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+      if (S.IsDerivedFrom(ToType1, ToType2))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(ToType2, ToType1))
+      else if (S.IsDerivedFrom(ToType2, ToType1))
         return ImplicitConversionSequence::Worse;
     }
 
@@ -2548,11 +2620,11 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
     //   -- binding of an expression of type B to a reference of type
     //      A& is better than binding an expression of type C to a
     //      reference of type A&,
-    if (!Context.hasSameUnqualifiedType(FromType1, FromType2) &&
-        Context.hasSameUnqualifiedType(ToType1, ToType2)) {
-      if (IsDerivedFrom(FromType2, FromType1))
+    if (!S.Context.hasSameUnqualifiedType(FromType1, FromType2) &&
+        S.Context.hasSameUnqualifiedType(ToType1, ToType2)) {
+      if (S.IsDerivedFrom(FromType2, FromType1))
         return ImplicitConversionSequence::Better;
-      else if (IsDerivedFrom(FromType1, FromType2))
+      else if (S.IsDerivedFrom(FromType1, FromType2))
         return ImplicitConversionSequence::Worse;
     }
   }
@@ -2570,7 +2642,8 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
 Sema::ReferenceCompareResult
 Sema::CompareReferenceRelationship(SourceLocation Loc,
                                    QualType OrigT1, QualType OrigT2,
-                                   bool& DerivedToBase) {
+                                   bool &DerivedToBase,
+                                   bool &ObjCConversion) {
   assert(!OrigT1->isReferenceType() &&
     "T1 must be the pointee type of the reference type");
   assert(!OrigT2->isReferenceType() && "T2 cannot be a reference type");
@@ -2585,11 +2658,17 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
   //   Given types "cv1 T1" and "cv2 T2," "cv1 T1" is
   //   reference-related to "cv2 T2" if T1 is the same type as T2, or
   //   T1 is a base class of T2.
-  if (UnqualT1 == UnqualT2)
-    DerivedToBase = false;
-  else if (!RequireCompleteType(Loc, OrigT2, PDiag()) &&
+  DerivedToBase = false;
+  ObjCConversion = false;
+  if (UnqualT1 == UnqualT2) {
+    // Nothing to do.
+  } else if (!RequireCompleteType(Loc, OrigT2, PDiag()) &&
            IsDerivedFrom(UnqualT2, UnqualT1))
     DerivedToBase = true;
+  else if (UnqualT1->isObjCObjectOrInterfaceType() &&
+           UnqualT2->isObjCObjectOrInterfaceType() &&
+           Context.canBindObjCObjectType(UnqualT1, UnqualT2))
+    ObjCConversion = true;
   else
     return Ref_Incompatible;
 
@@ -2618,16 +2697,21 @@ Sema::CompareReferenceRelationship(SourceLocation Loc,
     return Ref_Related;
 }
 
-/// \brief Look for a user-defined conversion to an lvalue reference-compatible
+/// \brief Look for a user-defined conversion to an value reference-compatible
 ///        with DeclType. Return true if something definite is found.
 static bool
-FindConversionToLValue(Sema &S, ImplicitConversionSequence &ICS,
-                       QualType DeclType, SourceLocation DeclLoc,
-                       Expr *Init, QualType T2, bool AllowExplicit) {
+FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
+                         QualType DeclType, SourceLocation DeclLoc,
+                         Expr *Init, QualType T2, bool AllowRvalues,
+                         bool AllowExplicit) {
   assert(T2->isRecordType() && "Can only find conversions of record types.");
   CXXRecordDecl *T2RecordDecl
     = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl());
 
+  QualType ToType
+    = AllowRvalues? DeclType->getAs<ReferenceType>()->getPointeeType()
+                  : DeclType;
+
   OverloadCandidateSet CandidateSet(DeclLoc);
   const UnresolvedSetImpl *Conversions
     = T2RecordDecl->getVisibleConversionFunctions();
@@ -2646,25 +2730,44 @@ FindConversionToLValue(Sema &S, ImplicitConversionSequence &ICS,
     else
       Conv = cast<CXXConversionDecl>(D);
 
-    // If the conversion function doesn't return a reference type,
-    // it can't be considered for this conversion. An rvalue reference
-    // is only acceptable if its referencee is a function type.
-    const ReferenceType *RefType =
-      Conv->getConversionType()->getAs<ReferenceType>();
-    if (RefType && (RefType->isLValueReferenceType() ||
-                    RefType->getPointeeType()->isFunctionType()) &&
-        (AllowExplicit || !Conv->isExplicit())) {
-      if (ConvTemplate)
-        S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
-                                       Init, DeclType, CandidateSet);
-      else
-        S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
-                               DeclType, CandidateSet);
+    // If this is an explicit conversion, and we're not allowed to consider 
+    // explicit conversions, skip it.
+    if (!AllowExplicit && Conv->isExplicit())
+      continue;
+    
+    if (AllowRvalues) {
+      bool DerivedToBase = false;
+      bool ObjCConversion = false;
+      if (!ConvTemplate &&
+          S.CompareReferenceRelationship(DeclLoc,
+                                         Conv->getConversionType().getNonReferenceType().getUnqualifiedType(),
+                                         DeclType.getNonReferenceType().getUnqualifiedType(),
+                                         DerivedToBase, ObjCConversion)
+            == Sema::Ref_Incompatible)
+        continue;
+    } else {
+      // If the conversion function doesn't return a reference type,
+      // it can't be considered for this conversion. An rvalue reference
+      // is only acceptable if its referencee is a function type.
+
+      const ReferenceType *RefType =
+        Conv->getConversionType()->getAs<ReferenceType>();
+      if (!RefType ||
+          (!RefType->isLValueReferenceType() &&
+           !RefType->getPointeeType()->isFunctionType()))
+        continue;
     }
+    
+    if (ConvTemplate)
+      S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC,
+                                       Init, ToType, CandidateSet);
+    else
+      S.AddConversionCandidate(Conv, I.getPair(), ActingDC, Init,
+                               ToType, CandidateSet);
   }
 
   OverloadCandidateSet::iterator Best;
-  switch (S.BestViableFunction(CandidateSet, DeclLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
   case OR_Success:
     // C++ [over.ics.ref]p1:
     //
@@ -2736,9 +2839,11 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
   // Compute some basic properties of the types and the initializer.
   bool isRValRef = DeclType->isRValueReferenceType();
   bool DerivedToBase = false;
+  bool ObjCConversion = false;
   Expr::Classification InitCategory = Init->Classify(S.Context);
   Sema::ReferenceCompareResult RefRelationship
-    = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
+    = S.CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase,
+                                     ObjCConversion);
 
 
   // C++0x [dcl.init.ref]p5:
@@ -2764,7 +2869,9 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
       //   derived-to-base Conversion (13.3.3.1).
       ICS.setStandard();
       ICS.Standard.First = ICK_Identity;
-      ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
+      ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base
+                         : ObjCConversion? ICK_Compatible_Conversion
+                         : ICK_Identity;
       ICS.Standard.Third = ICK_Identity;
       ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
       ICS.Standard.setToType(0, T2);
@@ -2792,8 +2899,9 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
     if (!SuppressUserConversions && T2->isRecordType() &&
         !S.RequireCompleteType(DeclLoc, T2, 0) && 
         RefRelationship == Sema::Ref_Incompatible) {
-      if (FindConversionToLValue(S, ICS, DeclType, DeclLoc,
-                                 Init, T2, AllowExplicit))
+      if (FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+                                   Init, T2, /*AllowRvalues=*/false,
+                                   AllowExplicit))
         return ICS;
     }
   }
@@ -2845,26 +2953,37 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
   //          that is the result of the conversion in the second case
   //          (or, in either case, to the appropriate base class
   //          subobject of the object).
-  //
-  // We're only checking the first case here, which is a direct
-  // binding in C++0x but not in C++03.
-  if (InitCategory.isRValue() && T2->isRecordType() &&
-      RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
-    ICS.setStandard();
-    ICS.Standard.First = ICK_Identity;
-    ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
-    ICS.Standard.Third = ICK_Identity;
-    ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
-    ICS.Standard.setToType(0, T2);
-    ICS.Standard.setToType(1, T1);
-    ICS.Standard.setToType(2, T1);
-    ICS.Standard.ReferenceBinding = true;
-    ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
-    ICS.Standard.RRefBinding = isRValRef;
-    ICS.Standard.CopyConstructor = 0;
-    return ICS;
+  if (T2->isRecordType()) {
+    // First case: "cv1 T1" is reference-compatible with "cv2 T2". This is a
+    // direct binding in C++0x but not in C++03.
+    if (InitCategory.isRValue() && 
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+      ICS.setStandard();
+      ICS.Standard.First = ICK_Identity;
+      ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base 
+                          : ObjCConversion? ICK_Compatible_Conversion
+                          : ICK_Identity;
+      ICS.Standard.Third = ICK_Identity;
+      ICS.Standard.FromTypePtr = T2.getAsOpaquePtr();
+      ICS.Standard.setToType(0, T2);
+      ICS.Standard.setToType(1, T1);
+      ICS.Standard.setToType(2, T1);
+      ICS.Standard.ReferenceBinding = true;
+      ICS.Standard.DirectBinding = S.getLangOptions().CPlusPlus0x;
+      ICS.Standard.RRefBinding = isRValRef;
+      ICS.Standard.CopyConstructor = 0;
+      return ICS;
+    }
+    
+    // Second case: not reference-related.
+    if (RefRelationship == Sema::Ref_Incompatible &&
+        !S.RequireCompleteType(DeclLoc, T2, 0) && 
+        FindConversionForRefInit(S, ICS, DeclType, DeclLoc,
+                                 Init, T2, /*AllowRvalues=*/true,
+                                 AllowExplicit))
+      return ICS;
   }
-
+  
   //       -- Otherwise, a temporary of type "cv1 T1" is created and
   //          initialized from the initializer expression using the
   //          rules for a non-reference copy initialization (8.5). The
@@ -2899,9 +3018,9 @@ TryReferenceInit(Sema &S, Expr *&Init, QualType DeclType,
   //   the argument expression. Any difference in top-level
   //   cv-qualification is subsumed by the initialization itself
   //   and does not constitute a conversion.
-  ICS = S.TryImplicitConversion(Init, T1, SuppressUserConversions,
-                                /*AllowExplicit=*/false,
-                                /*InOverloadResolution=*/false);
+  ICS = TryImplicitConversion(S, Init, T1, SuppressUserConversions,
+                              /*AllowExplicit=*/false,
+                              /*InOverloadResolution=*/false);
 
   // Of course, that's still a reference binding.
   if (ICS.isStandard()) {
@@ -2930,25 +3049,25 @@ TryCopyInitialization(Sema &S, Expr *From, QualType ToType,
                             SuppressUserConversions,
                             /*AllowExplicit=*/false);
 
-  return S.TryImplicitConversion(From, ToType,
-                                 SuppressUserConversions,
-                                 /*AllowExplicit=*/false,
-                                 InOverloadResolution);
+  return TryImplicitConversion(S, From, ToType,
+                               SuppressUserConversions,
+                               /*AllowExplicit=*/false,
+                               InOverloadResolution);
 }
 
 /// TryObjectArgumentInitialization - Try to initialize the object
 /// parameter of the given member function (@c Method) from the
 /// expression @p From.
-ImplicitConversionSequence
-Sema::TryObjectArgumentInitialization(QualType OrigFromType,
-                                      CXXMethodDecl *Method,
-                                      CXXRecordDecl *ActingContext) {
-  QualType ClassType = Context.getTypeDeclType(ActingContext);
+static ImplicitConversionSequence
+TryObjectArgumentInitialization(Sema &S, QualType OrigFromType,
+                                CXXMethodDecl *Method,
+                                CXXRecordDecl *ActingContext) {
+  QualType ClassType = S.Context.getTypeDeclType(ActingContext);
   // [class.dtor]p2: A destructor can be invoked for a const, volatile or
   //                 const volatile object.
   unsigned Quals = isa<CXXDestructorDecl>(Method) ?
     Qualifiers::Const | Qualifiers::Volatile : Method->getTypeQualifiers();
-  QualType ImplicitParamType =  Context.getCVRQualifiedType(ClassType, Quals);
+  QualType ImplicitParamType =  S.Context.getCVRQualifiedType(ClassType, Quals);
 
   // Set up the conversion sequence as a "bad" conversion, to allow us
   // to exit early.
@@ -2972,7 +3091,7 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
 
   // First check the qualifiers. We don't care about lvalue-vs-rvalue
   // with the implicit object parameter (C++ [over.match.funcs]p5).
-  QualType FromTypeCanon = Context.getCanonicalType(FromType);
+  QualType FromTypeCanon = S.Context.getCanonicalType(FromType);
   if (ImplicitParamType.getCVRQualifiers() 
                                     != FromTypeCanon.getLocalCVRQualifiers() &&
       !ImplicitParamType.isAtLeastAsQualifiedAs(FromTypeCanon)) {
@@ -2983,11 +3102,11 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
 
   // Check that we have either the same type or a derived type. It
   // affects the conversion rank.
-  QualType ClassTypeCanon = Context.getCanonicalType(ClassType);
+  QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType);
   ImplicitConversionKind SecondKind;
   if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) {
     SecondKind = ICK_Identity;
-  } else if (IsDerivedFrom(FromType, ClassType))
+  } else if (S.IsDerivedFrom(FromType, ClassType))
     SecondKind = ICK_Derived_To_Base;
   else {
     ICS.setBad(BadConversionSequence::unrelated_class,
@@ -3030,7 +3149,7 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
   // Note that we always use the true parent context when performing
   // the actual argument initialization.
   ImplicitConversionSequence ICS
-    = TryObjectArgumentInitialization(From->getType(), Method,
+    = TryObjectArgumentInitialization(*this, From->getType(), Method,
                                       Method->getParent());
   if (ICS.isBad())
     return Diag(From->getSourceRange().getBegin(),
@@ -3041,16 +3160,17 @@ Sema::PerformObjectArgumentInitialization(Expr *&From,
     return PerformObjectMemberConversion(From, Qualifier, FoundDecl, Method);
 
   if (!Context.hasSameType(From->getType(), DestType))
-    ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
-                      /*isLvalue=*/!From->getType()->isPointerType());
+    ImpCastExprToType(From, DestType, CK_NoOp,
+                      From->getType()->isPointerType() ? VK_RValue : VK_LValue);
   return false;
 }
 
 /// TryContextuallyConvertToBool - Attempt to contextually convert the
 /// expression From to bool (C++0x [conv]p3).
-ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
+static ImplicitConversionSequence
+TryContextuallyConvertToBool(Sema &S, Expr *From) {
   // FIXME: This is pretty broken.
-  return TryImplicitConversion(From, Context.BoolTy,
+  return TryImplicitConversion(S, From, S.Context.BoolTy,
                                // FIXME: Are these flags correct?
                                /*SuppressUserConversions=*/false,
                                /*AllowExplicit=*/true,
@@ -3060,7 +3180,7 @@ ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
 /// PerformContextuallyConvertToBool - Perform a contextual conversion
 /// of the expression From to bool (C++0x [conv]p3).
 bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
-  ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From);
+  ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
   if (!ICS.isBad())
     return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
   
@@ -3073,20 +3193,21 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
   
 /// TryContextuallyConvertToObjCId - Attempt to contextually convert the
 /// expression From to 'id'.
-ImplicitConversionSequence Sema::TryContextuallyConvertToObjCId(Expr *From) {
-  QualType Ty = Context.getObjCIdType();
-  return TryImplicitConversion(From, Ty,
-                                 // FIXME: Are these flags correct?
-                                 /*SuppressUserConversions=*/false,
-                                 /*AllowExplicit=*/true,
-                                 /*InOverloadResolution=*/false);
+static ImplicitConversionSequence
+TryContextuallyConvertToObjCId(Sema &S, Expr *From) {
+  QualType Ty = S.Context.getObjCIdType();
+  return TryImplicitConversion(S, From, Ty,
+                               // FIXME: Are these flags correct?
+                               /*SuppressUserConversions=*/false,
+                               /*AllowExplicit=*/true,
+                               /*InOverloadResolution=*/false);
 }
-  
+
 /// PerformContextuallyConvertToObjCId - Perform a contextual conversion
 /// of the expression From to 'id'.
 bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
   QualType Ty = Context.getObjCIdType();
-  ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(From);
+  ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(*this, From);
   if (!ICS.isBad())
     return PerformImplicitConversion(From, Ty, ICS, AA_Converting);
   return true;
@@ -3128,8 +3249,8 @@ bool Sema::PerformContextuallyConvertToObjCId(Expr *&From) {
 ///
 /// \returns The expression, converted to an integral or enumeration type if
 /// successful.
-Sema::OwningExprResult 
-Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
+ExprResult 
+Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
                                          const PartialDiagnostic &NotIntDiag,
                                        const PartialDiagnostic &IncompleteDiag,
                                      const PartialDiagnostic &ExplicitConvDiag,
@@ -3137,16 +3258,14 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
                                          const PartialDiagnostic &AmbigDiag,
                                          const PartialDiagnostic &AmbigNote,
                                          const PartialDiagnostic &ConvDiag) {
-  Expr *From = static_cast<Expr *>(FromE.get());
-  
   // We can't perform any more checking for type-dependent expressions.
   if (From->isTypeDependent())
-    return move(FromE);
+    return Owned(From);
   
   // If the expression already has integral or enumeration type, we're golden.
   QualType T = From->getType();
   if (T->isIntegralOrEnumerationType())
-    return move(FromE);
+    return Owned(From);
 
   // FIXME: Check for missing '()' if T is a function type?
 
@@ -3156,12 +3275,12 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
   if (!RecordTy || !getLangOptions().CPlusPlus) {
     Diag(Loc, NotIntDiag)
       << T << From->getSourceRange();
-    return move(FromE);
+    return Owned(From);
   }
     
   // We must have a complete class type.
   if (RequireCompleteType(Loc, T, IncompleteDiag))
-    return move(FromE);
+    return Owned(From);
   
   // Look for a conversion to an integral or enumeration type.
   UnresolvedSet<4> ViableConversions;
@@ -3213,8 +3332,7 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
         return ExprError();
       
       CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
-      From = BuildCXXMemberCallExpr(FromE.takeAs<Expr>(), Found, Conversion);
-      FromE = Owned(From);
+      From = BuildCXXMemberCallExpr(From, Found, Conversion);
     }
     
     // We'll complain below about a non-integral condition type.
@@ -3237,9 +3355,8 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
         << T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
     }
     
-    From = BuildCXXMemberCallExpr(FromE.takeAs<Expr>(), Found,
+    From = BuildCXXMemberCallExpr(From, Found,
                           cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
-    FromE = Owned(From);
     break;
   }
     
@@ -3253,14 +3370,14 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, ExprArg FromE,
       Diag(Conv->getLocation(), AmbigNote)
         << ConvTy->isEnumeralType() << ConvTy;
     }
-    return move(FromE);
+    return Owned(From);
   }
   
   if (!From->getType()->isIntegralOrEnumerationType())
     Diag(Loc, NotIntDiag)
       << From->getType() << From->getSourceRange();
 
-  return move(FromE);
+  return Owned(From);
 }
 
 /// AddOverloadCandidate - Adds the given function to the set of
@@ -3306,7 +3423,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Function)){
     // C++ [class.copy]p3:
@@ -3469,7 +3586,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
   CandidateSet.push_back(OverloadCandidate());
@@ -3513,7 +3630,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
     // Determine the implicit conversion sequence for the object
     // parameter.
     Candidate.Conversions[0]
-      = TryObjectArgumentInitialization(ObjectType, Method, ActingContext);
+      = TryObjectArgumentInitialization(*this, ObjectType, Method,
+                                        ActingContext);
     if (Candidate.Conversions[0].isBad()) {
       Candidate.Viable = false;
       Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -3666,7 +3784,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
   CandidateSet.push_back(OverloadCandidate());
@@ -3678,25 +3796,32 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
   Candidate.FinalConversion.setAsIdentityConversion();
   Candidate.FinalConversion.setFromType(ConvType);
   Candidate.FinalConversion.setAllToTypes(ToType);
+  Candidate.Viable = true;
+  Candidate.Conversions.resize(1);
 
+  // C++ [over.match.funcs]p4:
+  //   For conversion functions, the function is considered to be a member of 
+  //   the class of the implicit implied object argument for the purpose of 
+  //   defining the type of the implicit object parameter.
+  //
   // Determine the implicit conversion sequence for the implicit
   // object parameter.
-  Candidate.Viable = true;
-  Candidate.Conversions.resize(1);
+  QualType ImplicitParamType = From->getType();
+  if (const PointerType *FromPtrType = ImplicitParamType->getAs<PointerType>())
+    ImplicitParamType = FromPtrType->getPointeeType();
+  CXXRecordDecl *ConversionContext
+    = cast<CXXRecordDecl>(ImplicitParamType->getAs<RecordType>()->getDecl());
+  
   Candidate.Conversions[0]
-    = TryObjectArgumentInitialization(From->getType(), Conversion,
-                                      ActingContext);
-  // Conversion functions to a different type in the base class is visible in 
-  // the derived class.  So, a derived to base conversion should not participate
-  // in overload resolution. 
-  if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base)
-    Candidate.Conversions[0].Standard.Second = ICK_Identity;
+    = TryObjectArgumentInitialization(*this, From->getType(), Conversion,
+                                      ConversionContext);
+  
   if (Candidate.Conversions[0].isBad()) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_bad_conversion;
     return;
   }
-  
+
   // We won't go through a user-define type conversion function to convert a 
   // derived to base as such conversions are given Conversion Rank. They only
   // go through a copy constructor. 13.3.3.1.2-p4 [over.ics.user]
@@ -3719,9 +3844,10 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
   // well-formed.
   DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
                             From->getLocStart());
-  ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
-                                CastExpr::CK_FunctionToPointerDecay,
-                                &ConversionRef, CXXBaseSpecifierArray(), false);
+  ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack,
+                                Context.getPointerType(Conversion->getType()),
+                                CK_FunctionToPointerDecay,
+                                &ConversionRef, VK_RValue);
 
   // Note that it is safe to allocate CallExpr on the stack here because
   // there are 0 arguments (i.e., nothing is allocated using ASTContext's
@@ -3819,7 +3945,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
     return;
 
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   CandidateSet.push_back(OverloadCandidate());
   OverloadCandidate& Candidate = CandidateSet.back();
@@ -3834,7 +3960,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
   // Determine the implicit conversion sequence for the implicit
   // object parameter.
   ImplicitConversionSequence ObjectInit
-    = TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext);
+    = TryObjectArgumentInitialization(*this, ObjectType, Conversion,
+                                      ActingContext);
   if (ObjectInit.isBad()) {
     Candidate.Viable = false;
     Candidate.FailureKind = ovl_fail_bad_conversion;
@@ -3925,9 +4052,6 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
   //   candidates, non-member candidates and built-in candidates, are
   //   constructed as follows:
   QualType T1 = Args[0]->getType();
-  QualType T2;
-  if (NumArgs > 1)
-    T2 = Args[1]->getType();
 
   //     -- If T1 is a class type, the set of member candidates is the
   //        result of the qualified lookup of T1::operator@
@@ -3966,7 +4090,7 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
                                bool IsAssignmentOperator,
                                unsigned NumContextualBoolArguments) {
   // Overload resolution is always an unevaluated context.
-  EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
 
   // Add this candidate
   CandidateSet.push_back(OverloadCandidate());
@@ -3999,7 +4123,8 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
     if (ArgIdx < NumContextualBoolArguments) {
       assert(ParamTys[ArgIdx] == Context.BoolTy &&
              "Contextual conversion to bool requires bool type");
-      Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(Args[ArgIdx]);
+      Candidate.Conversions[ArgIdx]
+        = TryContextuallyConvertToBool(*this, Args[ArgIdx]);
     } else {
       Candidate.Conversions[ArgIdx]
         = TryCopyInitialization(*this, Args[ArgIdx], ParamTys[ArgIdx],
@@ -4100,11 +4225,21 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
   // Insert this type.
   if (!PointerTypes.insert(Ty))
     return false;
-
+    
+  QualType PointeeTy;
   const PointerType *PointerTy = Ty->getAs<PointerType>();
-  assert(PointerTy && "type was not a pointer type!");
-
-  QualType PointeeTy = PointerTy->getPointeeType();
+  bool buildObjCPtr = false;
+  if (!PointerTy) {
+    if (const ObjCObjectPointerType *PTy = Ty->getAs<ObjCObjectPointerType>()) {
+      PointeeTy = PTy->getPointeeType();
+      buildObjCPtr = true;
+    }
+    else
+      assert(false && "type was not a pointer type!");
+  }
+  else
+    PointeeTy = PointerTy->getPointeeType();
+  
   // Don't add qualified variants of arrays. For one, they're not allowed
   // (the qualifier would sink to the element type), and for another, the
   // only overload situation where it matters is subscript or pointer +- int,
@@ -4125,7 +4260,10 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
     if ((CVR & Qualifiers::Volatile) && !hasVolatile) continue;
     if ((CVR & Qualifiers::Restrict) && !hasRestrict) continue;
     QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
-    PointerTypes.insert(Context.getPointerType(QPointeeTy));
+    if (!buildObjCPtr)
+      PointerTypes.insert(Context.getPointerType(QPointeeTy));
+    else
+      PointerTypes.insert(Context.getObjCObjectPointerType(QPointeeTy));
   }
 
   return true;
@@ -4200,10 +4338,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
   // If we're dealing with an array type, decay to the pointer.
   if (Ty->isArrayType())
     Ty = SemaRef.Context.getArrayDecayedType(Ty);
-
-  if (const PointerType *PointerTy = Ty->getAs<PointerType>()) {
-    QualType PointeeTy = PointerTy->getPointeeType();
-
+  if (Ty->isObjCIdType() || Ty->isObjCClassType())
+    PointerTypes.insert(Ty);
+  else if (Ty->getAs<PointerType>() || Ty->getAs<ObjCObjectPointerType>()) {
     // Insert our type, and its more-qualified variants, into the set
     // of types.
     if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals))
@@ -4479,7 +4616,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
     for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
          Ptr != CandidateTypes.pointer_end(); ++Ptr) {
       // Skip pointer types that aren't pointers to object types.
-      if (!(*Ptr)->getAs<PointerType>()->getPointeeType()->isObjectType())
+      if (!(*Ptr)->getPointeeType()->isIncompleteOrObjectType())
         continue;
 
       QualType ParamTypes[2] = {
@@ -4519,7 +4656,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
     for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
          Ptr != CandidateTypes.pointer_end(); ++Ptr) {
       QualType ParamTy = *Ptr;
-      QualType PointeeTy = ParamTy->getAs<PointerType>()->getPointeeType();
+      QualType PointeeTy = ParamTy->getPointeeType();
       AddBuiltinCandidate(Context.getLValueReferenceType(PointeeTy),
                           &ParamTy, Args, 1, CandidateSet);
     }
@@ -5000,7 +5137,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
     for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
          Ptr != CandidateTypes.pointer_end(); ++Ptr) {
       QualType ParamTypes[2] = { *Ptr, Context.getPointerDiffType() };
-      QualType PointeeType = (*Ptr)->getAs<PointerType>()->getPointeeType();
+      QualType PointeeType = (*Ptr)->getPointeeType();
       QualType ResultTy = Context.getLValueReferenceType(PointeeType);
 
       // T& operator[](T*, ptrdiff_t)
@@ -5028,18 +5165,16 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
         QualType C1Ty = (*Ptr);
         QualType C1;
         QualifierCollector Q1;
-        if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) {
-          C1 = QualType(Q1.strip(PointerTy->getPointeeType()), 0);
-          if (!isa<RecordType>(C1))
-            continue;
-          // heuristic to reduce number of builtin candidates in the set.
-          // Add volatile/restrict version only if there are conversions to a
-          // volatile/restrict type.
-          if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile())
-            continue;
-          if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict())
-            continue;
-        }
+        C1 = QualType(Q1.strip(C1Ty->getPointeeType()), 0);
+        if (!isa<RecordType>(C1))
+          continue;
+        // heuristic to reduce number of builtin candidates in the set.
+        // Add volatile/restrict version only if there are conversions to a
+        // volatile/restrict type.
+        if (!VisibleTypeConversionsQuals.hasVolatile() && Q1.hasVolatile())
+          continue;
+        if (!VisibleTypeConversionsQuals.hasRestrict() && Q1.hasRestrict())
+          continue;
         for (BuiltinCandidateTypeSet::iterator
              MemPtr = CandidateTypes.member_pointer_begin(),
              MemPtrEnd = CandidateTypes.member_pointer_end();
@@ -5148,9 +5283,10 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
 /// isBetterOverloadCandidate - Determines whether the first overload
 /// candidate is a better candidate than the second (C++ 13.3.3p1).
 bool
-Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
-                                const OverloadCandidate& Cand2,
-                                SourceLocation Loc) {
+isBetterOverloadCandidate(Sema &S,
+                          const OverloadCandidate& Cand1,
+                          const OverloadCandidate& Cand2,
+                          SourceLocation Loc) {
   // Define viable functions to be better candidates than non-viable
   // functions.
   if (!Cand2.Viable)
@@ -5176,7 +5312,8 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
   assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
   bool HasBetterConversion = false;
   for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) {
-    switch (CompareImplicitConversionSequences(Cand1.Conversions[ArgIdx],
+    switch (CompareImplicitConversionSequences(S,
+                                               Cand1.Conversions[ArgIdx],
                                                Cand2.Conversions[ArgIdx])) {
     case ImplicitConversionSequence::Better:
       // Cand1 has a better conversion sequence.
@@ -5211,9 +5348,9 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
   if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
       Cand2.Function && Cand2.Function->getPrimaryTemplate())
     if (FunctionTemplateDecl *BetterTemplate
-          = getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
-                                       Cand2.Function->getPrimaryTemplate(),
-                                       Loc,
+          = S.getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+                                         Cand2.Function->getPrimaryTemplate(),
+                                         Loc,
                        isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion 
                                                              : TPOC_Call))
       return BetterTemplate == Cand1.Function->getPrimaryTemplate();
@@ -5227,7 +5364,8 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
   if (Cand1.Function && Cand2.Function &&
       isa<CXXConversionDecl>(Cand1.Function) &&
       isa<CXXConversionDecl>(Cand2.Function)) {
-    switch (CompareStandardConversionSequences(Cand1.FinalConversion,
+    switch (CompareStandardConversionSequences(S,
+                                               Cand1.FinalConversion,
                                                Cand2.FinalConversion)) {
     case ImplicitConversionSequence::Better:
       // Cand1 has a better conversion sequence.
@@ -5258,32 +5396,28 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
 /// function, Best points to the candidate function found.
 ///
 /// \returns The result of overload resolution.
-OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
-                                           SourceLocation Loc,
-                                        OverloadCandidateSet::iterator& Best) {
+OverloadingResult
+OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
+                                         iterator& Best) {
   // Find the best viable function.
-  Best = CandidateSet.end();
-  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
-       Cand != CandidateSet.end(); ++Cand) {
-    if (Cand->Viable) {
-      if (Best == CandidateSet.end() ||
-          isBetterOverloadCandidate(*Cand, *Best, Loc))
+  Best = end();
+  for (iterator Cand = begin(); Cand != end(); ++Cand) {
+    if (Cand->Viable)
+      if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc))
         Best = Cand;
-    }
   }
 
   // If we didn't find any viable functions, abort.
-  if (Best == CandidateSet.end())
+  if (Best == end())
     return OR_No_Viable_Function;
 
   // Make sure that this function is better than every other viable
   // function. If not, we have an ambiguity.
-  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
-       Cand != CandidateSet.end(); ++Cand) {
+  for (iterator Cand = begin(); Cand != end(); ++Cand) {
     if (Cand->Viable &&
         Cand != Best &&
-        !isBetterOverloadCandidate(*Best, *Cand, Loc)) {
-      Best = CandidateSet.end();
+        !isBetterOverloadCandidate(S, *Best, *Cand, Loc)) {
+      Best = end();
       return OR_Ambiguous;
     }
   }
@@ -5301,7 +5435,7 @@ OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
   //   (clause 13), user-defined conversions (12.3.2), allocation function for
   //   placement new (5.3.4), as well as non-default initialization (8.5).
   if (Best->Function)
-    MarkDeclarationReferenced(Loc, Best->Function);
+    S.MarkDeclarationReferenced(Loc, Best->Function);
   return OR_Success;
 }
 
@@ -5365,14 +5499,15 @@ void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
 /// Diagnoses an ambiguous conversion.  The partial diagnostic is the
 /// "lead" diagnostic; it will be given two arguments, the source and
 /// target types of the conversion.
-void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
-                                       SourceLocation CaretLoc,
-                                       const PartialDiagnostic &PDiag) {
-  Diag(CaretLoc, PDiag)
-    << ICS.Ambiguous.getFromType() << ICS.Ambiguous.getToType();
+void ImplicitConversionSequence::DiagnoseAmbiguousConversion(
+                                 Sema &S,
+                                 SourceLocation CaretLoc,
+                                 const PartialDiagnostic &PDiag) const {
+  S.Diag(CaretLoc, PDiag)
+    << Ambiguous.getFromType() << Ambiguous.getToType();
   for (AmbiguousConversionSequence::const_iterator
-         I = ICS.Ambiguous.begin(), E = ICS.Ambiguous.end(); I != E; ++I) {
-    NoteOverloadCandidate(*I);
+         I = Ambiguous.begin(), E = Ambiguous.end(); I != E; ++I) {
+    S.NoteOverloadCandidate(*I);
   }
 }
 
@@ -5589,8 +5724,31 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
     return;
   }
 
-  case Sema::TDK_Inconsistent:
-  case Sema::TDK_InconsistentQuals: {
+  case Sema::TDK_Underqualified: {
+    assert(ParamD && "no parameter found for bad qualifiers deduction result");
+    TemplateTypeParmDecl *TParam = cast<TemplateTypeParmDecl>(ParamD);
+
+    QualType Param = Cand->DeductionFailure.getFirstArg()->getAsType();
+
+    // Param will have been canonicalized, but it should just be a
+    // qualified version of ParamD, so move the qualifiers to that.
+    QualifierCollector Qs(S.Context);
+    Qs.strip(Param);
+    QualType NonCanonParam = Qs.apply(TParam->getTypeForDecl());
+    assert(S.Context.hasSameType(Param, NonCanonParam));
+
+    // Arg has also been canonicalized, but there's nothing we can do
+    // about that.  It also doesn't matter as much, because it won't
+    // have any template parameters in it (because deduction isn't
+    // done on dependent types).
+    QualType Arg = Cand->DeductionFailure.getSecondArg()->getAsType();
+
+    S.Diag(Fn->getLocation(), diag::note_ovl_candidate_underqualified)
+      << ParamD->getDeclName() << Arg << NonCanonParam;
+    return;
+  }
+
+  case Sema::TDK_Inconsistent: {
     assert(ParamD && "no parameter found for inconsistent deduction result");    
     int which = 0;
     if (isa<TemplateTypeParmDecl>(ParamD))
@@ -5779,7 +5937,7 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
     if (ICS.isBad()) break; // all meaningless after first invalid
     if (!ICS.isAmbiguous()) continue;
 
-    S.DiagnoseAmbiguousConversion(ICS, OpLoc,
+    ICS.DiagnoseAmbiguousConversion(S, OpLoc,
                               S.PDiag(diag::note_ambiguous_type_conversion));
   }
 }
@@ -5808,8 +5966,8 @@ struct CompareOverloadCandidatesForDisplay {
       // TODO: introduce a tri-valued comparison for overload
       // candidates.  Would be more worthwhile if we had a sort
       // that could exploit it.
-      if (S.isBetterOverloadCandidate(*L, *R, SourceLocation())) return true;
-      if (S.isBetterOverloadCandidate(*R, *L, SourceLocation())) return false;
+      if (isBetterOverloadCandidate(S, *L, *R, SourceLocation())) return true;
+      if (isBetterOverloadCandidate(S, *R, *L, SourceLocation())) return false;
     } else if (R->Viable)
       return false;
 
@@ -5838,8 +5996,9 @@ struct CompareOverloadCandidatesForDisplay {
         int leftBetter = 0;
         unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument);
         for (unsigned E = L->Conversions.size(); I != E; ++I) {
-          switch (S.CompareImplicitConversionSequences(L->Conversions[I],
-                                                       R->Conversions[I])) {
+          switch (CompareImplicitConversionSequences(S,
+                                                     L->Conversions[I],
+                                                     R->Conversions[I])) {
           case ImplicitConversionSequence::Better:
             leftBetter++;
             break;
@@ -5947,23 +6106,20 @@ void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
 /// PrintOverloadCandidates - When overload resolution fails, prints
 /// diagnostic messages containing the candidates in the candidate
 /// set.
-void
-Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
-                              OverloadCandidateDisplayKind OCD,
-                              Expr **Args, unsigned NumArgs,
-                              const char *Opc,
-                              SourceLocation OpLoc) {
+void OverloadCandidateSet::NoteCandidates(Sema &S,
+                                          OverloadCandidateDisplayKind OCD,
+                                          Expr **Args, unsigned NumArgs,
+                                          const char *Opc,
+                                          SourceLocation OpLoc) {
   // Sort the candidates by viability and position.  Sorting directly would
   // be prohibitive, so we make a set of pointers and sort those.
   llvm::SmallVector<OverloadCandidate*, 32> Cands;
-  if (OCD == OCD_AllCandidates) Cands.reserve(CandidateSet.size());
-  for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
-                                  LastCand = CandidateSet.end();
-       Cand != LastCand; ++Cand) {
+  if (OCD == OCD_AllCandidates) Cands.reserve(size());
+  for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) {
     if (Cand->Viable)
       Cands.push_back(Cand);
     else if (OCD == OCD_AllCandidates) {
-      CompleteNonViableCandidate(*this, Cand, Args, NumArgs);
+      CompleteNonViableCandidate(S, Cand, Args, NumArgs);
       if (Cand->Function || Cand->IsSurrogate)
         Cands.push_back(Cand);
       // Otherwise, this a non-viable builtin candidate.  We do not, in general,
@@ -5972,12 +6128,12 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
   }
 
   std::sort(Cands.begin(), Cands.end(),
-            CompareOverloadCandidatesForDisplay(*this));
+            CompareOverloadCandidatesForDisplay(S));
   
   bool ReportedAmbiguousConversions = false;
 
   llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
-  const Diagnostic::OverloadsShown ShowOverloads = Diags.getShowOverloads();
+  const Diagnostic::OverloadsShown ShowOverloads = S.Diags.getShowOverloads();
   unsigned CandsShown = 0;
   for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
     OverloadCandidate *Cand = *I;
@@ -5991,9 +6147,9 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
     ++CandsShown;
 
     if (Cand->Function)
-      NoteFunctionCandidate(*this, Cand, Args, NumArgs);
+      NoteFunctionCandidate(S, Cand, Args, NumArgs);
     else if (Cand->IsSurrogate)
-      NoteSurrogateCandidate(*this, Cand);
+      NoteSurrogateCandidate(S, Cand);
     else {
       assert(Cand->Viable &&
              "Non-viable built-in candidates are not added to Cands.");
@@ -6004,17 +6160,17 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
       // FIXME: It's quite possible for different conversions to see
       // different ambiguities, though.
       if (!ReportedAmbiguousConversions) {
-        NoteAmbiguousUserConversions(*this, OpLoc, Cand);
+        NoteAmbiguousUserConversions(S, OpLoc, Cand);
         ReportedAmbiguousConversions = true;
       }
 
       // If this is a viable builtin, print it.
-      NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand);
+      NoteBuiltinOperatorCandidate(S, Opc, OpLoc, Cand);
     }
   }
 
   if (I != E)
-    Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I);
+    S.Diag(OpLoc, diag::note_ovl_too_many_candidates) << int(E - I);
 }
 
 static bool CheckUnresolvedAccess(Sema &S, OverloadExpr *E, DeclAccessPair D) {
@@ -6061,12 +6217,13 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
   // C++ [over.over]p1:
   //   [...] The overloaded function name can be preceded by the &
   //   operator.
-  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
-  TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
-  if (OvlExpr->hasExplicitTemplateArgs()) {
-    OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
-    ExplicitTemplateArgs = &ETABuffer;
-  }
+  // However, remember whether the expression has member-pointer form:
+  // C++ [expr.unary.op]p4:
+  //     A pointer to member is only formed when an explicit & is used
+  //     and its operand is a qualified-id not enclosed in
+  //     parentheses.
+  OverloadExpr::FindResult Ovl = OverloadExpr::find(From);
+  OverloadExpr *OvlExpr = Ovl.Expression;
   
   // We expect a pointer or reference to function, or a function pointer.
   FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
@@ -6078,6 +6235,25 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
     return 0;
   }
 
+  // If the overload expression doesn't have the form of a pointer to
+  // member, don't try to convert it to a pointer-to-member type.
+  if (IsMember && !Ovl.HasFormOfMemberPointer) {
+    if (!Complain) return 0;
+
+    // TODO: Should we condition this on whether any functions might
+    // have matched, or is it more appropriate to do that in callers?
+    // TODO: a fixit wouldn't hurt.
+    Diag(OvlExpr->getNameLoc(), diag::err_addr_ovl_no_qualifier)
+      << ToType << OvlExpr->getSourceRange();
+    return 0;
+  }
+
+  TemplateArgumentListInfo ETABuffer, *ExplicitTemplateArgs = 0;
+  if (OvlExpr->hasExplicitTemplateArgs()) {
+    OvlExpr->getExplicitTemplateArgs().copyInto(ETABuffer);
+    ExplicitTemplateArgs = &ETABuffer;
+  }
+
   assert(From->getType() == Context.OverloadTy);
 
   // Look through all of the overloaded functions, searching for one
@@ -6267,7 +6443,7 @@ FunctionDecl *Sema::ResolveSingleFunctionTemplateSpecialization(Expr *From) {
   if (From->getType() != Context.OverloadTy)
     return 0;
 
-  OverloadExpr *OvlExpr = OverloadExpr::find(From).getPointer();
+  OverloadExpr *OvlExpr = OverloadExpr::find(From).Expression;
   
   // If we didn't actually find any template-ids, we're done.
   if (!OvlExpr->hasExplicitTemplateArgs())
@@ -6405,18 +6581,10 @@ void Sema::AddOverloadedCallCandidates(UnresolvedLookupExpr *ULE,
                                          PartialOverloading);  
 }
 
-static Sema::OwningExprResult Destroy(Sema &SemaRef, Expr *Fn,
-                                      Expr **Args, unsigned NumArgs) {
-  Fn->Destroy(SemaRef.Context);
-  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
-    Args[Arg]->Destroy(SemaRef.Context);
-  return SemaRef.ExprError();
-}
-
 /// Attempts to recover from a call where no functions were found.
 ///
 /// Returns true if new candidates were found.
-static Sema::OwningExprResult
+static ExprResult
 BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
                       UnresolvedLookupExpr *ULE,
                       SourceLocation LParenLoc,
@@ -6440,13 +6608,13 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
   LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
                  Sema::LookupOrdinaryName);
   if (SemaRef.DiagnoseEmptyLookup(S, SS, R, Sema::CTC_Expression))
-    return Destroy(SemaRef, Fn, Args, NumArgs);
+    return ExprError();
 
   assert(!R.empty() && "lookup results empty despite recovery");
 
   // Build an implicit member call if appropriate.  Just drop the
   // casts and such from the call, we don't really care.
-  Sema::OwningExprResult NewFn = SemaRef.ExprError();
+  ExprResult NewFn = ExprError();
   if ((*R.begin())->isCXXClassMember())
     NewFn = SemaRef.BuildPossibleImplicitMemberExpr(SS, R, ExplicitTemplateArgs);
   else if (ExplicitTemplateArgs)
@@ -6455,15 +6623,13 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
     NewFn = SemaRef.BuildDeclarationNameExpr(SS, R, false);
 
   if (NewFn.isInvalid())
-    return Destroy(SemaRef, Fn, Args, NumArgs);
-
-  Fn->Destroy(SemaRef.Context);
+    return ExprError();
 
   // This shouldn't cause an infinite loop because we're giving it
   // an expression with non-empty lookup results, which should never
   // end up here.
-  return SemaRef.ActOnCallExpr(/*Scope*/ 0, move(NewFn), LParenLoc,
-                         Sema::MultiExprArg(SemaRef, (void**) Args, NumArgs),
+  return SemaRef.ActOnCallExpr(/*Scope*/ 0, NewFn.take(), LParenLoc,
+                               MultiExprArg(Args, NumArgs),
                                CommaLocs, RParenLoc);
 }
 
@@ -6474,7 +6640,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
 /// the function declaration produced by overload
 /// resolution. Otherwise, emits diagnostics, deletes all of the
 /// arguments and Fn, and returns NULL.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
                               SourceLocation LParenLoc,
                               Expr **Args, unsigned NumArgs,
@@ -6512,7 +6678,7 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
                                  CommaLocs, RParenLoc);
 
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
+  switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
   case OR_Success: {
     FunctionDecl *FDecl = Best->Function;
     CheckUnresolvedLookupAccess(ULE, Best->FoundDecl);
@@ -6525,13 +6691,13 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
     Diag(Fn->getSourceRange().getBegin(),
          diag::err_ovl_no_viable_function_in_call)
       << ULE->getName() << Fn->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     break;
 
   case OR_Ambiguous:
     Diag(Fn->getSourceRange().getBegin(), diag::err_ovl_ambiguous_call)
       << ULE->getName() << Fn->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
     break;
 
   case OR_Deleted:
@@ -6539,15 +6705,11 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
       << Best->Function->isDeleted()
       << ULE->getName()
       << Fn->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     break;
   }
 
-  // Overload resolution failed. Destroy all of the subexpressions and
-  // return NULL.
-  Fn->Destroy(Context);
-  for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
-    Args[Arg]->Destroy(Context);
+  // Overload resolution failed.
   return ExprError();
 }
 
@@ -6572,16 +6734,17 @@ static bool IsOverloaded(const UnresolvedSetImpl &Functions) {
 /// by CreateOverloadedUnaryOp().
 ///
 /// \param input The input argument.
-Sema::OwningExprResult
+ExprResult
 Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
                               const UnresolvedSetImpl &Fns,
-                              ExprArg input) {
+                              Expr *Input) {
   UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
-  Expr *Input = (Expr *)input.get();
 
   OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc);
   assert(Op != OO_None && "Invalid opcode for overloaded unary operator");
   DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
+  // TODO: provide better source location info.
+  DeclarationNameInfo OpNameInfo(OpName, OpLoc);
 
   Expr *Args[2] = { Input, 0 };
   unsigned NumArgs = 1;
@@ -6589,16 +6752,16 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
   // For post-increment and post-decrement, add the implicit '0' as
   // the second argument, so that we know this is a post-increment or
   // post-decrement.
-  if (Opc == UnaryOperator::PostInc || Opc == UnaryOperator::PostDec) {
+  if (Opc == UO_PostInc || Opc == UO_PostDec) {
     llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false);
-    Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
-                                           SourceLocation());
+    Args[1] = IntegerLiteral::Create(Context, Zero, Context.IntTy,
+                                     SourceLocation());
     NumArgs = 2;
   }
 
   if (Input->isTypeDependent()) {
     if (Fns.empty())
-      return Owned(new (Context) UnaryOperator(input.takeAs<Expr>(),
+      return Owned(new (Context) UnaryOperator(Input,
                                                Opc, 
                                                Context.DependentTy,
                                                OpLoc));
@@ -6606,10 +6769,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, OpLoc,
+                                     0, SourceRange(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
-    input.release();
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
                                                    &Args[0], NumArgs,
                                                    Context.DependentTy,
@@ -6636,7 +6798,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
   case OR_Success: {
     // We found a built-in operator or an overloaded operator.
     FunctionDecl *FnDecl = Best->Function;
@@ -6654,16 +6816,14 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
           return ExprError();
       } else {
         // Convert the arguments.
-        OwningExprResult InputInit
+        ExprResult InputInit
           = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(), 
-                                      move(input));
+                                      Input);
         if (InputInit.isInvalid())
           return ExprError();
-        
-        input = move(InputInit);
-        Input = (Expr *)input.get();
+        Input = InputInit.take();
       }
 
       DiagnoseUseOfDecl(Best->FoundDecl, OpLoc);
@@ -6676,17 +6836,16 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
                                                SourceLocation());
       UsualUnaryConversions(FnExpr);
 
-      input.release();
       Args[0] = Input;
-      ExprOwningPtr<CallExpr> TheCall(this,
+      CallExpr *TheCall =
         new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
-                                          Args, NumArgs, ResultTy, OpLoc));
+                                          Args, NumArgs, ResultTy, OpLoc);
 
-      if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
+      if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, 
                               FnDecl))
         return ExprError();
 
-      return MaybeBindToTemporary(TheCall.release());
+      return MaybeBindToTemporary(TheCall);
     } else {
       // We matched a built-in operator. Convert the arguments, then
       // break out so that we will build the appropriate built-in
@@ -6708,8 +6867,9 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << UnaryOperator::getOpcodeStr(Opc)
           << Input->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs,
-                              UnaryOperator::getOpcodeStr(Opc), OpLoc);
+      CandidateSet.NoteCandidates(*this, OCD_ViableCandidates,
+                                  Args, NumArgs,
+                                  UnaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -6717,15 +6877,14 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
         << Best->Function->isDeleted()
         << UnaryOperator::getOpcodeStr(Opc)
         << Input->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
       return ExprError();
     }
 
   // Either we found no viable overloaded operator or we matched a
   // built-in operator. In either case, fall through to trying to
   // build a built-in operation.
-  input.release();
-  return CreateBuiltinUnaryOp(OpLoc, Opc, Owned(Input));
+  return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
 }
 
 /// \brief Create a binary operation that may resolve to an overloaded
@@ -6745,7 +6904,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
 ///
 /// \param LHS Left-hand argument.
 /// \param RHS Right-hand argument.
-Sema::OwningExprResult
+ExprResult
 Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
                             unsigned OpcIn,
                             const UnresolvedSetImpl &Fns,
@@ -6763,7 +6922,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
     if (Fns.empty()) {
       // If there are no functions to store, just build a dependent 
       // BinaryOperator or CompoundAssignment.
-      if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
+      if (Opc <= BO_Assign || Opc > BO_OrAssign)
         return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
                                                   Context.DependentTy, OpLoc));
       
@@ -6776,9 +6935,11 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
 
     // FIXME: save results of ADL from here?
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    // TODO: provide better source location info in DNLoc component.
+    DeclarationNameInfo OpNameInfo(OpName, OpLoc);
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, OpLoc,
+                                     0, SourceRange(), OpNameInfo,
                                      /*ADL*/ true, IsOverloaded(Fns),
                                      Fns.begin(), Fns.end());
     return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
@@ -6789,7 +6950,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
 
   // If this is the .* operator, which is not overloadable, just
   // create a built-in binary operator.
-  if (Opc == BinaryOperator::PtrMemD)
+  if (Opc == BO_PtrMemD)
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // If this is the assignment operator, we only perform overload resolution
@@ -6798,7 +6959,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
   // various built-in candidates, but as DR507 points out, this can lead to
   // problems. So we do it this way, which pretty much follows what GCC does.
   // Note that we go the traditional code path for compound assignment forms.
-  if (Opc==BinaryOperator::Assign && !Args[0]->getType()->isOverloadableType())
+  if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType())
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // Build an empty overload set.
@@ -6821,7 +6982,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
     case OR_Success: {
       // We found a built-in operator or an overloaded operator.
       FunctionDecl *FnDecl = Best->Function;
@@ -6835,7 +6996,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
           // Best->Access is only meaningful for class members.
           CheckMemberOperatorAccess(OpLoc, Args[0], Args[1], Best->FoundDecl);
 
-          OwningExprResult Arg1
+          ExprResult Arg1
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
                                                         FnDecl->getParamDecl(0)),
@@ -6851,7 +7012,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
           Args[1] = RHS = Arg1.takeAs<Expr>();
         } else {
           // Convert the arguments.
-          OwningExprResult Arg0
+          ExprResult Arg0
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
                                                         FnDecl->getParamDecl(0)),
@@ -6860,7 +7021,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
           if (Arg0.isInvalid())
             return ExprError();
 
-          OwningExprResult Arg1
+          ExprResult Arg1
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
                                                         FnDecl->getParamDecl(1)),
@@ -6884,16 +7045,15 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
                                                  OpLoc);
         UsualUnaryConversions(FnExpr);
 
-        ExprOwningPtr<CXXOperatorCallExpr> 
-          TheCall(this, new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
-                                                          Args, 2, ResultTy, 
-                                                          OpLoc));
+        CXXOperatorCallExpr *TheCall =
+          new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+                                            Args, 2, ResultTy, OpLoc);
         
-        if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(), 
+        if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, 
                                 FnDecl))
           return ExprError();
 
-        return MaybeBindToTemporary(TheCall.release());
+        return MaybeBindToTemporary(TheCall);
       } else {
         // We matched a built-in operator. Convert the arguments, then
         // break out so that we will build the appropriate built-in
@@ -6913,15 +7073,15 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
       //   If the operator is the operator , [...] and there are no
       //   viable functions, then the operator is assumed to be the
       //   built-in operator and interpreted according to clause 5.
-      if (Opc == BinaryOperator::Comma)
+      if (Opc == BO_Comma)
         break;
 
       // For class as left operand for assignment or compound assigment operator
       // do not fall through to handling in built-in, but report that no overloaded
       // assignment operator found
-      OwningExprResult Result = ExprError();
+      ExprResult Result = ExprError();
       if (Args[0]->getType()->isRecordType() && 
-          Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
+          Opc >= BO_Assign && Opc <= BO_OrAssign) {
         Diag(OpLoc,  diag::err_ovl_no_viable_oper)
              << BinaryOperator::getOpcodeStr(Opc)
              << Args[0]->getSourceRange() << Args[1]->getSourceRange();
@@ -6933,8 +7093,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
       assert(Result.isInvalid() && 
              "C++ binary operator overloading is missing candidates!");
       if (Result.isInvalid())
-        PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
-                                BinaryOperator::getOpcodeStr(Opc), OpLoc);
+        CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+                                    BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return move(Result);
     }
 
@@ -6942,8 +7102,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << BinaryOperator::getOpcodeStr(Opc)
           << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2,
-                              BinaryOperator::getOpcodeStr(Opc), OpLoc);
+      CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, 2,
+                                  BinaryOperator::getOpcodeStr(Opc), OpLoc);
       return ExprError();
 
     case OR_Deleted:
@@ -6951,7 +7111,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
         << Best->Function->isDeleted()
         << BinaryOperator::getOpcodeStr(Opc)
         << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2);
       return ExprError();
   }
 
@@ -6959,12 +7119,11 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
   return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 }
 
-Action::OwningExprResult
+ExprResult
 Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
                                          SourceLocation RLoc,
-                                         ExprArg Base, ExprArg Idx) {
-  Expr *Args[2] = { static_cast<Expr*>(Base.get()),
-                    static_cast<Expr*>(Idx.get()) };
+                                         Expr *Base, Expr *Idx) {
+  Expr *Args[2] = { Base, Idx };
   DeclarationName OpName =
       Context.DeclarationNames.getCXXOperatorName(OO_Subscript);
 
@@ -6973,16 +7132,17 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
   if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
 
     CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators
+    // CHECKME: no 'operator' keyword?
+    DeclarationNameInfo OpNameInfo(OpName, LLoc);
+    OpNameInfo.setCXXOperatorNameRange(SourceRange(LLoc, RLoc));
     UnresolvedLookupExpr *Fn
       = UnresolvedLookupExpr::Create(Context, /*Dependent*/ true, NamingClass,
-                                     0, SourceRange(), OpName, LLoc,
+                                     0, SourceRange(), OpNameInfo,
                                      /*ADL*/ true, /*Overloaded*/ false,
                                      UnresolvedSetIterator(),
                                      UnresolvedSetIterator());
     // Can't add any actual overloads yet
 
-    Base.release();
-    Idx.release();
     return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn,
                                                    Args, 2,
                                                    Context.DependentTy,
@@ -7002,7 +7162,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, LLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, LLoc, Best)) {
     case OR_Success: {
       // We found a built-in operator or an overloaded operator.
       FunctionDecl *FnDecl = Best->Function;
@@ -7021,7 +7181,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
           return ExprError();
 
         // Convert the arguments.
-        OwningExprResult InputInit
+        ExprResult InputInit
           = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(), 
@@ -7041,18 +7201,16 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
                                                  LLoc);
         UsualUnaryConversions(FnExpr);
 
-        Base.release();
-        Idx.release();
-        ExprOwningPtr<CXXOperatorCallExpr>
-          TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
-                                                          FnExpr, Args, 2,
-                                                          ResultTy, RLoc));
+        CXXOperatorCallExpr *TheCall =
+          new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
+                                            FnExpr, Args, 2,
+                                            ResultTy, RLoc);
 
-        if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall.get(),
+        if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall,
                                 FnDecl))
           return ExprError();
 
-        return MaybeBindToTemporary(TheCall.release());
+        return MaybeBindToTemporary(TheCall);
       } else {
         // We matched a built-in operator. Convert the arguments, then
         // break out so that we will build the appropriate built-in
@@ -7076,32 +7234,29 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
         Diag(LLoc, diag::err_ovl_no_viable_subscript)
           << Args[0]->getType()
           << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
-                              "[]", LLoc);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+                                  "[]", LLoc);
       return ExprError();
     }
 
     case OR_Ambiguous:
       Diag(LLoc,  diag::err_ovl_ambiguous_oper)
           << "[]" << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, 2,
-                              "[]", LLoc);
+      CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, 2,
+                                  "[]", LLoc);
       return ExprError();
 
     case OR_Deleted:
       Diag(LLoc, diag::err_ovl_deleted_oper)
         << Best->Function->isDeleted() << "[]"
         << Args[0]->getSourceRange() << Args[1]->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, 2,
-                              "[]", LLoc);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, 2,
+                                  "[]", LLoc);
       return ExprError();
     }
 
   // We matched a built-in operator; build it.
-  Base.release();
-  Idx.release();
-  return CreateBuiltinArraySubscriptExpr(Owned(Args[0]), LLoc,
-                                         Owned(Args[1]), RLoc);
+  return CreateBuiltinArraySubscriptExpr(Args[0], LLoc, Args[1], RLoc);
 }
 
 /// BuildCallToMemberFunction - Build a call to a member
@@ -7111,7 +7266,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
 /// parameter). The caller needs to validate that the member
 /// expression refers to a member function or an overloaded member
 /// function.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
                                 SourceLocation LParenLoc, Expr **Args,
                                 unsigned NumArgs, SourceLocation *CommaLocs,
@@ -7174,7 +7329,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
     DeclarationName DeclName = UnresExpr->getMemberName();
 
     OverloadCandidateSet::iterator Best;
-    switch (BestViableFunction(CandidateSet, UnresExpr->getLocStart(), Best)) {
+    switch (CandidateSet.BestViableFunction(*this, UnresExpr->getLocStart(),
+                               Best)) {
     case OR_Success:
       Method = cast<CXXMethodDecl>(Best->Function);
       FoundDecl = Best->FoundDecl;
@@ -7186,14 +7342,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
       Diag(UnresExpr->getMemberLoc(),
            diag::err_ovl_no_viable_member_function_in_call)
         << DeclName << MemExprE->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
       // FIXME: Leaking incoming expressions!
       return ExprError();
 
     case OR_Ambiguous:
       Diag(UnresExpr->getMemberLoc(), diag::err_ovl_ambiguous_member_call)
         << DeclName << MemExprE->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
       // FIXME: Leaking incoming expressions!
       return ExprError();
 
@@ -7201,7 +7357,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
       Diag(UnresExpr->getMemberLoc(), diag::err_ovl_deleted_member_call)
         << Best->Function->isDeleted()
         << DeclName << MemExprE->getSourceRange();
-      PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+      CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
       // FIXME: Leaking incoming expressions!
       return ExprError();
     }
@@ -7219,15 +7375,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
   }
 
   assert(Method && "Member call to something that isn't a method?");
-  ExprOwningPtr<CXXMemberCallExpr>
-    TheCall(this, new (Context) CXXMemberCallExpr(Context, MemExprE, Args,
-                                                  NumArgs,
-                                  Method->getCallResultType(),
-                                  RParenLoc));
+  CXXMemberCallExpr *TheCall = 
+    new (Context) CXXMemberCallExpr(Context, MemExprE, Args, NumArgs,
+                                    Method->getCallResultType(),
+                                    RParenLoc);
 
   // Check for a valid return type.
   if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(), 
-                          TheCall.get(), Method))
+                          TheCall, Method))
     return ExprError();
   
   // Convert the object argument (for a non-static member function call).
@@ -7242,21 +7397,21 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
 
   // Convert the rest of the arguments
   const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
-  if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
+  if (ConvertArgumentsForCall(TheCall, MemExpr, Method, Proto, Args, NumArgs,
                               RParenLoc))
     return ExprError();
 
-  if (CheckFunctionCall(Method, TheCall.get()))
+  if (CheckFunctionCall(Method, TheCall))
     return ExprError();
 
-  return MaybeBindToTemporary(TheCall.release());
+  return MaybeBindToTemporary(TheCall);
 }
 
 /// BuildCallToObjectOfClassType - Build a call to an object of class
 /// type (C++ [over.call.object]), which can end up invoking an
 /// overloaded function call operator (@c operator()) or performing a
 /// user-defined conversion on the object argument.
-Sema::ExprResult
+ExprResult
 Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
                                    SourceLocation LParenLoc,
                                    Expr **Args, unsigned NumArgs,
@@ -7338,7 +7493,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, Object->getLocStart(), Best)) {
+  switch (CandidateSet.BestViableFunction(*this, Object->getLocStart(),
+                             Best)) {
   case OR_Success:
     // Overload resolution succeeded; we'll build the appropriate call
     // below.
@@ -7353,14 +7509,14 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
       Diag(Object->getSourceRange().getBegin(),
            diag::err_ovl_no_viable_object_call)
         << Object->getType() << Object->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     break;
 
   case OR_Ambiguous:
     Diag(Object->getSourceRange().getBegin(),
          diag::err_ovl_ambiguous_object_call)
       << Object->getType() << Object->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, Args, NumArgs);
     break;
 
   case OR_Deleted:
@@ -7368,18 +7524,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
          diag::err_ovl_deleted_object_call)
       << Best->Function->isDeleted()
       << Object->getType() << Object->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Args, NumArgs);
     break;
   }
 
-  if (Best == CandidateSet.end()) {
-    // We had an error; delete all of the subexpressions and return
-    // the error.
-    Object->Destroy(Context);
-    for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
-      Args[ArgIdx]->Destroy(Context);
+  if (Best == CandidateSet.end())
     return true;
-  }
 
   if (Best->Function == 0) {
     // Since there is no function declaration, this is one of the
@@ -7400,9 +7550,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
     CXXMemberCallExpr *CE = BuildCXXMemberCallExpr(Object, Best->FoundDecl,
                                                    Conv);
       
-    return ActOnCallExpr(S, ExprArg(*this, CE), LParenLoc,
-                         MultiExprArg(*this, (ExprTy**)Args, NumArgs),
-                         CommaLocs, RParenLoc).result();
+    return ActOnCallExpr(S, CE, LParenLoc, MultiExprArg(Args, NumArgs),
+                         CommaLocs, RParenLoc);
   }
 
   CheckMemberOperatorAccess(LParenLoc, Object, 0, Best->FoundDecl);
@@ -7438,13 +7587,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
   // Once we've built TheCall, all of the expressions are properly
   // owned.
   QualType ResultTy = Method->getCallResultType();
-  ExprOwningPtr<CXXOperatorCallExpr>
-    TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
-                                                    MethodArgs, NumArgs + 1,
-                                                    ResultTy, RParenLoc));
+  CXXOperatorCallExpr *TheCall =
+    new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
+                                      MethodArgs, NumArgs + 1,
+                                      ResultTy, RParenLoc);
   delete [] MethodArgs;
 
-  if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall.get(), 
+  if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall, 
                           Method))
     return true;
   
@@ -7471,15 +7620,15 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
 
       // Pass the argument.
 
-      OwningExprResult InputInit
+      ExprResult InputInit
         = PerformCopyInitialization(InitializedEntity::InitializeParameter(
                                                     Method->getParamDecl(i)),
-                                    SourceLocation(), Owned(Arg));
+                                    SourceLocation(), Arg);
       
       IsError |= InputInit.isInvalid();
       Arg = InputInit.takeAs<Expr>();
     } else {
-      OwningExprResult DefArg
+      ExprResult DefArg
         = BuildCXXDefaultArgExpr(LParenLoc, Method, Method->getParamDecl(i));
       if (DefArg.isInvalid()) {
         IsError = true;
@@ -7504,18 +7653,17 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
 
   if (IsError) return true;
 
-  if (CheckFunctionCall(Method, TheCall.get()))
+  if (CheckFunctionCall(Method, TheCall))
     return true;
 
-  return MaybeBindToTemporary(TheCall.release()).result();
+  return MaybeBindToTemporary(TheCall);
 }
 
 /// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator->
 ///  (if one exists), where @c Base is an expression of class type and
 /// @c Member is the name of the member we're trying to find.
-Sema::OwningExprResult
-Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
-  Expr *Base = static_cast<Expr *>(BaseIn.get());
+ExprResult
+Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
   assert(Base->getType()->isRecordType() && "left-hand side must have class type");
 
   SourceLocation Loc = Base->getExprLoc();
@@ -7547,7 +7695,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
 
   // Perform overload resolution.
   OverloadCandidateSet::iterator Best;
-  switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
+  switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
   case OR_Success:
     // Overload resolution succeeded; we'll build the call below.
     break;
@@ -7559,20 +7707,20 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
     else
       Diag(OpLoc, diag::err_ovl_no_viable_oper)
         << "operator->" << Base->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
     return ExprError();
 
   case OR_Ambiguous:
     Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
       << "->" << Base->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, &Base, 1);
+    CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, &Base, 1);
     return ExprError();
 
   case OR_Deleted:
     Diag(OpLoc,  diag::err_ovl_deleted_oper)
       << Best->Function->isDeleted()
       << "->" << Base->getSourceRange();
-    PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, &Base, 1);
+    CandidateSet.NoteCandidates(*this, OCD_AllCandidates, &Base, 1);
     return ExprError();
   }
 
@@ -7585,23 +7733,20 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
                                           Best->FoundDecl, Method))
     return ExprError();
 
-  // No concerns about early exits now.
-  BaseIn.release();
-
   // Build the operator call.
   Expr *FnExpr = new (Context) DeclRefExpr(Method, Method->getType(),
                                            SourceLocation());
   UsualUnaryConversions(FnExpr);
   
   QualType ResultTy = Method->getCallResultType();
-  ExprOwningPtr<CXXOperatorCallExpr> 
-    TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, 
-                                                    &Base, 1, ResultTy, OpLoc));
+  CXXOperatorCallExpr *TheCall =
+    new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, 
+                                      &Base, 1, ResultTy, OpLoc);
 
-  if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall.get(), 
+  if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall, 
                           Method))
           return ExprError();
-  return move(TheCall);
+  return Owned(TheCall);
 }
 
 /// FixOverloadedFunctionReference - E is an expression that refers to
@@ -7626,17 +7771,18 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
     assert(Context.hasSameType(ICE->getSubExpr()->getType(), 
                                SubExpr->getType()) &&
            "Implicit cast type cannot be determined from overload");
+    assert(ICE->path_empty() && "fixing up hierarchy conversion?");
     if (SubExpr == ICE->getSubExpr())
       return ICE->Retain();
     
-    return new (Context) ImplicitCastExpr(ICE->getType(), 
-                                          ICE->getCastKind(),
-                                          SubExpr, CXXBaseSpecifierArray(),
-                                          ICE->isLvalueCast());
+    return ImplicitCastExpr::Create(Context, ICE->getType(), 
+                                    ICE->getCastKind(),
+                                    SubExpr, 0,
+                                    ICE->getValueKind());
   } 
   
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
-    assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
+    assert(UnOp->getOpcode() == UO_AddrOf &&
            "Can only take the address of an overloaded function");
     if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
       if (Method->isStatic()) {
@@ -7664,7 +7810,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
         QualType MemPtrType
           = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr());
 
-        return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+        return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
                                            MemPtrType, UnOp->getOperatorLoc());
       }
     }
@@ -7673,7 +7819,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
     if (SubExpr == UnOp->getSubExpr())
       return UnOp->Retain();
     
-    return new (Context) UnaryOperator(SubExpr, UnaryOperator::AddrOf,
+    return new (Context) UnaryOperator(SubExpr, UO_AddrOf,
                                      Context.getPointerType(SubExpr->getType()),
                                        UnOp->getOperatorLoc());
   } 
@@ -7732,7 +7878,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
                               MemExpr->getQualifierRange(),
                               Fn, 
                               Found,
-                              MemExpr->getMemberLoc(),
+                              MemExpr->getMemberNameInfo(),
                               TemplateArgs,
                               Fn->getType());
   }
@@ -7741,9 +7887,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
   return E->Retain();
 }
 
-Sema::OwningExprResult Sema::FixOverloadedFunctionReference(OwningExprResult E, 
-                                                          DeclAccessPair Found,
-                                                            FunctionDecl *Fn) {
+ExprResult Sema::FixOverloadedFunctionReference(ExprResult E, 
+                                                DeclAccessPair Found,
+                                                FunctionDecl *Fn) {
   return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Found, Fn));
 }
 
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
deleted file mode 100644
index eb4fc65..0000000
--- a/lib/Sema/SemaOverload.h
+++ /dev/null
@@ -1,617 +0,0 @@
-//===--- Overload.h - C++ Overloading ---------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the data structures and types used in C++
-// overload resolution.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_OVERLOAD_H
-#define LLVM_CLANG_SEMA_OVERLOAD_H
-
-#include "clang/AST/Decl.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/Expr.h"
-#include "clang/AST/TemplateBase.h"
-#include "clang/AST/Type.h"
-#include "clang/AST/UnresolvedSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-  class ASTContext;
-  class CXXConstructorDecl;
-  class CXXConversionDecl;
-  class FunctionDecl;
-
-  /// OverloadingResult - Capture the result of performing overload
-  /// resolution.
-  enum OverloadingResult {
-    OR_Success,             ///< Overload resolution succeeded.
-    OR_No_Viable_Function,  ///< No viable function found.
-    OR_Ambiguous,           ///< Ambiguous candidates found.
-    OR_Deleted              ///< Succeeded, but refers to a deleted function.
-  };
-    
-  /// ImplicitConversionKind - The kind of implicit conversion used to
-  /// convert an argument to a parameter's type. The enumerator values
-  /// match with Table 9 of (C++ 13.3.3.1.1) and are listed such that
-  /// better conversion kinds have smaller values.
-  enum ImplicitConversionKind {
-    ICK_Identity = 0,          ///< Identity conversion (no conversion)
-    ICK_Lvalue_To_Rvalue,      ///< Lvalue-to-rvalue conversion (C++ 4.1)
-    ICK_Array_To_Pointer,      ///< Array-to-pointer conversion (C++ 4.2)
-    ICK_Function_To_Pointer,   ///< Function-to-pointer (C++ 4.3)
-    ICK_NoReturn_Adjustment,   ///< Removal of noreturn from a type (Clang)
-    ICK_Qualification,         ///< Qualification conversions (C++ 4.4)
-    ICK_Integral_Promotion,    ///< Integral promotions (C++ 4.5)
-    ICK_Floating_Promotion,    ///< Floating point promotions (C++ 4.6)
-    ICK_Complex_Promotion,     ///< Complex promotions (Clang extension)
-    ICK_Integral_Conversion,   ///< Integral conversions (C++ 4.7)
-    ICK_Floating_Conversion,   ///< Floating point conversions (C++ 4.8)
-    ICK_Complex_Conversion,    ///< Complex conversions (C99 6.3.1.6)
-    ICK_Floating_Integral,     ///< Floating-integral conversions (C++ 4.9)
-    ICK_Pointer_Conversion,    ///< Pointer conversions (C++ 4.10)
-    ICK_Pointer_Member,        ///< Pointer-to-member conversions (C++ 4.11)
-    ICK_Boolean_Conversion,    ///< Boolean conversions (C++ 4.12)
-    ICK_Compatible_Conversion, ///< Conversions between compatible types in C99
-    ICK_Derived_To_Base,       ///< Derived-to-base (C++ [over.best.ics])
-    ICK_Vector_Conversion,     ///< Vector conversions
-    ICK_Vector_Splat,          ///< A vector splat from an arithmetic type
-    ICK_Complex_Real,          ///< Complex-real conversions (C99 6.3.1.7)
-    ICK_Num_Conversion_Kinds   ///< The number of conversion kinds
-  };
-
-  /// ImplicitConversionCategory - The category of an implicit
-  /// conversion kind. The enumerator values match with Table 9 of
-  /// (C++ 13.3.3.1.1) and are listed such that better conversion
-  /// categories have smaller values.
-  enum ImplicitConversionCategory {
-    ICC_Identity = 0,              ///< Identity
-    ICC_Lvalue_Transformation,     ///< Lvalue transformation
-    ICC_Qualification_Adjustment,  ///< Qualification adjustment
-    ICC_Promotion,                 ///< Promotion
-    ICC_Conversion                 ///< Conversion
-  };
-
-  ImplicitConversionCategory
-  GetConversionCategory(ImplicitConversionKind Kind);
-
-  /// ImplicitConversionRank - The rank of an implicit conversion
-  /// kind. The enumerator values match with Table 9 of (C++
-  /// 13.3.3.1.1) and are listed such that better conversion ranks
-  /// have smaller values.
-  enum ImplicitConversionRank {
-    ICR_Exact_Match = 0,        ///< Exact Match
-    ICR_Promotion,              ///< Promotion
-    ICR_Conversion,             ///< Conversion
-    ICR_Complex_Real_Conversion ///< Complex <-> Real conversion
-  };
-
-  ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind);
-
-  /// StandardConversionSequence - represents a standard conversion
-  /// sequence (C++ 13.3.3.1.1). A standard conversion sequence
-  /// contains between zero and three conversions. If a particular
-  /// conversion is not needed, it will be set to the identity conversion
-  /// (ICK_Identity). Note that the three conversions are
-  /// specified as separate members (rather than in an array) so that
-  /// we can keep the size of a standard conversion sequence to a
-  /// single word.
-  struct StandardConversionSequence {
-    /// First -- The first conversion can be an lvalue-to-rvalue
-    /// conversion, array-to-pointer conversion, or
-    /// function-to-pointer conversion.
-    ImplicitConversionKind First : 8;
-
-    /// Second - The second conversion can be an integral promotion,
-    /// floating point promotion, integral conversion, floating point
-    /// conversion, floating-integral conversion, pointer conversion,
-    /// pointer-to-member conversion, or boolean conversion.
-    ImplicitConversionKind Second : 8;
-
-    /// Third - The third conversion can be a qualification conversion.
-    ImplicitConversionKind Third : 8;
-
-    /// Deprecated - Whether this the deprecated conversion of a
-    /// string literal to a pointer to non-const character data
-    /// (C++ 4.2p2).
-    bool DeprecatedStringLiteralToCharPtr : 1;
-
-    /// IncompatibleObjC - Whether this is an Objective-C conversion
-    /// that we should warn about (if we actually use it).
-    bool IncompatibleObjC : 1;
-
-    /// ReferenceBinding - True when this is a reference binding
-    /// (C++ [over.ics.ref]).
-    bool ReferenceBinding : 1;
-
-    /// DirectBinding - True when this is a reference binding that is a
-    /// direct binding (C++ [dcl.init.ref]).
-    bool DirectBinding : 1;
-
-    /// RRefBinding - True when this is a reference binding of an rvalue
-    /// reference to an rvalue (C++0x [over.ics.rank]p3b4).
-    bool RRefBinding : 1;
-
-    /// FromType - The type that this conversion is converting
-    /// from. This is an opaque pointer that can be translated into a
-    /// QualType.
-    void *FromTypePtr;
-
-    /// ToType - The types that this conversion is converting to in
-    /// each step. This is an opaque pointer that can be translated
-    /// into a QualType.
-    void *ToTypePtrs[3];
-
-    /// CopyConstructor - The copy constructor that is used to perform
-    /// this conversion, when the conversion is actually just the
-    /// initialization of an object via copy constructor. Such
-    /// conversions are either identity conversions or derived-to-base
-    /// conversions.
-    CXXConstructorDecl *CopyConstructor;
-
-    void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
-    void setToType(unsigned Idx, QualType T) { 
-      assert(Idx < 3 && "To type index is out of range");
-      ToTypePtrs[Idx] = T.getAsOpaquePtr(); 
-    }
-    void setAllToTypes(QualType T) {
-      ToTypePtrs[0] = T.getAsOpaquePtr(); 
-      ToTypePtrs[1] = ToTypePtrs[0];
-      ToTypePtrs[2] = ToTypePtrs[0];
-    }
-
-    QualType getFromType() const {
-      return QualType::getFromOpaquePtr(FromTypePtr);
-    }
-    QualType getToType(unsigned Idx) const {
-      assert(Idx < 3 && "To type index is out of range");
-      return QualType::getFromOpaquePtr(ToTypePtrs[Idx]);
-    }
-
-    void setAsIdentityConversion();
-    
-    bool isIdentityConversion() const {
-      return First == ICK_Identity && Second == ICK_Identity && 
-             Third == ICK_Identity;
-    }
-    
-    ImplicitConversionRank getRank() const;
-    bool isPointerConversionToBool() const;
-    bool isPointerConversionToVoidPointer(ASTContext& Context) const;
-    void DebugPrint() const;
-  };
-
-  /// UserDefinedConversionSequence - Represents a user-defined
-  /// conversion sequence (C++ 13.3.3.1.2).
-  struct UserDefinedConversionSequence {
-    /// Before - Represents the standard conversion that occurs before
-    /// the actual user-defined conversion. (C++ 13.3.3.1.2p1):
-    ///
-    ///   If the user-defined conversion is specified by a constructor
-    ///   (12.3.1), the initial standard conversion sequence converts
-    ///   the source type to the type required by the argument of the
-    ///   constructor. If the user-defined conversion is specified by
-    ///   a conversion function (12.3.2), the initial standard
-    ///   conversion sequence converts the source type to the implicit
-    ///   object parameter of the conversion function.
-    StandardConversionSequence Before;
-
-    /// EllipsisConversion - When this is true, it means user-defined
-    /// conversion sequence starts with a ... (elipsis) conversion, instead of 
-    /// a standard conversion. In this case, 'Before' field must be ignored.
-    // FIXME. I much rather put this as the first field. But there seems to be
-    // a gcc code gen. bug which causes a crash in a test. Putting it here seems
-    // to work around the crash.
-    bool EllipsisConversion : 1;
-    
-    /// After - Represents the standard conversion that occurs after
-    /// the actual user-defined conversion.
-    StandardConversionSequence After;
-
-    /// ConversionFunction - The function that will perform the
-    /// user-defined conversion.
-    FunctionDecl* ConversionFunction;
-
-    void DebugPrint() const;
-  };
-
-  /// Represents an ambiguous user-defined conversion sequence.
-  struct AmbiguousConversionSequence {
-    typedef llvm::SmallVector<FunctionDecl*, 4> ConversionSet;
-
-    void *FromTypePtr;
-    void *ToTypePtr;
-    char Buffer[sizeof(ConversionSet)];
-
-    QualType getFromType() const {
-      return QualType::getFromOpaquePtr(FromTypePtr);
-    }
-    QualType getToType() const {
-      return QualType::getFromOpaquePtr(ToTypePtr);
-    }
-    void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
-    void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
-
-    ConversionSet &conversions() {
-      return *reinterpret_cast<ConversionSet*>(Buffer);
-    }
-
-    const ConversionSet &conversions() const {
-      return *reinterpret_cast<const ConversionSet*>(Buffer);
-    }
-
-    void addConversion(FunctionDecl *D) {
-      conversions().push_back(D);
-    }
-
-    typedef ConversionSet::iterator iterator;
-    iterator begin() { return conversions().begin(); }
-    iterator end() { return conversions().end(); }
-
-    typedef ConversionSet::const_iterator const_iterator;
-    const_iterator begin() const { return conversions().begin(); }
-    const_iterator end() const { return conversions().end(); }
-
-    void construct();
-    void destruct();
-    void copyFrom(const AmbiguousConversionSequence &);
-  };
-
-  /// BadConversionSequence - Records information about an invalid
-  /// conversion sequence.
-  struct BadConversionSequence {
-    enum FailureKind {
-      no_conversion,
-      unrelated_class,
-      suppressed_user,
-      bad_qualifiers
-    };
-
-    // This can be null, e.g. for implicit object arguments.
-    Expr *FromExpr;
-
-    FailureKind Kind;
-
-  private:
-    // The type we're converting from (an opaque QualType).
-    void *FromTy;
-
-    // The type we're converting to (an opaque QualType).
-    void *ToTy;
-
-  public:
-    void init(FailureKind K, Expr *From, QualType To) {
-      init(K, From->getType(), To);
-      FromExpr = From;
-    }
-    void init(FailureKind K, QualType From, QualType To) {
-      Kind = K;
-      FromExpr = 0;
-      setFromType(From);
-      setToType(To);
-    }
-
-    QualType getFromType() const { return QualType::getFromOpaquePtr(FromTy); }
-    QualType getToType() const { return QualType::getFromOpaquePtr(ToTy); }
-
-    void setFromExpr(Expr *E) {
-      FromExpr = E;
-      setFromType(E->getType());
-    }
-    void setFromType(QualType T) { FromTy = T.getAsOpaquePtr(); }
-    void setToType(QualType T) { ToTy = T.getAsOpaquePtr(); }
-  };
-
-  /// ImplicitConversionSequence - Represents an implicit conversion
-  /// sequence, which may be a standard conversion sequence
-  /// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
-  /// or an ellipsis conversion sequence (C++ 13.3.3.1.3).
-  struct ImplicitConversionSequence {
-    /// Kind - The kind of implicit conversion sequence. BadConversion
-    /// specifies that there is no conversion from the source type to
-    /// the target type.  AmbiguousConversion represents the unique
-    /// ambiguous conversion (C++0x [over.best.ics]p10).
-    enum Kind {
-      StandardConversion = 0,
-      UserDefinedConversion,
-      AmbiguousConversion,
-      EllipsisConversion,
-      BadConversion
-    };
-
-  private:
-    enum {
-      Uninitialized = BadConversion + 1
-    };
-
-    /// ConversionKind - The kind of implicit conversion sequence.
-    unsigned ConversionKind;
-
-    void setKind(Kind K) {
-      destruct();
-      ConversionKind = K;
-    }
-
-    void destruct() {
-      if (ConversionKind == AmbiguousConversion) Ambiguous.destruct();
-    }
-
-  public:
-    union {
-      /// When ConversionKind == StandardConversion, provides the
-      /// details of the standard conversion sequence.
-      StandardConversionSequence Standard;
-
-      /// When ConversionKind == UserDefinedConversion, provides the
-      /// details of the user-defined conversion sequence.
-      UserDefinedConversionSequence UserDefined;
-
-      /// When ConversionKind == AmbiguousConversion, provides the
-      /// details of the ambiguous conversion.
-      AmbiguousConversionSequence Ambiguous;
-
-      /// When ConversionKind == BadConversion, provides the details
-      /// of the bad conversion.
-      BadConversionSequence Bad;
-    };
-
-    ImplicitConversionSequence() : ConversionKind(Uninitialized) {}
-    ~ImplicitConversionSequence() {
-      destruct();
-    }
-    ImplicitConversionSequence(const ImplicitConversionSequence &Other)
-      : ConversionKind(Other.ConversionKind)
-    {
-      switch (ConversionKind) {
-      case Uninitialized: break;
-      case StandardConversion: Standard = Other.Standard; break;
-      case UserDefinedConversion: UserDefined = Other.UserDefined; break;
-      case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
-      case EllipsisConversion: break;
-      case BadConversion: Bad = Other.Bad; break;
-      }
-    }
-
-    ImplicitConversionSequence &
-        operator=(const ImplicitConversionSequence &Other) {
-      destruct();
-      new (this) ImplicitConversionSequence(Other);
-      return *this;
-    }
-    
-    Kind getKind() const {
-      assert(isInitialized() && "querying uninitialized conversion");
-      return Kind(ConversionKind);
-    }
-    
-    /// \brief Return a ranking of the implicit conversion sequence
-    /// kind, where smaller ranks represent better conversion
-    /// sequences.
-    ///
-    /// In particular, this routine gives user-defined conversion
-    /// sequences and ambiguous conversion sequences the same rank,
-    /// per C++ [over.best.ics]p10.
-    unsigned getKindRank() const {
-      switch (getKind()) {
-      case StandardConversion: 
-        return 0;
-
-      case UserDefinedConversion:
-      case AmbiguousConversion: 
-        return 1;
-
-      case EllipsisConversion:
-        return 2;
-
-      case BadConversion:
-        return 3;
-      }
-
-      return 3;
-    }
-
-    bool isBad() const { return getKind() == BadConversion; }
-    bool isStandard() const { return getKind() == StandardConversion; }
-    bool isEllipsis() const { return getKind() == EllipsisConversion; }
-    bool isAmbiguous() const { return getKind() == AmbiguousConversion; }
-    bool isUserDefined() const { return getKind() == UserDefinedConversion; }
-
-    /// Determines whether this conversion sequence has been
-    /// initialized.  Most operations should never need to query
-    /// uninitialized conversions and should assert as above.
-    bool isInitialized() const { return ConversionKind != Uninitialized; }
-
-    /// Sets this sequence as a bad conversion for an explicit argument.
-    void setBad(BadConversionSequence::FailureKind Failure,
-                Expr *FromExpr, QualType ToType) {
-      setKind(BadConversion);
-      Bad.init(Failure, FromExpr, ToType);
-    }
-
-    /// Sets this sequence as a bad conversion for an implicit argument.
-    void setBad(BadConversionSequence::FailureKind Failure,
-                QualType FromType, QualType ToType) {
-      setKind(BadConversion);
-      Bad.init(Failure, FromType, ToType);
-    }
-
-    void setStandard() { setKind(StandardConversion); }
-    void setEllipsis() { setKind(EllipsisConversion); }
-    void setUserDefined() { setKind(UserDefinedConversion); }
-    void setAmbiguous() {
-      if (ConversionKind == AmbiguousConversion) return;
-      ConversionKind = AmbiguousConversion;
-      Ambiguous.construct();
-    }
-
-    // The result of a comparison between implicit conversion
-    // sequences. Use Sema::CompareImplicitConversionSequences to
-    // actually perform the comparison.
-    enum CompareKind {
-      Better = -1,
-      Indistinguishable = 0,
-      Worse = 1
-    };
-
-    void DebugPrint() const;
-  };
-
-  enum OverloadFailureKind {
-    ovl_fail_too_many_arguments,
-    ovl_fail_too_few_arguments,
-    ovl_fail_bad_conversion,
-    ovl_fail_bad_deduction,
-
-    /// This conversion candidate was not considered because it
-    /// duplicates the work of a trivial or derived-to-base
-    /// conversion.
-    ovl_fail_trivial_conversion,
-
-    /// This conversion candidate is not viable because its result
-    /// type is not implicitly convertible to the desired type.
-    ovl_fail_bad_final_conversion,
-    
-    /// This conversion function template specialization candidate is not 
-    /// viable because the final conversion was not an exact match.
-    ovl_fail_final_conversion_not_exact
-  };
-
-  /// OverloadCandidate - A single candidate in an overload set (C++ 13.3).
-  struct OverloadCandidate {
-    /// Function - The actual function that this candidate
-    /// represents. When NULL, this is a built-in candidate
-    /// (C++ [over.oper]) or a surrogate for a conversion to a
-    /// function pointer or reference (C++ [over.call.object]).
-    FunctionDecl *Function;
-
-    /// FoundDecl - The original declaration that was looked up /
-    /// invented / otherwise found, together with its access.
-    /// Might be a UsingShadowDecl or a FunctionTemplateDecl.
-    DeclAccessPair FoundDecl;
-
-    // BuiltinTypes - Provides the return and parameter types of a
-    // built-in overload candidate. Only valid when Function is NULL.
-    struct {
-      QualType ResultTy;
-      QualType ParamTypes[3];
-    } BuiltinTypes;
-
-    /// Surrogate - The conversion function for which this candidate
-    /// is a surrogate, but only if IsSurrogate is true.
-    CXXConversionDecl *Surrogate;
-
-    /// Conversions - The conversion sequences used to convert the
-    /// function arguments to the function parameters.
-    llvm::SmallVector<ImplicitConversionSequence, 4> Conversions;
-
-    /// Viable - True to indicate that this overload candidate is viable.
-    bool Viable;
-
-    /// IsSurrogate - True to indicate that this candidate is a
-    /// surrogate for a conversion to a function pointer or reference
-    /// (C++ [over.call.object]).
-    bool IsSurrogate;
-
-    /// IgnoreObjectArgument - True to indicate that the first
-    /// argument's conversion, which for this function represents the
-    /// implicit object argument, should be ignored. This will be true
-    /// when the candidate is a static member function (where the
-    /// implicit object argument is just a placeholder) or a
-    /// non-static member function when the call doesn't have an
-    /// object argument.
-    bool IgnoreObjectArgument;
-
-    /// FailureKind - The reason why this candidate is not viable.
-    /// Actually an OverloadFailureKind.
-    unsigned char FailureKind;
-
-    /// A structure used to record information about a failed
-    /// template argument deduction.
-    struct DeductionFailureInfo {
-      // A Sema::TemplateDeductionResult.
-      unsigned Result;
-
-      /// \brief Opaque pointer containing additional data about
-      /// this deduction failure.
-      void *Data;
-      
-      /// \brief Retrieve the template parameter this deduction failure
-      /// refers to, if any.
-      TemplateParameter getTemplateParameter();
-      
-      /// \brief Retrieve the template argument list associated with this
-      /// deduction failure, if any.
-      TemplateArgumentList *getTemplateArgumentList();
-      
-      /// \brief Return the first template argument this deduction failure
-      /// refers to, if any.
-      const TemplateArgument *getFirstArg();
-
-      /// \brief Return the second template argument this deduction failure
-      /// refers to, if any.
-      const TemplateArgument *getSecondArg();
-      
-      /// \brief Free any memory associated with this deduction failure.
-      void Destroy();
-    };
-
-    union {
-      DeductionFailureInfo DeductionFailure;
-      
-      /// FinalConversion - For a conversion function (where Function is
-      /// a CXXConversionDecl), the standard conversion that occurs
-      /// after the call to the overload candidate to convert the result
-      /// of calling the conversion function to the required type.
-      StandardConversionSequence FinalConversion;
-    };
-
-    /// hasAmbiguousConversion - Returns whether this overload
-    /// candidate requires an ambiguous conversion or not.
-    bool hasAmbiguousConversion() const {
-      for (llvm::SmallVectorImpl<ImplicitConversionSequence>::const_iterator
-             I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
-        if (!I->isInitialized()) return false;
-        if (I->isAmbiguous()) return true;
-      }
-      return false;
-    }
-  };
-
-  /// OverloadCandidateSet - A set of overload candidates, used in C++
-  /// overload resolution (C++ 13.3).
-  class OverloadCandidateSet : public llvm::SmallVector<OverloadCandidate, 16> {
-    typedef llvm::SmallVector<OverloadCandidate, 16> inherited;
-    llvm::SmallPtrSet<Decl *, 16> Functions;
-
-    SourceLocation Loc;    
-    
-    OverloadCandidateSet(const OverloadCandidateSet &);
-    OverloadCandidateSet &operator=(const OverloadCandidateSet &);
-    
-  public:
-    OverloadCandidateSet(SourceLocation Loc) : Loc(Loc) {}
-
-    SourceLocation getLocation() const { return Loc; }
-
-    /// \brief Determine when this overload candidate will be new to the
-    /// overload set.
-    bool isNewCandidate(Decl *F) { 
-      return Functions.insert(F->getCanonicalDecl()); 
-    }
-
-    /// \brief Clear out all of the candidates.
-    void clear();
-    
-    ~OverloadCandidateSet() { clear(); }
-  };
-} // end namespace clang
-
-#endif // LLVM_CLANG_SEMA_OVERLOAD_H
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9c8f48b..083e4db 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -11,8 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
-#include "SemaInit.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/Initialization.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
@@ -26,19 +28,11 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 using namespace clang;
+using namespace sema;
 
-Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
-  Expr *E = expr->takeAs<Expr>();
+StmtResult Sema::ActOnExprStmt(FullExprArg expr) {
+  Expr *E = expr.get();
   assert(E && "ActOnExprStmt(): missing expression");
-  if (E->getType()->isObjCObjectType()) {
-    if (LangOpts.ObjCNonFragileABI)
-      Diag(E->getLocEnd(), diag::err_indirection_requires_nonfragile_object)
-             << E->getType();
-    else
-      Diag(E->getLocEnd(), diag::err_direct_interface_unsupported)
-             << E->getType();
-    return StmtError();
-  }
   // C99 6.8.3p2: The expression in an expression statement is evaluated as a
   // void expression for its side effects.  Conversion to void allows any
   // operand, even incomplete types.
@@ -48,11 +42,11 @@ Sema::OwningStmtResult Sema::ActOnExprStmt(FullExprArg expr) {
 }
 
 
-Sema::OwningStmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
+StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc) {
   return Owned(new (Context) NullStmt(SemiLoc));
 }
 
-Sema::OwningStmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
+StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
                                            SourceLocation StartLoc,
                                            SourceLocation EndLoc) {
   DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
@@ -141,10 +135,10 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
     }
   }
 
-  Diag(Loc, DiagID) << R1 << R2;
+  DiagRuntimeBehavior(Loc, PDiag(DiagID) << R1 << R2);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                         MultiStmtArg elts, bool isStmtExpr) {
   unsigned NumElts = elts.size();
@@ -179,70 +173,60 @@ Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
   return Owned(new (Context) CompoundStmt(Context, Elts, NumElts, L, R));
 }
 
-Action::OwningStmtResult
-Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprArg lhsval,
-                    SourceLocation DotDotDotLoc, ExprArg rhsval,
+StmtResult
+Sema::ActOnCaseStmt(SourceLocation CaseLoc, Expr *LHSVal,
+                    SourceLocation DotDotDotLoc, Expr *RHSVal,
                     SourceLocation ColonLoc) {
-  assert((lhsval.get() != 0) && "missing expression in case statement");
+  assert((LHSVal != 0) && "missing expression in case statement");
 
   // C99 6.8.4.2p3: The expression shall be an integer constant.
   // However, GCC allows any evaluatable integer expression.
-  Expr *LHSVal = static_cast<Expr*>(lhsval.get());
   if (!LHSVal->isTypeDependent() && !LHSVal->isValueDependent() &&
       VerifyIntegerConstantExpression(LHSVal))
     return StmtError();
 
   // GCC extension: The expression shall be an integer constant.
 
-  Expr *RHSVal = static_cast<Expr*>(rhsval.get());
   if (RHSVal && !RHSVal->isTypeDependent() && !RHSVal->isValueDependent() &&
       VerifyIntegerConstantExpression(RHSVal)) {
     RHSVal = 0;  // Recover by just forgetting about it.
-    rhsval = 0;
   }
 
-  if (getSwitchStack().empty()) {
+  if (getCurFunction()->SwitchStack.empty()) {
     Diag(CaseLoc, diag::err_case_not_in_switch);
     return StmtError();
   }
 
-  // Only now release the smart pointers.
-  lhsval.release();
-  rhsval.release();
   CaseStmt *CS = new (Context) CaseStmt(LHSVal, RHSVal, CaseLoc, DotDotDotLoc,
                                         ColonLoc);
-  getSwitchStack().back()->addSwitchCase(CS);
+  getCurFunction()->SwitchStack.back()->addSwitchCase(CS);
   return Owned(CS);
 }
 
 /// ActOnCaseStmtBody - This installs a statement as the body of a case.
-void Sema::ActOnCaseStmtBody(StmtTy *caseStmt, StmtArg subStmt) {
+void Sema::ActOnCaseStmtBody(Stmt *caseStmt, Stmt *SubStmt) {
   CaseStmt *CS = static_cast<CaseStmt*>(caseStmt);
-  Stmt *SubStmt = subStmt.takeAs<Stmt>();
   CS->setSubStmt(SubStmt);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
-                       StmtArg subStmt, Scope *CurScope) {
-  Stmt *SubStmt = subStmt.takeAs<Stmt>();
-
-  if (getSwitchStack().empty()) {
+                       Stmt *SubStmt, Scope *CurScope) {
+  if (getCurFunction()->SwitchStack.empty()) {
     Diag(DefaultLoc, diag::err_default_not_in_switch);
     return Owned(SubStmt);
   }
 
   DefaultStmt *DS = new (Context) DefaultStmt(DefaultLoc, ColonLoc, SubStmt);
-  getSwitchStack().back()->addSwitchCase(DS);
+  getCurFunction()->SwitchStack.back()->addSwitchCase(DS);
   return Owned(DS);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
-                     SourceLocation ColonLoc, StmtArg subStmt) {
-  Stmt *SubStmt = subStmt.takeAs<Stmt>();
+                     SourceLocation ColonLoc, Stmt *SubStmt) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[II];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[II];
 
   // If not forward referenced or defined already, just create a new LabelStmt.
   if (LabelDecl == 0)
@@ -265,15 +249,15 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
   return Owned(LabelDecl);
 }
 
-Action::OwningStmtResult
-Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
-                  StmtArg ThenVal, SourceLocation ElseLoc,
-                  StmtArg ElseVal) {
-  OwningExprResult CondResult(CondVal.release());
+StmtResult
+Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
+                  Stmt *thenStmt, SourceLocation ElseLoc,
+                  Stmt *elseStmt) {
+  ExprResult CondResult(CondVal.release());
 
   VarDecl *ConditionVar = 0;
-  if (CondVar.get()) {
-    ConditionVar = CondVar.getAs<VarDecl>();
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
     CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
     if (CondResult.isInvalid())
       return StmtError();
@@ -282,22 +266,19 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar,
   if (!ConditionExpr)
     return StmtError();
   
-  Stmt *thenStmt = ThenVal.takeAs<Stmt>();
   DiagnoseUnusedExprResult(thenStmt);
 
   // Warn if the if block has a null body without an else value.
   // this helps prevent bugs due to typos, such as
   // if (condition);
   //   do_stuff();
-  if (!ElseVal.get()) {
+  if (!elseStmt) {
     if (NullStmt* stmt = dyn_cast<NullStmt>(thenStmt))
       Diag(stmt->getSemiLoc(), diag::warn_empty_if_body);
   }
 
-  Stmt *elseStmt = ElseVal.takeAs<Stmt>();
   DiagnoseUnusedExprResult(elseStmt);
 
-  CondResult.release();
   return Owned(new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr, 
                                     thenStmt, ElseLoc, elseStmt));
 }
@@ -404,64 +385,63 @@ static QualType GetTypeBeforeIntegralPromotion(const Expr* expr) {
   return expr->getType();
 }
 
-Action::OwningStmtResult
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, ExprArg Cond, 
-                             DeclPtrTy CondVar) {
+StmtResult
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond, 
+                             Decl *CondVar) {
+  ExprResult CondResult;
+
   VarDecl *ConditionVar = 0;
-  if (CondVar.get()) {
-    ConditionVar = CondVar.getAs<VarDecl>();
-    OwningExprResult CondE = CheckConditionVariable(ConditionVar, SourceLocation(), false);
-    if (CondE.isInvalid())
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
+    CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
+    if (CondResult.isInvalid())
       return StmtError();
     
-    Cond = move(CondE);
+    Cond = CondResult.release();
   }
   
-  if (!Cond.get())
+  if (!Cond)
     return StmtError();
   
-  Expr *CondExpr = static_cast<Expr *>(Cond.get());
-  OwningExprResult ConvertedCond 
-    = ConvertToIntegralOrEnumerationType(SwitchLoc, move(Cond), 
+  CondResult
+    = ConvertToIntegralOrEnumerationType(SwitchLoc, Cond, 
                           PDiag(diag::err_typecheck_statement_requires_integer),
                                    PDiag(diag::err_switch_incomplete_class_type)
-                                     << CondExpr->getSourceRange(),
+                                     << Cond->getSourceRange(),
                                    PDiag(diag::err_switch_explicit_conversion),
                                          PDiag(diag::note_switch_conversion),
                                    PDiag(diag::err_switch_multiple_conversions),
                                          PDiag(diag::note_switch_conversion),
                                          PDiag(0));
-  if (ConvertedCond.isInvalid())
-    return StmtError();
+  if (CondResult.isInvalid()) return StmtError();
+  Cond = CondResult.take();
   
-  CondExpr = ConvertedCond.takeAs<Expr>();
-  
-  if (!CondVar.get()) {
-    CondExpr = MaybeCreateCXXExprWithTemporaries(CondExpr);
-    if (!CondExpr)
+  if (!CondVar) {
+    CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
+    if (CondResult.isInvalid())
       return StmtError();
+    Cond = CondResult.take();
   }
+
+  getCurFunction()->setHasBranchIntoScope();
     
-  SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, CondExpr);
-  getSwitchStack().push_back(SS);
+  SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
+  getCurFunction()->SwitchStack.push_back(SS);
   return Owned(SS);
 }
 
-Action::OwningStmtResult
-Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
-                            StmtArg Body) {
-  Stmt *BodyStmt = Body.takeAs<Stmt>();
-
-  SwitchStmt *SS = getSwitchStack().back();
-  assert(SS == (SwitchStmt*)Switch.get() && "switch stack missing push/pop!");
+StmtResult
+Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
+                            Stmt *BodyStmt) {
+  SwitchStmt *SS = cast<SwitchStmt>(Switch);
+  assert(SS == getCurFunction()->SwitchStack.back() &&
+         "switch stack missing push/pop!");
 
   SS->setBody(BodyStmt, SwitchLoc);
-  getSwitchStack().pop_back();
+  getCurFunction()->SwitchStack.pop_back();
 
-  if (SS->getCond() == 0) {
-    SS->Destroy(Context);
+  if (SS->getCond() == 0)
     return StmtError();
-  }
     
   Expr *CondExpr = SS->getCond();
   Expr *CondExprBeforePromotion = CondExpr;
@@ -556,7 +536,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
 
       // If the LHS is not the same type as the condition, insert an implicit
       // cast.
-      ImpCastExprToType(Lo, CondType, CastExpr::CK_IntegralCast);
+      ImpCastExprToType(Lo, CondType, CK_IntegralCast);
       CS->setLHS(Lo);
 
       // If this is a case range, remember it in CaseRanges, otherwise CaseVals.
@@ -635,7 +615,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
 
         // If the LHS is not the same type as the condition, insert an implicit
         // cast.
-        ImpCastExprToType(Hi, CondType, CastExpr::CK_IntegralCast);
+        ImpCastExprToType(Hi, CondType, CK_IntegralCast);
         CR->setRHS(Hi);
 
         // If the low value is bigger than the high value, the case is empty.
@@ -804,65 +784,55 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch,
   if (CaseListIsErroneous)
     return StmtError();
 
-  Switch.release();
   return Owned(SS);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, 
-                     DeclPtrTy CondVar, StmtArg Body) {
-  OwningExprResult CondResult(Cond.release());
+                     Decl *CondVar, Stmt *Body) {
+  ExprResult CondResult(Cond.release());
   
   VarDecl *ConditionVar = 0;
-  if (CondVar.get()) {
-    ConditionVar = CondVar.getAs<VarDecl>();
+  if (CondVar) {
+    ConditionVar = cast<VarDecl>(CondVar);
     CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
     if (CondResult.isInvalid())
       return StmtError();
   }
-  Expr *ConditionExpr = CondResult.takeAs<Expr>();
+  Expr *ConditionExpr = CondResult.take();
   if (!ConditionExpr)
     return StmtError();
   
-  Stmt *bodyStmt = Body.takeAs<Stmt>();
-  DiagnoseUnusedExprResult(bodyStmt);
+  DiagnoseUnusedExprResult(Body);
 
-  CondResult.release();
   return Owned(new (Context) WhileStmt(Context, ConditionVar, ConditionExpr,
-                                       bodyStmt, WhileLoc));
+                                       Body, WhileLoc));
 }
 
-Action::OwningStmtResult
-Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body,
+StmtResult
+Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
                   SourceLocation WhileLoc, SourceLocation CondLParen,
-                  ExprArg Cond, SourceLocation CondRParen) {
-  Expr *condExpr = Cond.takeAs<Expr>();
-  assert(condExpr && "ActOnDoStmt(): missing expression");
+                  Expr *Cond, SourceLocation CondRParen) {
+  assert(Cond && "ActOnDoStmt(): missing expression");
 
-  if (CheckBooleanCondition(condExpr, DoLoc)) {
-    Cond = condExpr;
+  if (CheckBooleanCondition(Cond, DoLoc))
     return StmtError();
-  }
 
-  condExpr = MaybeCreateCXXExprWithTemporaries(condExpr);
-  if (!condExpr)
+  ExprResult CondResult = MaybeCreateCXXExprWithTemporaries(Cond);
+  if (CondResult.isInvalid())
     return StmtError();
+  Cond = CondResult.take();
   
-  Stmt *bodyStmt = Body.takeAs<Stmt>();
-  DiagnoseUnusedExprResult(bodyStmt);
+  DiagnoseUnusedExprResult(Body);
 
-  Cond.release();
-  return Owned(new (Context) DoStmt(bodyStmt, condExpr, DoLoc,
-                                    WhileLoc, CondRParen));
+  return Owned(new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
-                   StmtArg first, FullExprArg second, DeclPtrTy secondVar,
+                   Stmt *First, FullExprArg second, Decl *secondVar,
                    FullExprArg third,
-                   SourceLocation RParenLoc, StmtArg body) {
-  Stmt *First  = static_cast<Stmt*>(first.get());
-
+                   SourceLocation RParenLoc, Stmt *Body) {
   if (!getLangOptions().CPlusPlus) {
     if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
       // C99 6.8.5p3: The declaration part of a 'for' statement shall only
@@ -880,38 +850,32 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
     }
   }
 
-  OwningExprResult SecondResult(second.release());
+  ExprResult SecondResult(second.release());
   VarDecl *ConditionVar = 0;
-  if (secondVar.get()) {
-    ConditionVar = secondVar.getAs<VarDecl>();
+  if (secondVar) {
+    ConditionVar = cast<VarDecl>(secondVar);
     SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
     if (SecondResult.isInvalid())
       return StmtError();
   }
   
   Expr *Third  = third.release().takeAs<Expr>();
-  Stmt *Body  = static_cast<Stmt*>(body.get());
   
   DiagnoseUnusedExprResult(First);
   DiagnoseUnusedExprResult(Third);
   DiagnoseUnusedExprResult(Body);
 
-  first.release();
-  body.release();
   return Owned(new (Context) ForStmt(Context, First, 
-                                     SecondResult.takeAs<Expr>(), ConditionVar, 
+                                     SecondResult.take(), ConditionVar, 
                                      Third, Body, ForLoc, LParenLoc, 
                                      RParenLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
                                  SourceLocation LParenLoc,
-                                 StmtArg first, ExprArg second,
-                                 SourceLocation RParenLoc, StmtArg body) {
-  Stmt *First  = static_cast<Stmt*>(first.get());
-  Expr *Second = static_cast<Expr*>(second.get());
-  Stmt *Body  = static_cast<Stmt*>(body.get());
+                                 Stmt *First, Expr *Second,
+                                 SourceLocation RParenLoc, Stmt *Body) {
   if (First) {
     QualType FirstType;
     if (DeclStmt *DS = dyn_cast<DeclStmt>(First)) {
@@ -950,19 +914,39 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
     if (!SecondType->isObjCObjectPointerType())
       Diag(ForLoc, diag::err_collection_expr_type)
         << SecondType << Second->getSourceRange();
+    else if (const ObjCObjectPointerType *OPT =
+             SecondType->getAsObjCInterfacePointerType()) {
+      llvm::SmallVector<IdentifierInfo *, 4> KeyIdents;
+      IdentifierInfo* selIdent = 
+        &Context.Idents.get("countByEnumeratingWithState");
+      KeyIdents.push_back(selIdent);
+      selIdent = &Context.Idents.get("objects");
+      KeyIdents.push_back(selIdent);
+      selIdent = &Context.Idents.get("count");
+      KeyIdents.push_back(selIdent);
+      Selector CSelector = Context.Selectors.getSelector(3, &KeyIdents[0]);
+      if (ObjCInterfaceDecl *IDecl = OPT->getInterfaceDecl()) {
+        if (!IDecl->isForwardDecl() && 
+            !IDecl->lookupInstanceMethod(CSelector)) {
+          // Must further look into private implementation methods.
+          if (!LookupPrivateInstanceMethod(CSelector, IDecl))
+            Diag(ForLoc, diag::warn_collection_expr_type)
+              << SecondType << CSelector << Second->getSourceRange();
+        }
+      }
+    }
   }
-  first.release();
-  second.release();
-  body.release();
   return Owned(new (Context) ObjCForCollectionStmt(First, Second, Body,
                                                    ForLoc, RParenLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
                     IdentifierInfo *LabelII) {
   // Look up the record for this label identifier.
-  LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+  LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
+
+  getCurFunction()->setHasBranchIntoScope();
 
   // If we haven't seen this label yet, create a forward reference.
   if (LabelDecl == 0)
@@ -971,11 +955,10 @@ Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
   return Owned(new (Context) GotoStmt(LabelDecl, GotoLoc, LabelLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
-                            ExprArg DestExp) {
+                            Expr *E) {
   // Convert operand to void*
-  Expr* E = DestExp.takeAs<Expr>();
   if (!E->isTypeDependent()) {
     QualType ETy = E->getType();
     QualType DestTy = Context.getPointerType(Context.VoidTy.withConst());
@@ -984,10 +967,13 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
     if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
       return StmtError();
   }
+
+  getCurFunction()->setHasIndirectGoto();
+
   return Owned(new (Context) IndirectGotoStmt(GotoLoc, StarLoc, E));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
   Scope *S = CurScope->getContinueParent();
   if (!S) {
@@ -998,7 +984,7 @@ Sema::ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope) {
   return Owned(new (Context) ContinueStmt(ContinueLoc));
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
   Scope *S = CurScope->getBreakParent();
   if (!S) {
@@ -1050,7 +1036,7 @@ static const VarDecl *getNRVOCandidate(ASTContext &Ctx, QualType RetType,
 
 /// ActOnBlockReturnStmt - Utility routine to figure out block's return type.
 ///
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   // If this is the first return we've seen in the block, infer the type of
   // the block from it.
@@ -1086,7 +1072,6 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   if (CurBlock->ReturnType->isVoidType()) {
     if (RetValExp) {
       Diag(ReturnLoc, diag::err_return_block_has_expr);
-      RetValExp->Destroy(Context);
       RetValExp = 0;
     }
     Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
@@ -1105,7 +1090,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
       // In C++ the return statement is handled via a copy initialization.
       // the C version of which boils down to CheckSingleAssignmentConstraints.
       NRVOCandidate = getNRVOCandidate(Context, FnRetType, RetValExp);
-      OwningExprResult Res = PerformCopyInitialization(
+      ExprResult Res = PerformCopyInitialization(
                                InitializedEntity::InitializeResult(ReturnLoc, 
                                                                    FnRetType,
                                                             NRVOCandidate != 0),
@@ -1136,9 +1121,8 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   return Owned(Result);
 }
 
-Action::OwningStmtResult
-Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) {
-  Expr *RetValExp = rex.takeAs<Expr>();
+StmtResult
+Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
   if (getCurBlock())
     return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
 
@@ -1197,7 +1181,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprArg rex) {
       // In C++ the return statement is handled via a copy initialization.
       // the C version of which boils down to CheckSingleAssignmentConstraints.
       NRVOCandidate = getNRVOCandidate(Context, FnRetType, RetValExp);
-      OwningExprResult Res = PerformCopyInitialization(
+      ExprResult Res = PerformCopyInitialization(
                                InitializedEntity::InitializeResult(ReturnLoc, 
                                                                    FnRetType,
                                                             NRVOCandidate != 0),
@@ -1261,7 +1245,7 @@ static bool CheckAsmLValue(const Expr *E, Sema &S) {
 }
 
 
-Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
+StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
                                           bool IsSimple,
                                           bool IsVolatile,
                                           unsigned NumOutputs,
@@ -1269,15 +1253,15 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
                                           IdentifierInfo **Names,
                                           MultiExprArg constraints,
                                           MultiExprArg exprs,
-                                          ExprArg asmString,
+                                          Expr *asmString,
                                           MultiExprArg clobbers,
                                           SourceLocation RParenLoc,
                                           bool MSAsm) {
   unsigned NumClobbers = clobbers.size();
   StringLiteral **Constraints =
     reinterpret_cast<StringLiteral**>(constraints.get());
-  Expr **Exprs = reinterpret_cast<Expr **>(exprs.get());
-  StringLiteral *AsmString = cast<StringLiteral>((Expr *)asmString.get());
+  Expr **Exprs = exprs.get();
+  StringLiteral *AsmString = cast<StringLiteral>(asmString);
   StringLiteral **Clobbers = reinterpret_cast<StringLiteral**>(clobbers.get());
 
   llvm::SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
@@ -1373,10 +1357,6 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
                   diag::err_asm_unknown_register_name) << Clobber);
   }
 
-  constraints.release();
-  exprs.release();
-  asmString.release();
-  clobbers.release();
   AsmStmt *NS =
     new (Context) AsmStmt(Context, AsmLoc, IsSimple, IsVolatile, MSAsm, 
                           NumOutputs, NumInputs, Names, Constraints, Exprs, 
@@ -1388,7 +1368,6 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
   if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {
     Diag(getLocationOfStringLiteralByte(AsmString, DiagOffs), DiagID)
            << AsmString->getSourceRange();
-    DeleteStmt(NS);
     return StmtError();
   }
 
@@ -1479,45 +1458,41 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
          diag::err_asm_tying_incompatible_types)
       << InTy << OutTy << OutputExpr->getSourceRange()
       << InputExpr->getSourceRange();
-    DeleteStmt(NS);
     return StmtError();
   }
 
   return Owned(NS);
 }
 
-Action::OwningStmtResult
+StmtResult
 Sema::ActOnObjCAtCatchStmt(SourceLocation AtLoc,
-                           SourceLocation RParen, DeclPtrTy Parm,
-                           StmtArg Body) {
-  VarDecl *Var = cast_or_null<VarDecl>(Parm.getAs<Decl>());
+                           SourceLocation RParen, Decl *Parm,
+                           Stmt *Body) {
+  VarDecl *Var = cast_or_null<VarDecl>(Parm);
   if (Var && Var->isInvalidDecl())
     return StmtError();
   
-  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, 
-                                             Body.takeAs<Stmt>()));
+  return Owned(new (Context) ObjCAtCatchStmt(AtLoc, RParen, Var, Body));
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, StmtArg Body) {
-  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc,
-                                           static_cast<Stmt*>(Body.release())));
+StmtResult
+Sema::ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body) {
+  return Owned(new (Context) ObjCAtFinallyStmt(AtLoc, Body));
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, StmtArg Try, 
-                         MultiStmtArg CatchStmts, StmtArg Finally) {
-  FunctionNeedsScopeChecking() = true;
+StmtResult
+Sema::ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, 
+                         MultiStmtArg CatchStmts, Stmt *Finally) {
+  getCurFunction()->setHasBranchProtectedScope();
   unsigned NumCatchStmts = CatchStmts.size();
-  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try.takeAs<Stmt>(),
-                                     (Stmt **)CatchStmts.release(),
+  return Owned(ObjCAtTryStmt::Create(Context, AtLoc, Try,
+                                     CatchStmts.release(),
                                      NumCatchStmts,
-                                     Finally.takeAs<Stmt>()));
+                                     Finally));
 }
 
-Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
-                                                  ExprArg ThrowE) {
-  Expr *Throw = static_cast<Expr *>(ThrowE.get());
+StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                                  Expr *Throw) {
   if (Throw) {
     QualType ThrowType = Throw->getType();
     // Make sure the expression type is an ObjC pointer or "void *".
@@ -1530,13 +1505,13 @@ Sema::OwningStmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc,
     }
   }
   
-  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, ThrowE.takeAs<Expr>()));
+  return Owned(new (Context) ObjCAtThrowStmt(AtLoc, Throw));
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw, 
+StmtResult
+Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw, 
                            Scope *CurScope) {
-  if (!Throw.get()) {
+  if (!Throw) {
     // @throw without an expression designates a rethrow (which much occur
     // in the context of an @catch clause).
     Scope *AtCatchParent = CurScope;
@@ -1546,16 +1521,15 @@ Sema::ActOnObjCAtThrowStmt(SourceLocation AtLoc, ExprArg Throw,
       return StmtError(Diag(AtLoc, diag::error_rethrow_used_outside_catch));
   } 
   
-  return BuildObjCAtThrowStmt(AtLoc, move(Throw));
+  return BuildObjCAtThrowStmt(AtLoc, Throw);
 }
 
-Action::OwningStmtResult
-Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
-                                  StmtArg SynchBody) {
-  FunctionNeedsScopeChecking() = true;
+StmtResult
+Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SyncExpr,
+                                  Stmt *SyncBody) {
+  getCurFunction()->setHasBranchProtectedScope();
 
   // Make sure the expression type is an ObjC pointer or "void *".
-  Expr *SyncExpr = static_cast<Expr*>(SynchExpr.get());
   if (!SyncExpr->getType()->isDependentType() &&
       !SyncExpr->getType()->isObjCObjectPointerType()) {
     const PointerType *PT = SyncExpr->getType()->getAs<PointerType>();
@@ -1564,22 +1538,22 @@ Sema::ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, ExprArg SynchExpr,
                        << SyncExpr->getType() << SyncExpr->getSourceRange());
   }
 
-  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc,
-                                                    SynchExpr.takeAs<Stmt>(),
-                                                    SynchBody.takeAs<Stmt>()));
+  return Owned(new (Context) ObjCAtSynchronizedStmt(AtLoc, SyncExpr, SyncBody));
 }
 
 /// ActOnCXXCatchBlock - Takes an exception declaration and a handler block
 /// and creates a proper catch handler from them.
-Action::OwningStmtResult
-Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, DeclPtrTy ExDecl,
-                         StmtArg HandlerBlock) {
+StmtResult
+Sema::ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl,
+                         Stmt *HandlerBlock) {
   // There's nothing to test that ActOnExceptionDecl didn't already test.
   return Owned(new (Context) CXXCatchStmt(CatchLoc,
-                                  cast_or_null<VarDecl>(ExDecl.getAs<Decl>()),
-                                          HandlerBlock.takeAs<Stmt>()));
+                                          cast_or_null<VarDecl>(ExDecl),
+                                          HandlerBlock));
 }
 
+namespace {
+
 class TypeWithHandler {
   QualType t;
   CXXCatchStmt *stmt;
@@ -1602,22 +1576,23 @@ public:
     return t == other.t;
   }
 
-  QualType getQualType() const { return t; }
   CXXCatchStmt *getCatchStmt() const { return stmt; }
   SourceLocation getTypeSpecStartLoc() const {
     return stmt->getExceptionDecl()->getTypeSpecStartLoc();
   }
 };
 
+}
+
 /// ActOnCXXTryBlock - Takes a try compound-statement and a number of
 /// handlers and creates a try statement from them.
-Action::OwningStmtResult
-Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
+StmtResult
+Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
                        MultiStmtArg RawHandlers) {
   unsigned NumHandlers = RawHandlers.size();
   assert(NumHandlers > 0 &&
          "The parser shouldn't call this if there are no handlers.");
-  Stmt **Handlers = reinterpret_cast<Stmt**>(RawHandlers.get());
+  Stmt **Handlers = RawHandlers.get();
 
   llvm::SmallVector<TypeWithHandler, 8> TypesWithHandlers;
 
@@ -1657,15 +1632,14 @@ Sema::ActOnCXXTryBlock(SourceLocation TryLoc, StmtArg TryBlock,
     }
   }
 
+  getCurFunction()->setHasBranchProtectedScope();
+
   // FIXME: We should detect handlers that cannot catch anything because an
   // earlier handler catches a superclass. Need to find a method that is not
   // quadratic for this.
   // Neither of these are explicitly forbidden, but every compiler detects them
   // and warns.
 
-  FunctionNeedsScopeChecking() = true;
-  RawHandlers.release();
-  return Owned(CXXTryStmt::Create(Context, TryLoc,
-                                  static_cast<Stmt*>(TryBlock.release()),
+  return Owned(CXXTryStmt::Create(Context, TryLoc, TryBlock,
                                   Handlers, NumHandlers));
 }
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index f121954..0fc8392 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -9,20 +9,24 @@
 //  This file implements semantic analysis for C++ templates.
 //===----------------------------------------------------------------------===/
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "TreeTransform.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/ParsedTemplate.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace clang;
+using namespace sema;
 
 /// \brief Determine whether the declaration found is acceptable as the name
 /// of a template and, if so, return that template declaration. Otherwise,
@@ -88,8 +92,13 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
           filter.erase();
           continue;
         }
-          
-      filter.replace(Repl);
+
+      // FIXME: we promote access to public here as a workaround to
+      // the fact that LookupResult doesn't let us remember that we
+      // found this template through a particular injected class name,
+      // which means we end up doing nasty things to the invariants.
+      // Pretending that access is public is *much* safer.
+      filter.replace(Repl, AS_public);
     }
   }
   filter.done();
@@ -97,8 +106,9 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
 
 TemplateNameKind Sema::isTemplateName(Scope *S,
                                       CXXScopeSpec &SS,
+                                      bool hasTemplateKeyword,
                                       UnqualifiedId &Name,
-                                      TypeTy *ObjectTypePtr,
+                                      ParsedType ObjectTypePtr,
                                       bool EnteringContext,
                                       TemplateTy &TemplateResult,
                                       bool &MemberOfUnknownSpecialization) {
@@ -125,15 +135,21 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
     return TNK_Non_template;
   }
 
-  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  QualType ObjectType = ObjectTypePtr.get();
 
   LookupResult R(*this, TName, Name.getSourceRange().getBegin(), 
                  LookupOrdinaryName);
-  R.suppressDiagnostics();
   LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
                      MemberOfUnknownSpecialization);
-  if (R.empty() || R.isAmbiguous())
+  if (R.empty()) return TNK_Non_template;
+  if (R.isAmbiguous()) {
+    // Suppress diagnostics;  we'll redo this lookup later.
+    R.suppressDiagnostics();
+
+    // FIXME: we might have ambiguous templates, in which case we
+    // should at least parse them properly!
     return TNK_Non_template;
+  }
 
   TemplateName Template;
   TemplateNameKind TemplateKind;
@@ -144,20 +160,27 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
     // template name in other ways.
     Template = Context.getOverloadedTemplateName(R.begin(), R.end());
     TemplateKind = TNK_Function_template;
+
+    // We'll do this lookup again later.
+    R.suppressDiagnostics();
   } else {
     TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
 
     if (SS.isSet() && !SS.isInvalid()) {
       NestedNameSpecifier *Qualifier
         = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
-      Template = Context.getQualifiedTemplateName(Qualifier, false, TD);
+      Template = Context.getQualifiedTemplateName(Qualifier,
+                                                  hasTemplateKeyword, TD);
     } else {
       Template = TemplateName(TD);
     }
 
-    if (isa<FunctionTemplateDecl>(TD))
+    if (isa<FunctionTemplateDecl>(TD)) {
       TemplateKind = TNK_Function_template;
-    else {
+
+      // We'll do this lookup again later.
+      R.suppressDiagnostics();
+    } else {
       assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD));
       TemplateKind = TNK_Type_template;
     }
@@ -238,13 +261,10 @@ void Sema::LookupTemplateName(LookupResult &Found,
       //   expression. If the identifier is not found, it is then looked up in
       //   the context of the entire postfix-expression and shall name a class
       //   or function template.
-      //
-      // FIXME: When we're instantiating a template, do we actually have to
-      // look in the scope of the template? Seems fishy...
       if (S) LookupName(Found, S);
       ObjectTypeSearchedInScope = true;
     }
-  } else if (isDependent) {
+  } else if (isDependent && (!S || ObjectType.isNull())) {
     // We cannot look into a dependent object type or nested nme
     // specifier.
     MemberOfUnknownSpecialization = true;
@@ -282,8 +302,11 @@ void Sema::LookupTemplateName(LookupResult &Found,
   }
 
   FilterAcceptableTemplateNames(Context, Found);
-  if (Found.empty())
+  if (Found.empty()) {
+    if (isDependent)
+      MemberOfUnknownSpecialization = true;
     return;
+  }
 
   if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope) {
     // C++ [basic.lookup.classref]p1:
@@ -330,10 +353,9 @@ void Sema::LookupTemplateName(LookupResult &Found,
 /// ActOnDependentIdExpression - Handle a dependent id-expression that
 /// was just parsed.  This is only possible with an explicit scope
 /// specifier naming a dependent type.
-Sema::OwningExprResult
+ExprResult
 Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
-                                 DeclarationName Name,
-                                 SourceLocation NameLoc,
+                                 const DeclarationNameInfo &NameInfo,
                                  bool isAddressOfOperand,
                            const TemplateArgumentListInfo *TemplateArgs) {
   NestedNameSpecifier *Qualifier
@@ -356,22 +378,21 @@ Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
                                                      /*Op*/ SourceLocation(),
                                                      Qualifier, SS.getRange(),
                                                      FirstQualifierInScope,
-                                                     Name, NameLoc,
+                                                     NameInfo,
                                                      TemplateArgs));
   }
 
-  return BuildDependentDeclRefExpr(SS, Name, NameLoc, TemplateArgs);
+  return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs);
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
-                                DeclarationName Name,
-                                SourceLocation NameLoc,
+                                const DeclarationNameInfo &NameInfo,
                                 const TemplateArgumentListInfo *TemplateArgs) {
   return Owned(DependentScopeDeclRefExpr::Create(Context,
                static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
                                                  SS.getRange(),
-                                                 Name, NameLoc,
+                                                 NameInfo,
                                                  TemplateArgs));
 }
 
@@ -398,9 +419,9 @@ bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
 /// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
 /// the parameter D to reference the templated declaration and return a pointer
 /// to the template declaration. Otherwise, do nothing to D and return null.
-TemplateDecl *Sema::AdjustDeclIfTemplate(DeclPtrTy &D) {
-  if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D.getAs<Decl>())) {
-    D = DeclPtrTy::make(Temp->getTemplatedDecl());
+TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
+  if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D)) {
+    D = Temp->getTemplatedDecl();
     return Temp;
   }
   return 0;
@@ -424,8 +445,7 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
   }
     
   case ParsedTemplateArgument::Template: {
-    TemplateName Template
-      = TemplateName::getFromVoidPointer(Arg.getAsTemplate().get());
+    TemplateName Template = Arg.getAsTemplate().get();
     return TemplateArgumentLoc(TemplateArgument(Template),
                                Arg.getScopeSpec().getRange(),
                                Arg.getLocation());
@@ -454,14 +474,14 @@ void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
 /// ParamName is the location of the parameter name (if any).
 /// If the type parameter has a default argument, it will be added
 /// later via ActOnTypeParameterDefault.
-Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
-                                         SourceLocation EllipsisLoc,
-                                         SourceLocation KeyLoc,
-                                         IdentifierInfo *ParamName,
-                                         SourceLocation ParamNameLoc,
-                                         unsigned Depth, unsigned Position,
-                                         SourceLocation EqualLoc,
-                                         TypeTy *DefaultArg) {
+Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
+                               SourceLocation EllipsisLoc,
+                               SourceLocation KeyLoc,
+                               IdentifierInfo *ParamName,
+                               SourceLocation ParamNameLoc,
+                               unsigned Depth, unsigned Position,
+                               SourceLocation EqualLoc,
+                               ParsedType DefaultArg) {
   assert(S->isTemplateParamScope() &&
          "Template type parameter not in template parameter scope!");
   bool Invalid = false;
@@ -488,7 +508,7 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
 
   if (ParamName) {
     // Add the template parameter into the current scope.
-    S->AddDecl(DeclPtrTy::make(Param));
+    S->AddDecl(Param);
     IdResolver.AddDecl(Param);
   }
 
@@ -504,19 +524,19 @@ Sema::DeclPtrTy Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
     // template-parameter that is not a template parameter pack.
     if (Ellipsis) {
       Diag(EqualLoc, diag::err_template_param_pack_default_arg);
-      return DeclPtrTy::make(Param);
+      return Param;
     }
     
     // Check the template argument itself.
     if (CheckTemplateArgument(Param, DefaultTInfo)) {
       Param->setInvalidDecl();
-      return DeclPtrTy::make(Param);;
+      return Param;
     }
     
     Param->setDefaultArgument(DefaultTInfo, false);
   }
   
-  return DeclPtrTy::make(Param);
+  return Param;
 }
 
 /// \brief Check that the type of a non-type template parameter is
@@ -542,9 +562,7 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
   //       -- integral or enumeration type,
   if (T->isIntegralOrEnumerationType() ||
       //   -- pointer to object or pointer to function,
-      (T->isPointerType() &&
-       (T->getAs<PointerType>()->getPointeeType()->isObjectType() ||
-        T->getAs<PointerType>()->getPointeeType()->isFunctionType())) ||
+      T->isPointerType() ||
       //   -- reference to object or reference to function,
       T->isReferenceType() ||
       //   -- pointer to member.
@@ -571,11 +589,11 @@ Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
   return QualType();
 }
 
-Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
-                                                    unsigned Depth,
-                                                    unsigned Position,
-                                                    SourceLocation EqualLoc,
-                                                    ExprArg DefaultArg) {
+Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
+                                          unsigned Depth,
+                                          unsigned Position,
+                                          SourceLocation EqualLoc,
+                                          Expr *Default) {
   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
   QualType T = TInfo->getType();
 
@@ -608,35 +626,35 @@ Sema::DeclPtrTy Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
 
   if (D.getIdentifier()) {
     // Add the template parameter into the current scope.
-    S->AddDecl(DeclPtrTy::make(Param));
+    S->AddDecl(Param);
     IdResolver.AddDecl(Param);
   }
   
   // Check the well-formedness of the default template argument, if provided.
-  if (Expr *Default = static_cast<Expr *>(DefaultArg.get())) {  
+  if (Default) {  
     TemplateArgument Converted;
     if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) {
       Param->setInvalidDecl();
-      return DeclPtrTy::make(Param);;
+      return Param;
     }
   
-    Param->setDefaultArgument(DefaultArg.takeAs<Expr>(), false);
+    Param->setDefaultArgument(Default, false);
   }
   
-  return DeclPtrTy::make(Param);
+  return Param;
 }
 
 /// ActOnTemplateTemplateParameter - Called when a C++ template template
 /// parameter (e.g. T in template <template <typename> class T> class array)
 /// has been parsed. S is the current scope.
-Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
-                                                     SourceLocation TmpLoc,
-                                                     TemplateParamsTy *Params,
-                                                     IdentifierInfo *Name,
-                                                     SourceLocation NameLoc,
-                                                     unsigned Depth,
-                                                     unsigned Position,
-                                                     SourceLocation EqualLoc,
+Decl *Sema::ActOnTemplateTemplateParameter(Scope* S,
+                                           SourceLocation TmpLoc,
+                                           TemplateParamsTy *Params,
+                                           IdentifierInfo *Name,
+                                           SourceLocation NameLoc,
+                                           unsigned Depth,
+                                           unsigned Position,
+                                           SourceLocation EqualLoc,
                                        const ParsedTemplateArgument &Default) {
   assert(S->isTemplateParamScope() &&
          "Template template parameter not in template parameter scope!");
@@ -644,13 +662,14 @@ Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
   // Construct the parameter object.
   TemplateTemplateParmDecl *Param =
     TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
-                                     TmpLoc, Depth, Position, Name,
+                                     NameLoc.isInvalid()? TmpLoc : NameLoc, 
+                                     Depth, Position, Name,
                                      (TemplateParameterList*)Params);
 
   // If the template template parameter has a name, then link the identifier 
   // into the scope and lookup mechanisms.
   if (Name) {
-    S->AddDecl(DeclPtrTy::make(Param));
+    S->AddDecl(Param);
     IdResolver.AddDecl(Param);
   }
 
@@ -667,13 +686,13 @@ Sema::DeclPtrTy Sema::ActOnTemplateTemplateParameter(Scope* S,
     if (DefaultArg.getArgument().getAsTemplate().isNull()) {
       Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template)
         << DefaultArg.getSourceRange();
-      return DeclPtrTy::make(Param);
+      return Param;
     }
     
     Param->setDefaultArgument(DefaultArg, false);
   }
   
-  return DeclPtrTy::make(Param);
+  return Param;
 }
 
 /// ActOnTemplateParameterList - Builds a TemplateParameterList that
@@ -683,7 +702,7 @@ Sema::ActOnTemplateParameterList(unsigned Depth,
                                  SourceLocation ExportLoc,
                                  SourceLocation TemplateLoc,
                                  SourceLocation LAngleLoc,
-                                 DeclPtrTy *Params, unsigned NumParams,
+                                 Decl **Params, unsigned NumParams,
                                  SourceLocation RAngleLoc) {
   if (ExportLoc.isValid())
     Diag(ExportLoc, diag::warn_template_export_unsupported);
@@ -699,7 +718,7 @@ static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
                         SS.getRange());
 }
 
-Sema::DeclResult
+DeclResult
 Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
                          SourceLocation KWLoc, CXXScopeSpec &SS,
                          IdentifierInfo *Name, SourceLocation NameLoc,
@@ -922,7 +941,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
     
     // Friend templates are visible in fairly strange ways.
     if (!CurContext->isDependentContext()) {
-      DeclContext *DC = SemanticContext->getLookupContext();
+      DeclContext *DC = SemanticContext->getRedeclContext();
       DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false);
       if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
         PushOnScopeChains(NewTemplate, EnclosingScope,
@@ -941,7 +960,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
     NewTemplate->setInvalidDecl();
     NewClass->setInvalidDecl();
   }
-  return DeclPtrTy::make(NewTemplate);
+  return NewTemplate;
 }
 
 /// \brief Diagnose the presence of a default template argument on a
@@ -1102,7 +1121,6 @@ bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
           DiagnoseDefaultTemplateArgument(*this, TPC, 
                                           NewNonTypeParm->getLocation(), 
                     NewNonTypeParm->getDefaultArgument()->getSourceRange())) {
-        NewNonTypeParm->getDefaultArgument()->Destroy(Context);
         NewNonTypeParm->removeDefaultArgument();
       }
 
@@ -1477,14 +1495,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
                = dyn_cast<ClassTemplateDecl>(Template)) {
     // Find the class template specialization declaration that
     // corresponds to these arguments.
-    llvm::FoldingSetNodeID ID;
-    ClassTemplateSpecializationDecl::Profile(ID,
-                                             Converted.getFlatArguments(),
-                                             Converted.flatSize(),
-                                             Context);
     void *InsertPos = 0;
     ClassTemplateSpecializationDecl *Decl
-      = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+                                          Converted.flatSize(), InsertPos);
     if (!Decl) {
       // This is the first time we have referenced this class template
       // specialization. Create the canonical declaration and add it to
@@ -1495,7 +1509,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
                                                 ClassTemplate->getLocation(),
                                                 ClassTemplate,
                                                 Converted, 0);
-      ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
+      ClassTemplate->AddSpecialization(Decl, InsertPos);
       Decl->setLexicalDeclContext(CurContext);
     }
 
@@ -1510,7 +1524,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
   return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
 }
 
-Action::TypeResult
+TypeResult
 Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
                           SourceLocation LAngleLoc,
                           ASTTemplateArgsPtr TemplateArgsIn,
@@ -1536,15 +1550,15 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
   for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
     TL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
 
-  return CreateLocInfoType(Result, DI).getAsOpaquePtr();
+  return CreateParsedType(Result, DI);
 }
 
-Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
-                                              TagUseKind TUK,
-                                              DeclSpec::TST TagSpec,
-                                              SourceLocation TagLoc) {
+TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
+                                        TagUseKind TUK,
+                                        TypeSpecifierType TagSpec,
+                                        SourceLocation TagLoc) {
   if (TypeResult.isInvalid())
-    return Sema::TypeResult();
+    return ::TypeResult();
 
   // FIXME: preserve source info, ideally without copying the DI.
   TypeSourceInfo *DI;
@@ -1571,10 +1585,10 @@ Sema::TypeResult Sema::ActOnTagTemplateIdType(TypeResult TypeResult,
     = TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
   QualType ElabType = Context.getElaboratedType(Keyword, /*NNS=*/0, Type);
 
-  return ElabType.getAsOpaquePtr();
+  return ParsedType::make(ElabType);
 }
 
-Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
+ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
                                                  LookupResult &R,
                                                  bool RequiresADL,
                                  const TemplateArgumentListInfo &TemplateArgs) {
@@ -1603,7 +1617,7 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
   UnresolvedLookupExpr *ULE
     = UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
                                    Qualifier, QualifierRange,
-                                   R.getLookupName(), R.getNameLoc(),
+                                   R.getLookupNameInfo(),
                                    RequiresADL, TemplateArgs, 
                                    R.begin(), R.end());
 
@@ -1611,19 +1625,18 @@ Sema::OwningExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
 }
 
 // We actually only call this from template instantiation.
-Sema::OwningExprResult
+ExprResult
 Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
-                                   DeclarationName Name,
-                                   SourceLocation NameLoc,
+                                   const DeclarationNameInfo &NameInfo,
                              const TemplateArgumentListInfo &TemplateArgs) {
   DeclContext *DC;
   if (!(DC = computeDeclContext(SS, false)) ||
       DC->isDependentContext() ||
       RequireCompleteDeclContext(SS, DC))
-    return BuildDependentDeclRefExpr(SS, Name, NameLoc, &TemplateArgs);
+    return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs);
 
   bool MemberOfUnknownSpecialization;
-  LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+  LookupResult R(*this, NameInfo, LookupOrdinaryName);
   LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false,
                      MemberOfUnknownSpecialization);
 
@@ -1631,14 +1644,15 @@ Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
     return ExprError();
   
   if (R.empty()) {
-    Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
-      << Name << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template)
+      << NameInfo.getName() << SS.getRange();
     return ExprError();
   }
 
   if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
-    Diag(NameLoc, diag::err_template_kw_refers_to_class_template)
-      << (NestedNameSpecifier*) SS.getScopeRep() << Name << SS.getRange();
+    Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
+      << (NestedNameSpecifier*) SS.getScopeRep()
+      << NameInfo.getName() << SS.getRange();
     Diag(Temp->getLocation(), diag::note_referenced_class_template);
     return ExprError();
   }
@@ -1657,7 +1671,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
                                                   SourceLocation TemplateKWLoc,
                                                   CXXScopeSpec &SS,
                                                   UnqualifiedId &Name,
-                                                  TypeTy *ObjectType,
+                                                  ParsedType ObjectType,
                                                   bool EnteringContext,
                                                   TemplateTy &Result) {
   if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() &&
@@ -1669,7 +1683,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
   if (SS.isSet())
     LookupCtx = computeDeclContext(SS, EnteringContext);
   if (!LookupCtx && ObjectType)
-    LookupCtx = computeDeclContext(QualType::getFromOpaquePtr(ObjectType));
+    LookupCtx = computeDeclContext(ObjectType.get());
   if (LookupCtx) {
     // C++0x [temp.names]p5:
     //   If a name prefixed by the keyword template is not the name of
@@ -1688,8 +1702,8 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
     // "template" keyword is now permitted). We follow the C++0x
     // rules, even in C++03 mode with a warning, retroactively applying the DR.
     bool MemberOfUnknownSpecialization;
-    TemplateNameKind TNK = isTemplateName(0, SS, Name, ObjectType,
-                                          EnteringContext, Result,
+    TemplateNameKind TNK = isTemplateName(0, SS, TemplateKWLoc.isValid(), Name,
+                                          ObjectType, EnteringContext, Result,
                                           MemberOfUnknownSpecialization);
     if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
         isa<CXXRecordDecl>(LookupCtx) &&
@@ -1698,7 +1712,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
     } else if (TNK == TNK_Non_template) {
       Diag(Name.getSourceRange().getBegin(), 
            diag::err_template_kw_refers_to_non_template)
-        << GetNameFromUnqualifiedId(Name)
+        << GetNameFromUnqualifiedId(Name).getName()
         << Name.getSourceRange()
         << TemplateKWLoc;
       return TNK_Non_template;
@@ -1731,7 +1745,7 @@ TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
   
   Diag(Name.getSourceRange().getBegin(), 
        diag::err_template_kw_refers_to_non_template)
-    << GetNameFromUnqualifiedId(Name)
+    << GetNameFromUnqualifiedId(Name).getName()
     << Name.getSourceRange()
     << TemplateKWLoc;
   return TNK_Non_template;
@@ -1856,7 +1870,7 @@ SubstDefaultTemplateArgument(Sema &SemaRef,
 /// parameters that precede \p Param in the template parameter list.
 ///
 /// \returns the substituted template argument, or NULL if an error occurred.
-static Sema::OwningExprResult
+static ExprResult
 SubstDefaultTemplateArgument(Sema &SemaRef,
                              TemplateDecl *Template,
                              SourceLocation TemplateLoc,
@@ -1952,7 +1966,7 @@ Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
     if (!NonTypeParm->hasDefaultArgument())
       return TemplateArgumentLoc();
 
-    OwningExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
+    ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
                                                         TemplateLoc,
                                                         RAngleLoc,
                                                         NonTypeParm,
@@ -2052,12 +2066,15 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param,
         // We have a template argument such as \c T::template X, which we
         // parsed as a template template argument. However, since we now
         // know that we need a non-type template argument, convert this
-        // template name into an expression.          
+        // template name into an expression.
+
+        DeclarationNameInfo NameInfo(DTN->getIdentifier(),
+                                     Arg.getTemplateNameLoc());
+
         Expr *E = DependentScopeDeclRefExpr::Create(Context,
                                                     DTN->getQualifier(),
                                                Arg.getTemplateQualifierRange(),
-                                                    DTN->getIdentifier(),
-                                                    Arg.getTemplateNameLoc());
+                                                    NameInfo);
         
         TemplateArgument Result;
         if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
@@ -2272,7 +2289,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
         break;
       }
 
-      Sema::OwningExprResult E = SubstDefaultTemplateArgument(*this, Template,
+      ExprResult E = SubstDefaultTemplateArgument(*this, Template,
                                                               TemplateLoc, 
                                                               RAngleLoc, 
                                                               NTTP, 
@@ -2330,31 +2347,33 @@ bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
   assert(ArgInfo && "invalid TypeSourceInfo");
   QualType Arg = ArgInfo->getType();
 
-  // C++ [temp.arg.type]p2:
+  // C++03 [temp.arg.type]p2:
   //   A local type, a type with no linkage, an unnamed type or a type
   //   compounded from any of these types shall not be used as a
   //   template-argument for a template type-parameter.
-  //
-  // FIXME: Perform the unnamed type check.
+  // C++0x allows these, and even in C++03 we allow them as an extension with
+  // a warning.
   SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
-  const TagType *Tag = 0;
-  if (const EnumType *EnumT = Arg->getAs<EnumType>())
-    Tag = EnumT;
-  else if (const RecordType *RecordT = Arg->getAs<RecordType>())
-    Tag = RecordT;
-  if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
-    SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
-    return Diag(SR.getBegin(), diag::err_template_arg_local_type)
-      << QualType(Tag, 0) << SR;
-  } else if (Tag && !Tag->getDecl()->getDeclName() &&
-           !Tag->getDecl()->getTypedefForAnonDecl()) {
-    Diag(SR.getBegin(), diag::err_template_arg_unnamed_type) << SR;
-    Diag(Tag->getDecl()->getLocation(), diag::note_template_unnamed_type_here);
-    return true;
-  } else if (Arg->isVariablyModifiedType()) {
-    Diag(SR.getBegin(), diag::err_variably_modified_template_arg)
-      << Arg;
-    return true;
+  if (!LangOpts.CPlusPlus0x) {
+    const TagType *Tag = 0;
+    if (const EnumType *EnumT = Arg->getAs<EnumType>())
+      Tag = EnumT;
+    else if (const RecordType *RecordT = Arg->getAs<RecordType>())
+      Tag = RecordT;
+    if (Tag && Tag->getDecl()->getDeclContext()->isFunctionOrMethod()) {
+      SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
+      Diag(SR.getBegin(), diag::ext_template_arg_local_type)
+        << QualType(Tag, 0) << SR;
+    } else if (Tag && !Tag->getDecl()->getDeclName() &&
+               !Tag->getDecl()->getTypedefForAnonDecl()) {
+      Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR;
+      Diag(Tag->getDecl()->getLocation(),
+           diag::note_template_unnamed_type_here);
+    }
+  }
+
+  if (Arg->isVariablyModifiedType()) {
+    return Diag(SR.getBegin(), diag::err_variably_modified_template_arg) << Arg;
   } else if (Context.hasSameUnqualifiedType(Arg, Context.OverloadTy)) {
     return Diag(SR.getBegin(), diag::err_template_arg_overload_type) << SR;
   }
@@ -2406,7 +2425,7 @@ CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
   bool AddressTaken = false;
   SourceLocation AddrOpLoc;
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
-    if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+    if (UnOp->getOpcode() == UO_AddrOf) {
       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
       AddressTaken = true;
       AddrOpLoc = UnOp->getOperatorLoc();
@@ -2653,7 +2672,7 @@ bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
 
   // A pointer-to-member constant written &Class::member.
   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
-    if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
+    if (UnOp->getOpcode() == UO_AddrOf) {
       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
       if (DRE && !DRE->getQualifier())
         DRE = 0;
@@ -2788,7 +2807,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     } else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
                !ParamType->isEnumeralType()) {
       // This is an integral promotion or conversion.
-      ImpCastExprToType(Arg, ParamType, CastExpr::CK_IntegralCast);
+      ImpCastExprToType(Arg, ParamType, CK_IntegralCast);
     } else {
       // We can't perform this conversion.
       Diag(Arg->getSourceRange().getBegin(),
@@ -2909,8 +2928,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
                                                             Arg, Converted);
 
     if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType())) {
-      ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
-                        Arg->isLvalue(Context) == Expr::LV_Valid);
+      ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
     } else if (!Context.hasSameUnqualifiedType(ArgType,
                                            ParamType.getNonReferenceType())) {
       // We can't perform this conversion.
@@ -2929,7 +2947,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     //      object, qualification conversions (4.4) and the
     //      array-to-pointer conversion (4.2) are applied.
     // C++0x also allows a value of std::nullptr_t.
-    assert(ParamType->getAs<PointerType>()->getPointeeType()->isObjectType() &&
+    assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
            "Only object pointers allowed here");
 
     return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, 
@@ -2944,7 +2962,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
     //      identical) type of the template-argument. The
     //      template-parameter is bound directly to the
     //      template-argument, which must be an lvalue.
-    assert(ParamRefType->getPointeeType()->isObjectType() &&
+    assert(ParamRefType->getPointeeType()->isIncompleteOrObjectType() &&
            "Only object references allowed here");
 
     if (Arg->getType() == Context.OverloadTy) {
@@ -2973,8 +2991,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
   if (Context.hasSameUnqualifiedType(ParamType, ArgType)) {
     // Types match exactly: nothing more to do here.
   } else if (IsQualificationConversion(ArgType, ParamType)) {
-    ImpCastExprToType(Arg, ParamType, CastExpr::CK_NoOp,
-                      Arg->isLvalue(Context) == Expr::LV_Valid);
+    ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg));
   } else {
     // We can't perform this conversion.
     Diag(Arg->getSourceRange().getBegin(),
@@ -3033,7 +3050,7 @@ bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
 /// declaration and the type of its corresponding non-type template
 /// parameter, produce an expression that properly refers to that
 /// declaration.
-Sema::OwningExprResult 
+ExprResult 
 Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
                                               QualType ParamType,
                                               SourceLocation Loc) {
@@ -3052,17 +3069,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
       QualType ClassType
         = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
       NestedNameSpecifier *Qualifier
-        = NestedNameSpecifier::Create(Context, 0, false, ClassType.getTypePtr());
+        = NestedNameSpecifier::Create(Context, 0, false,
+                                      ClassType.getTypePtr());
       CXXScopeSpec SS;
       SS.setScopeRep(Qualifier);
-      OwningExprResult RefExpr = BuildDeclRefExpr(VD, 
+      ExprResult RefExpr = BuildDeclRefExpr(VD, 
                                            VD->getType().getNonReferenceType(), 
                                                   Loc,
                                                   &SS);
       if (RefExpr.isInvalid())
         return ExprError();
       
-      RefExpr = CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+      RefExpr = CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
       
       // We might need to perform a trailing qualification conversion, since
       // the element type on the parameter could be more qualified than the
@@ -3070,8 +3088,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
       if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
                                     ParamType.getUnqualifiedType())) {
         Expr *RefE = RefExpr.takeAs<Expr>();
-        ImpCastExprToType(RefE, ParamType.getUnqualifiedType(),
-                          CastExpr::CK_NoOp);
+        ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp);
         RefExpr = Owned(RefE);
       }
       
@@ -3086,7 +3103,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
   if (ParamType->isPointerType()) {
     // When the non-type template parameter is a pointer, take the
     // address of the declaration.
-    OwningExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
+    ExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc);
     if (RefExpr.isInvalid())
       return ExprError();
 
@@ -3103,7 +3120,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
     }
     
     // Take the address of everything else
-    return CreateBuiltinUnaryOp(Loc, UnaryOperator::AddrOf, move(RefExpr));
+    return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
   }
 
   // If the non-type template parameter has reference type, qualify the
@@ -3122,7 +3139,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
 /// This routine takes care of the mapping from an integral template
 /// argument (which may have any integral type) to the appropriate
 /// literal value.
-Sema::OwningExprResult 
+ExprResult 
 Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
                                                   SourceLocation Loc) {
   assert(Arg.getKind() == TemplateArgument::Integral &&
@@ -3140,7 +3157,7 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
                                             T,
                                             Loc));
 
-  return Owned(new (Context) IntegerLiteral(*Arg.getAsIntegral(), T, Loc));
+  return Owned(IntegerLiteral::Create(Context, *Arg.getAsIntegral(), T, Loc));
 }
 
 
@@ -3401,7 +3418,7 @@ static bool CheckTemplateSpecializationScope(Sema &S,
   //   the explicit specialization was declared, or in a namespace
   //   that encloses the one in which the explicit specialization was
   //   declared.
-  if (S.CurContext->getLookupContext()->isFunctionOrMethod()) {
+  if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) {
     S.Diag(Loc, diag::err_template_spec_decl_function_scope)
       << Specialized;
     return true;
@@ -3426,8 +3443,8 @@ static bool CheckTemplateSpecializationScope(Sema &S,
        getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
     // There is no prior declaration of this entity, so this
     // specialization must be in the same context as the template
-    // itself.
-    if (!DC->Equals(SpecializedContext)) {
+    // itself, or in the enclosing namespace set.
+    if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
       if (isa<TranslationUnitDecl>(SpecializedContext))
         S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
         << EntityKind << Specialized;
@@ -3597,7 +3614,7 @@ static NamedDecl *getPreviousDecl(NamedDecl *ND) {
   return 0;
 }
 
-Sema::DeclResult
+DeclResult
 Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                                        TagUseKind TUK,
                                        SourceLocation KWLoc,
@@ -3666,7 +3683,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                diag::err_default_arg_in_partial_spec)
             << DefArg->getSourceRange();
           NTTP->removeDefaultArgument();
-          DefArg->Destroy(Context);
         }
       } else {
         TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
@@ -3729,7 +3745,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
 
   // Find the class template (partial) specialization declaration that
   // corresponds to these arguments.
-  llvm::FoldingSetNodeID ID;
   if (isPartialSpecialization) {
     bool MirrorsPrimaryTemplate;
     if (CheckClassTemplatePartialSpecializationArgs(
@@ -3762,30 +3777,22 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
       Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
         << ClassTemplate->getDeclName();
       isPartialSpecialization = false;
-    } else {
-      // FIXME: Template parameter list matters, too
-      ClassTemplatePartialSpecializationDecl::Profile(ID,
-                                                  Converted.getFlatArguments(),
-                                                      Converted.flatSize(),
-                                                      Context);
     }
   }
-  
-  if (!isPartialSpecialization)
-    ClassTemplateSpecializationDecl::Profile(ID,
-                                             Converted.getFlatArguments(),
-                                             Converted.flatSize(),
-                                             Context);
+
   void *InsertPos = 0;
   ClassTemplateSpecializationDecl *PrevDecl = 0;
 
   if (isPartialSpecialization)
+    // FIXME: Template parameter list matters, too
     PrevDecl
-      = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
-                                                                    InsertPos);
+      = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+                                                 Converted.flatSize(),
+                                                 InsertPos);
   else
     PrevDecl
-      = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+      = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+                                          Converted.flatSize(), InsertPos);
 
   ClassTemplateSpecializationDecl *Specialization = 0;
 
@@ -3823,7 +3830,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
     ClassTemplatePartialSpecializationDecl *PrevPartial
       = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
     unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber()
-                            : ClassTemplate->getPartialSpecializations().size();
+                            : ClassTemplate->getNextPartialSpecSequenceNumber();
     ClassTemplatePartialSpecializationDecl *Partial
       = ClassTemplatePartialSpecializationDecl::Create(Context, Kind,
                                              ClassTemplate->getDeclContext(),
@@ -3836,18 +3843,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                                                        PrevPartial,
                                                        SequenceNumber);
     SetNestedNameSpecifier(Partial, SS);
-    if (NumMatchedTemplateParamLists > 0) {
+    if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
       Partial->setTemplateParameterListsInfo(Context,
                                              NumMatchedTemplateParamLists,
                     (TemplateParameterList**) TemplateParameterLists.release());
     }
 
-    if (PrevPartial) {
-      ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
-      ClassTemplate->getPartialSpecializations().GetOrInsertNode(Partial);
-    } else {
-      ClassTemplate->getPartialSpecializations().InsertNode(Partial, InsertPos);
-    }
+    if (!PrevPartial)
+      ClassTemplate->AddPartialSpecialization(Partial, InsertPos);
     Specialization = Partial;
 
     // If we are providing an explicit specialization of a member class 
@@ -3883,7 +3886,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
           else
             Diag(Param->getLocation(),
                  diag::note_partial_spec_unused_parameter)
-              << std::string("<anonymous>");
+              << "<anonymous>";
         }
       }
     }
@@ -3898,19 +3901,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
                                                 Converted,
                                                 PrevDecl);
     SetNestedNameSpecifier(Specialization, SS);
-    if (NumMatchedTemplateParamLists > 0) {
+    if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
       Specialization->setTemplateParameterListsInfo(Context,
                                                   NumMatchedTemplateParamLists,
                     (TemplateParameterList**) TemplateParameterLists.release());
     }
 
-    if (PrevDecl) {
-      ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
-      ClassTemplate->getSpecializations().GetOrInsertNode(Specialization);
-    } else {
-      ClassTemplate->getSpecializations().InsertNode(Specialization,
-                                                     InsertPos);
-    }
+    if (!PrevDecl)
+      ClassTemplate->AddSpecialization(Specialization, InsertPos);
 
     CanonType = Context.getTypeDeclType(Specialization);
   }
@@ -4004,20 +4002,18 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
     // context. However, specializations are not found by name lookup.
     CurContext->addDecl(Specialization);
   }
-  return DeclPtrTy::make(Specialization);
+  return Specialization;
 }
 
-Sema::DeclPtrTy
-Sema::ActOnTemplateDeclarator(Scope *S,
+Decl *Sema::ActOnTemplateDeclarator(Scope *S,
                               MultiTemplateParamsArg TemplateParameterLists,
-                              Declarator &D) {
+                                    Declarator &D) {
   return HandleDeclarator(S, D, move(TemplateParameterLists), false);
 }
 
-Sema::DeclPtrTy
-Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
+Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
                                MultiTemplateParamsArg TemplateParameterLists,
-                                      Declarator &D) {
+                                            Declarator &D) {
   assert(getCurFunctionDecl() == 0 && "Function parsing confused");
   assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "Not a function declarator!");
@@ -4029,22 +4025,22 @@ Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
 
   Scope *ParentScope = FnBodyScope->getParent();
 
-  DeclPtrTy DP = HandleDeclarator(ParentScope, D,
-                                  move(TemplateParameterLists),
-                                  /*IsFunctionDefinition=*/true);
+  Decl *DP = HandleDeclarator(ParentScope, D,
+                              move(TemplateParameterLists),
+                              /*IsFunctionDefinition=*/true);
   if (FunctionTemplateDecl *FunctionTemplate
-        = dyn_cast_or_null<FunctionTemplateDecl>(DP.getAs<Decl>()))
+        = dyn_cast_or_null<FunctionTemplateDecl>(DP))
     return ActOnStartOfFunctionDef(FnBodyScope,
-                      DeclPtrTy::make(FunctionTemplate->getTemplatedDecl()));
-  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP.getAs<Decl>()))
-    return ActOnStartOfFunctionDef(FnBodyScope, DeclPtrTy::make(Function));
-  return DeclPtrTy();
+                                   FunctionTemplate->getTemplatedDecl());
+  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP))
+    return ActOnStartOfFunctionDef(FnBodyScope, Function);
+  return 0;
 }
 
 /// \brief Strips various properties off an implicit instantiation
 /// that has just been explicitly specialized.
 static void StripImplicitInstantiation(NamedDecl *D) {
-  D->invalidateAttrs();
+  D->dropAttrs();
 
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     FD->setInlineSpecified(false);
@@ -4241,12 +4237,13 @@ Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
                                                    LookupResult &Previous) {
   // Remove anything from Previous that isn't a function template in
   // the correct context.
-  DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
+  DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
   LookupResult::Filter F = Previous.makeFilter();
   while (F.hasNext()) {
     NamedDecl *D = F.next()->getUnderlyingDecl();
     if (!isa<FunctionTemplateDecl>(D) ||
-        !FDLookupContext->Equals(D->getDeclContext()->getLookupContext()))
+        !FDLookupContext->InEnclosingNamespaceSetOf(
+                              D->getDeclContext()->getRedeclContext()))
       F.erase();
   }
   F.done();
@@ -4285,14 +4282,15 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
   // explicit function template specialization.
   UnresolvedSet<8> Candidates;
   
-  DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
+  DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
   for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
          I != E; ++I) {
     NamedDecl *Ovl = (*I)->getUnderlyingDecl();
     if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
       // Only consider templates found within the same semantic lookup scope as 
       // FD.
-      if (!FDLookupContext->Equals(Ovl->getDeclContext()->getLookupContext()))
+      if (!FDLookupContext->InEnclosingNamespaceSetOf(
+                                Ovl->getDeclContext()->getRedeclContext()))
         continue;
       
       // C++ [temp.expl.spec]p11:
@@ -4373,8 +4371,10 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
   
   // Mark the prior declaration as an explicit specialization, so that later
   // clients know that this is an explicit specialization.
-  if (!isFriend)
+  if (!isFriend) {
     SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
+    MarkUnusedFileScopedDecl(Specialization);
+  }
   
   // Turn the given function declaration into a function template
   // specialization, with the template arguments from the previous
@@ -4527,6 +4527,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
     cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
                                         cast<CXXMethodDecl>(InstantiatedFrom),
                                                   TSK_ExplicitSpecialization);
+    MarkUnusedFileScopedDecl(InstantiationFunction);
   } else if (isa<VarDecl>(Member)) {
     VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
     if (InstantiationVar->getTemplateSpecializationKind() ==
@@ -4539,6 +4540,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
     Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
                                                 cast<VarDecl>(InstantiatedFrom),
                                                 TSK_ExplicitSpecialization);
+    MarkUnusedFileScopedDecl(InstantiationVar);
   } else {
     assert(isa<CXXRecordDecl>(Member) && "Only member classes remain");
     CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
@@ -4567,9 +4569,8 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
 static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
                                             SourceLocation InstLoc,
                                             bool WasQualifiedName) {
-  DeclContext *ExpectedContext
-    = D->getDeclContext()->getEnclosingNamespaceContext()->getLookupContext();
-  DeclContext *CurContext = S.CurContext->getLookupContext();
+  DeclContext *OrigContext= D->getDeclContext()->getEnclosingNamespaceContext();
+  DeclContext *CurContext = S.CurContext->getRedeclContext();
   
   if (CurContext->isRecord()) {
     S.Diag(InstLoc, diag::err_explicit_instantiation_in_class)
@@ -4583,8 +4584,8 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
   //
   // This is DR275, which we do not retroactively apply to C++98/03.
   if (S.getLangOptions().CPlusPlus0x && 
-      !CurContext->Encloses(ExpectedContext)) {
-    if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ExpectedContext))
+      !CurContext->Encloses(OrigContext)) {
+    if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext))
       S.Diag(InstLoc, 
              S.getLangOptions().CPlusPlus0x? 
                  diag::err_explicit_instantiation_out_of_scope
@@ -4599,7 +4600,7 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
     S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
     return false;
   }
-  
+
   // C++0x [temp.explicit]p2:
   //   If the name declared in the explicit instantiation is an unqualified 
   //   name, the explicit instantiation shall appear in the namespace where 
@@ -4607,15 +4608,15 @@ static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
   //   namespace from its enclosing namespace set.
   if (WasQualifiedName)
     return false;
-  
-  if (CurContext->Equals(ExpectedContext))
+
+  if (CurContext->InEnclosingNamespaceSetOf(OrigContext))
     return false;
-  
+
   S.Diag(InstLoc, 
          S.getLangOptions().CPlusPlus0x?
              diag::err_explicit_instantiation_unqualified_wrong_namespace
            : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
-    << D << ExpectedContext;
+    << D << OrigContext;
   S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
   return false;
 }
@@ -4642,7 +4643,7 @@ static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
 }
 
 // Explicit instantiation of a class template specialization
-Sema::DeclResult
+DeclResult
 Sema::ActOnExplicitInstantiation(Scope *S,
                                  SourceLocation ExternLoc,
                                  SourceLocation TemplateLoc,
@@ -4703,14 +4704,10 @@ Sema::ActOnExplicitInstantiation(Scope *S,
 
   // Find the class template specialization declaration that
   // corresponds to these arguments.
-  llvm::FoldingSetNodeID ID;
-  ClassTemplateSpecializationDecl::Profile(ID,
-                                           Converted.getFlatArguments(),
-                                           Converted.flatSize(),
-                                           Context);
   void *InsertPos = 0;
   ClassTemplateSpecializationDecl *PrevDecl
-    = ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
+    = ClassTemplate->findSpecialization(Converted.getFlatArguments(),
+                                        Converted.flatSize(), InsertPos);
 
   TemplateSpecializationKind PrevDecl_TSK
     = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
@@ -4733,7 +4730,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
                                                PrevDecl, PrevDecl_TSK,
                                             PrevDecl->getPointOfInstantiation(),
                                                HasNoEffect))
-      return DeclPtrTy::make(PrevDecl);
+      return PrevDecl;
 
     // Even though HasNoEffect == true means that this explicit instantiation
     // has no effect on semantics, we go on to put its syntax in the AST.
@@ -4763,15 +4760,9 @@ Sema::ActOnExplicitInstantiation(Scope *S,
                                                 Converted, PrevDecl);
     SetNestedNameSpecifier(Specialization, SS);
 
-    if (!HasNoEffect) {
-      if (PrevDecl) {
-        // Remove the previous declaration from the folding set, since we want
-        // to introduce a new declaration.
-        ClassTemplate->getSpecializations().RemoveNode(PrevDecl);
-        ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
-      }
+    if (!HasNoEffect && !PrevDecl) {
       // Insert the new specialization.
-      ClassTemplate->getSpecializations().InsertNode(Specialization, InsertPos);
+      ClassTemplate->AddSpecialization(Specialization, InsertPos);
     }
   }
 
@@ -4803,7 +4794,7 @@ Sema::ActOnExplicitInstantiation(Scope *S,
   if (HasNoEffect) {
     // Set the template specialization kind.
     Specialization->setTemplateSpecializationKind(TSK);
-    return DeclPtrTy::make(Specialization);
+    return Specialization;
   }
 
   // C++ [temp.explicit]p3:
@@ -4840,11 +4831,11 @@ Sema::ActOnExplicitInstantiation(Scope *S,
 
   // Set the template specialization kind.
   Specialization->setTemplateSpecializationKind(TSK);
-  return DeclPtrTy::make(Specialization);
+  return Specialization;
 }
 
 // Explicit instantiation of a member class of a class template.
-Sema::DeclResult
+DeclResult
 Sema::ActOnExplicitInstantiation(Scope *S,
                                  SourceLocation ExternLoc,
                                  SourceLocation TemplateLoc,
@@ -4857,16 +4848,16 @@ Sema::ActOnExplicitInstantiation(Scope *S,
 
   bool Owned = false;
   bool IsDependent = false;
-  DeclPtrTy TagD = ActOnTag(S, TagSpec, Action::TUK_Reference,
-                            KWLoc, SS, Name, NameLoc, Attr, AS_none,
-                            MultiTemplateParamsArg(*this, 0, 0),
-                            Owned, IsDependent);
+  Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
+                        KWLoc, SS, Name, NameLoc, Attr, AS_none,
+                        MultiTemplateParamsArg(*this, 0, 0),
+                        Owned, IsDependent);
   assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
 
   if (!TagD)
     return true;
 
-  TagDecl *Tag = cast<TagDecl>(TagD.getAs<Decl>());
+  TagDecl *Tag = cast<TagDecl>(TagD);
   if (Tag->isEnum()) {
     Diag(TemplateLoc, diag::err_explicit_instantiation_enum)
       << Context.getTypeDeclType(Tag);
@@ -4969,12 +4960,14 @@ Sema::ActOnExplicitInstantiation(Scope *S,
   return TagD;
 }
 
-Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
-                                                  SourceLocation ExternLoc,
-                                                  SourceLocation TemplateLoc,
-                                                  Declarator &D) {
+DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
+                                            SourceLocation ExternLoc,
+                                            SourceLocation TemplateLoc,
+                                            Declarator &D) {
   // Explicit instantiations always require a name.
-  DeclarationName Name = GetNameForDeclarator(D);
+  // TODO: check if/when DNInfo should replace Name.
+  DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
+  DeclarationName Name = NameInfo.getName();
   if (!Name) {
     if (!D.isInvalidType())
       Diag(D.getDeclSpec().getSourceRange().getBegin(),
@@ -5024,7 +5017,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
                            : TSK_ExplicitInstantiationDeclaration;
     
-  LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName);
+  LookupResult Previous(*this, NameInfo, LookupOrdinaryName);
   LookupParsedName(Previous, S, &D.getCXXScopeSpec());
 
   if (!R->isFunctionType()) {
@@ -5081,16 +5074,15 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
                                                HasNoEffect))
       return true;
     if (HasNoEffect)
-      return DeclPtrTy();
+      return (Decl*) 0;
     
     // Instantiate static data member.
     Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
     if (TSK == TSK_ExplicitInstantiationDefinition)
-      InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false,
-                                            /*DefinitionRequired=*/true);
+      InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev);
     
     // FIXME: Create an ExplicitInstantiation node?
-    return DeclPtrTy();
+    return (Decl*) 0;
   }
   
   // If the declarator is a template-id, translate the parser's template 
@@ -5188,14 +5180,13 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
     // FIXME: We may still want to build some representation of this
     // explicit specialization.
     if (HasNoEffect)
-      return DeclPtrTy();
+      return (Decl*) 0;
   }
 
   Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
   
   if (TSK == TSK_ExplicitInstantiationDefinition)
-    InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization, 
-                                  false, /*DefinitionRequired=*/true);
+    InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
  
   // C++0x [temp.explicit]p2:
   //   If the explicit instantiation is for a member function, a member class 
@@ -5219,10 +5210,10 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
                                   D.getCXXScopeSpec().isSet());
   
   // FIXME: Create some kind of ExplicitInstantiationDecl here.
-  return DeclPtrTy();
+  return (Decl*) 0;
 }
 
-Sema::TypeResult
+TypeResult
 Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
                         const CXXScopeSpec &SS, IdentifierInfo *Name,
                         SourceLocation TagLoc, SourceLocation NameLoc) {
@@ -5243,10 +5234,10 @@ Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
   }
 
   ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
-  return Context.getDependentNameType(Kwd, NNS, Name).getAsOpaquePtr();
+  return ParsedType::make(Context.getDependentNameType(Kwd, NNS, Name));
 }
 
-Sema::TypeResult
+TypeResult
 Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
                         const CXXScopeSpec &SS, const IdentifierInfo &II, 
                         SourceLocation IdLoc) {
@@ -5278,13 +5269,13 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
     cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
   }
   
-  return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+  return CreateParsedType(T, TSI);
 }
 
-Sema::TypeResult
+TypeResult
 Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, 
                         const CXXScopeSpec &SS, SourceLocation TemplateLoc, 
-                        TypeTy *Ty) {
+                        ParsedType Ty) {
   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() &&
       !getLangOptions().CPlusPlus0x)
     Diag(TypenameLoc, diag::ext_typename_outside_of_template)
@@ -5292,8 +5283,6 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
   
   TypeSourceInfo *InnerTSI = 0;
   QualType T = GetTypeFromParser(Ty, &InnerTSI);
-  NestedNameSpecifier *NNS
-    = static_cast<NestedNameSpecifier *>(SS.getScopeRep());
 
   assert(isa<TemplateSpecializationType>(T) && 
          "Expected a template specialization type");
@@ -5310,13 +5299,14 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
     else
       Builder.push<TemplateSpecializationTypeLoc>(T).initialize(TemplateLoc);
 
-    T = Context.getElaboratedType(ETK_Typename, NNS, T);
+    /* Note: NNS already embedded in template specialization type T. */
+    T = Context.getElaboratedType(ETK_Typename, /*NNS=*/0, T);
     ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
     TL.setKeywordLoc(TypenameLoc);
     TL.setQualifierRange(SS.getRange());
 
     TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
-    return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+    return CreateParsedType(T, TSI);
   }
 
   // TODO: it's really silly that we make a template specialization
@@ -5325,7 +5315,10 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
   DependentTemplateName *DTN =
     TST->getTemplateName().getAsDependentTemplateName();
   assert(DTN && "dependent template has non-dependent name?");
-  T = Context.getDependentTemplateSpecializationType(ETK_Typename, NNS,
+  assert(DTN->getQualifier()
+         == static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
+  T = Context.getDependentTemplateSpecializationType(ETK_Typename,
+                                                     DTN->getQualifier(),
                                                      DTN->getIdentifier(),
                                                      TST->getNumArgs(),
                                                      TST->getArgs());
@@ -5344,7 +5337,7 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
   }
   TL.setKeywordLoc(TypenameLoc);
   TL.setQualifierRange(SS.getRange());
-  return CreateLocInfoType(T, TSI).getAsOpaquePtr();
+  return CreateParsedType(T, TSI);
 }
 
 /// \brief Build the type that describes a C++ typename specifier,
@@ -5463,15 +5456,6 @@ namespace {
       this->Loc = Loc;
       this->Entity = Entity;
     }
-      
-    /// \brief Transforms an expression by returning the expression itself
-    /// (an identity function).
-    ///
-    /// FIXME: This is completely unsafe; we will need to actually clone the
-    /// expressions.
-    Sema::OwningExprResult TransformExpr(Expr *E) {
-      return getSema().Owned(E->Retain());
-    }
   };
 }
 
@@ -5511,6 +5495,12 @@ TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
   return Rebuilder.TransformType(T);
 }
 
+ExprResult Sema::RebuildExprInCurrentInstantiation(Expr *E) {
+  CurrentInstantiationRebuilder Rebuilder(*this, E->getExprLoc(),
+                                          DeclarationName());
+  return Rebuilder.TransformExpr(E);
+}
+
 bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
   if (SS.isInvalid()) return true;
 
diff --git a/lib/Sema/SemaTemplate.h b/lib/Sema/SemaTemplate.h
deleted file mode 100644
index b3f4651..0000000
--- a/lib/Sema/SemaTemplate.h
+++ /dev/null
@@ -1,151 +0,0 @@
-//===------- SemaTemplate.h - C++ Templates ---------------------*- C++ -*-===/
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===/
-//
-//  This file provides types used in the semantic analysis of C++ templates.
-//
-//===----------------------------------------------------------------------===/
-#ifndef LLVM_CLANG_SEMA_TEMPLATE_H
-#define LLVM_CLANG_SEMA_TEMPLATE_H
-
-#include "clang/AST/DeclTemplate.h"
-#include "llvm/ADT/SmallVector.h"
-#include <cassert>
-
-namespace clang {
-  /// \brief Data structure that captures multiple levels of template argument
-  /// lists for use in template instantiation.
-  ///
-  /// Multiple levels of template arguments occur when instantiating the 
-  /// definitions of member templates. For example:
-  ///
-  /// \code
-  /// template<typename T>
-  /// struct X {
-  ///   template<T Value>
-  ///   struct Y {
-  ///     void f();
-  ///   };
-  /// };
-  /// \endcode
-  ///
-  /// When instantiating X<int>::Y<17>::f, the multi-level template argument
-  /// list will contain a template argument list (int) at depth 0 and a
-  /// template argument list (17) at depth 1.
-  class MultiLevelTemplateArgumentList {
-  public:
-    typedef std::pair<const TemplateArgument *, unsigned> ArgList;
-    
-  private:
-    /// \brief The template argument lists, stored from the innermost template
-    /// argument list (first) to the outermost template argument list (last).
-    llvm::SmallVector<ArgList, 4> TemplateArgumentLists;
-    
-  public:
-    /// \brief Construct an empty set of template argument lists.
-    MultiLevelTemplateArgumentList() { }
-    
-    /// \brief Construct a single-level template argument list.
-    explicit 
-    MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) {
-      addOuterTemplateArguments(&TemplateArgs);
-    }
-    
-    /// \brief Determine the number of levels in this template argument
-    /// list.
-    unsigned getNumLevels() const { return TemplateArgumentLists.size(); }
-    
-    /// \brief Retrieve the template argument at a given depth and index.
-    const TemplateArgument &operator()(unsigned Depth, unsigned Index) const {
-      assert(Depth < TemplateArgumentLists.size());
-      assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second);
-      return TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index];
-    }
-    
-    /// \brief Determine whether there is a non-NULL template argument at the
-    /// given depth and index.
-    ///
-    /// There must exist a template argument list at the given depth.
-    bool hasTemplateArgument(unsigned Depth, unsigned Index) const {
-      assert(Depth < TemplateArgumentLists.size());
-      
-      if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].second)
-        return false;
-      
-      return !(*this)(Depth, Index).isNull();
-    }
-    
-    /// \brief Add a new outermost level to the multi-level template argument 
-    /// list.
-    void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) {
-      TemplateArgumentLists.push_back(
-                                    ArgList(TemplateArgs->getFlatArgumentList(),
-                                            TemplateArgs->flat_size()));
-    }
-    
-    /// \brief Add a new outmost level to the multi-level template argument
-    /// list.
-    void addOuterTemplateArguments(const TemplateArgument *Args, 
-                                   unsigned NumArgs) {
-      TemplateArgumentLists.push_back(ArgList(Args, NumArgs));
-    }
-    
-    /// \brief Retrieve the innermost template argument list.
-    const ArgList &getInnermost() const { 
-      return TemplateArgumentLists.front(); 
-    }
-  };
-  
-  /// \brief The context in which partial ordering of function templates occurs.
-  enum TemplatePartialOrderingContext {
-    /// \brief Partial ordering of function templates for a function call.
-    TPOC_Call,
-    /// \brief Partial ordering of function templates for a call to a 
-    /// conversion function.
-    TPOC_Conversion,
-    /// \brief Partial ordering of function templates in other contexts, e.g.,
-    /// taking the address of a function template or matching a function 
-    /// template specialization to a function template.
-    TPOC_Other
-  };
-
-  /// \brief Captures a template argument whose value has been deduced
-  /// via c++ template argument deduction.
-  class DeducedTemplateArgument : public TemplateArgument {
-    /// \brief For a non-type template argument, whether the value was
-    /// deduced from an array bound.
-    bool DeducedFromArrayBound;
-
-  public:
-    DeducedTemplateArgument()
-      : TemplateArgument(), DeducedFromArrayBound(false) { }
-
-    DeducedTemplateArgument(const TemplateArgument &Arg,
-                            bool DeducedFromArrayBound = false)
-      : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
-
-    /// \brief Construct an integral non-type template argument that
-    /// has been deduced, possible from an array bound.
-    DeducedTemplateArgument(const llvm::APSInt &Value,
-                            QualType ValueType,
-                            bool DeducedFromArrayBound)
-      : TemplateArgument(Value, ValueType), 
-        DeducedFromArrayBound(DeducedFromArrayBound) { }
-
-    /// \brief For a non-type template argument, determine whether the
-    /// template argument was deduced from an array bound.
-    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
-
-    /// \brief Specify whether the given non-type template argument
-    /// was deduced from an array bound.
-    void setDeducedFromArrayBound(bool Deduced) {
-      DeducedFromArrayBound = Deduced;
-    }
-  };
-}
-
-#endif // LLVM_CLANG_SEMA_TEMPLATE_H
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 403d554..5c77ed6 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -10,16 +10,21 @@
 //
 //===----------------------------------------------------------------------===/
 
-#include "Sema.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
-#include "clang/Parse/DeclSpec.h"
 #include <algorithm>
 
 namespace clang {
+  using namespace sema;
+
   /// \brief Various flags that control template argument deduction.
   ///
   /// These flags can be bitwise-OR'd together.
@@ -74,7 +79,7 @@ DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateArgument &Param,
                         const TemplateArgument &Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced);
 
 /// \brief If the given expression is of a form that permits the deduction
@@ -97,7 +102,7 @@ DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               llvm::APSInt Value, QualType ValueType,
                               bool DeducedFromArrayBound,
-                              Sema::TemplateDeductionInfo &Info,
+                              TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
@@ -138,7 +143,7 @@ static Sema::TemplateDeductionResult
 DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               Expr *Value,
-                              Sema::TemplateDeductionInfo &Info,
+                              TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
@@ -180,7 +185,7 @@ static Sema::TemplateDeductionResult
 DeduceNonTypeTemplateArgument(Sema &S,
                               NonTypeTemplateParmDecl *NTTP,
                               Decl *D,
-                              Sema::TemplateDeductionInfo &Info,
+                              TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(NTTP->getDepth() == 0 &&
          "Cannot deduce non-type template argument with depth > 0");
@@ -214,7 +219,7 @@ DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         TemplateName Param,
                         TemplateName Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
   if (!ParamDecl) {
@@ -278,7 +283,7 @@ DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateSpecializationType *Param,
                         QualType Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(Arg.isCanonical() && "Argument type must be canonical");
 
@@ -345,6 +350,29 @@ DeduceTemplateArguments(Sema &S,
   return Sema::TDK_Success;
 }
 
+/// \brief Determines whether the given type is an opaque type that
+/// might be more qualified when instantiated.
+static bool IsPossiblyOpaquelyQualifiedType(QualType T) {
+  switch (T->getTypeClass()) {
+  case Type::TypeOfExpr:
+  case Type::TypeOf:
+  case Type::DependentName:
+  case Type::Decltype:
+  case Type::UnresolvedUsing:
+    return true;
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+  case Type::VariableArray:
+  case Type::DependentSizedArray:
+    return IsPossiblyOpaquelyQualifiedType(
+                                      cast<ArrayType>(T)->getElementType());
+
+  default:
+    return false;
+  }
+}
+
 /// \brief Deduce the template arguments by comparing the parameter type and
 /// the argument type (C++ [temp.deduct.type]).
 ///
@@ -370,7 +398,7 @@ static Sema::TemplateDeductionResult
 DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         QualType ParamIn, QualType ArgIn,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                      llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
                         unsigned TDF) {
   // We only want to look at the canonical types, since typedefs and
@@ -428,9 +456,9 @@ DeduceTemplateArguments(Sema &S,
     // type.
     if (Param.isMoreQualifiedThan(Arg) && !(TDF & TDF_IgnoreQualifiers)) {
       Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
-      Info.FirstArg = Deduced[Index];
+      Info.FirstArg = TemplateArgument(Param);
       Info.SecondArg = TemplateArgument(Arg);
-      return Sema::TDK_InconsistentQuals;
+      return Sema::TDK_Underqualified;
     }
 
     assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
@@ -469,7 +497,7 @@ DeduceTemplateArguments(Sema &S,
     if (TDF & TDF_ParamWithReferenceType) {
       if (Param.isMoreQualifiedThan(Arg))
         return Sema::TDK_NonDeducedMismatch;
-    } else {
+    } else if (!IsPossiblyOpaquelyQualifiedType(Param)) {
       if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
         return Sema::TDK_NonDeducedMismatch;
     }
@@ -530,10 +558,11 @@ DeduceTemplateArguments(Sema &S,
       if (!IncompleteArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
+      unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
       return DeduceTemplateArguments(S, TemplateParams,
                      S.Context.getAsIncompleteArrayType(Param)->getElementType(),
                                      IncompleteArrayArg->getElementType(),
-                                     Info, Deduced, 0);
+                                     Info, Deduced, SubTDF);
     }
 
     //     T [integer-constant]
@@ -548,10 +577,11 @@ DeduceTemplateArguments(Sema &S,
       if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
         return Sema::TDK_NonDeducedMismatch;
 
+      unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
       return DeduceTemplateArguments(S, TemplateParams,
                                      ConstantArrayParm->getElementType(),
                                      ConstantArrayArg->getElementType(),
-                                     Info, Deduced, 0);
+                                     Info, Deduced, SubTDF);
     }
 
     //     type [i]
@@ -560,6 +590,8 @@ DeduceTemplateArguments(Sema &S,
       if (!ArrayArg)
         return Sema::TDK_NonDeducedMismatch;
 
+      unsigned SubTDF = TDF & TDF_IgnoreQualifiers;
+
       // Check the element type of the arrays
       const DependentSizedArrayType *DependentArrayParm
         = S.Context.getAsDependentSizedArrayType(Param);
@@ -567,7 +599,7 @@ DeduceTemplateArguments(Sema &S,
             = DeduceTemplateArguments(S, TemplateParams,
                                       DependentArrayParm->getElementType(),
                                       ArrayArg->getElementType(),
-                                      Info, Deduced, 0))
+                                      Info, Deduced, SubTDF))
         return Result;
 
       // Determine the array bound is something we can deduce.
@@ -797,7 +829,7 @@ DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateArgument &Param,
                         const TemplateArgument &Arg,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   switch (Param.getKind()) {
   case TemplateArgument::Null:
@@ -847,7 +879,6 @@ DeduceTemplateArguments(Sema &S,
       return Sema::TDK_NonDeducedMismatch;
     }
 
-    assert(false && "Type/value mismatch");
     Info.FirstArg = Param;
     Info.SecondArg = Arg;
     return Sema::TDK_NonDeducedMismatch;
@@ -868,7 +899,6 @@ DeduceTemplateArguments(Sema &S,
         return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsDecl(),
                                              Info, Deduced);
       
-      assert(false && "Type/value mismatch");
       Info.FirstArg = Param;
       Info.SecondArg = Arg;
       return Sema::TDK_NonDeducedMismatch;
@@ -890,7 +920,7 @@ DeduceTemplateArguments(Sema &S,
                         TemplateParameterList *TemplateParams,
                         const TemplateArgumentList &ParamList,
                         const TemplateArgumentList &ArgList,
-                        Sema::TemplateDeductionInfo &Info,
+                        TemplateDeductionInfo &Info,
                     llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
   assert(ParamList.size() == ArgList.size());
   for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
@@ -974,7 +1004,7 @@ FinishTemplateArgumentDeduction(Sema &S,
                                 ClassTemplatePartialSpecializationDecl *Partial,
                                 const TemplateArgumentList &TemplateArgs,
                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
-                                Sema::TemplateDeductionInfo &Info) {
+                                TemplateDeductionInfo &Info) {
   // Trap errors.
   Sema::SFINAETrap Trap(S);
   
@@ -1010,7 +1040,7 @@ FinishTemplateArgumentDeduction(Sema &S,
   // to the class template.
   // FIXME: Do we have to correct the types of deduced non-type template 
   // arguments (in particular, integral non-type template arguments?).
-  Sema::LocalInstantiationScope InstScope(S);
+  LocalInstantiationScope InstScope(S);
   ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
   const TemplateArgumentLoc *PartialTemplateArgs
     = Partial->getTemplateArgsAsWritten();
@@ -1245,7 +1275,8 @@ Sema::SubstituteExplicitTemplateArguments(
                                       Proto->isVariadic(),
                                       Proto->getTypeQuals(),
                                       Function->getLocation(),
-                                      Function->getDeclName());
+                                      Function->getDeclName(),
+                                      Proto->getExtInfo());
     if (FunctionType->isNull() || Trap.hasErrorOccurred())
       return TDK_SubstitutionFailure;
   }
@@ -1486,14 +1517,22 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate,
   return TDK_Success;
 }
 
+/// Gets the type of a function for template-argument-deducton
+/// purposes when it's considered as part of an overload set.
 static QualType GetTypeOfFunction(ASTContext &Context,
-                                  bool isAddressOfOperand,
+                                  const OverloadExpr::FindResult &R,
                                   FunctionDecl *Fn) {
-  if (!isAddressOfOperand) return Fn->getType();
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn))
-    if (Method->isInstance())
+    if (Method->isInstance()) {
+      // An instance method that's referenced in a form that doesn't
+      // look like a member pointer is just invalid.
+      if (!R.HasFormOfMemberPointer) return QualType();
+
       return Context.getMemberPointerType(Fn->getType(),
                Context.getTypeDeclType(Method->getParent()).getTypePtr());
+    }
+
+  if (!R.IsAddressOfOperand) return Fn->getType();
   return Context.getPointerType(Fn->getType());
 }
 
@@ -1503,11 +1542,19 @@ static QualType GetTypeOfFunction(ASTContext &Context,
 /// undeduced context
 static QualType
 ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
-                            Expr *Arg, QualType ParamType) {
-  llvm::PointerIntPair<OverloadExpr*,1> R = OverloadExpr::find(Arg);
+                            Expr *Arg, QualType ParamType,
+                            bool ParamWasReference) {
+  
+  OverloadExpr::FindResult R = OverloadExpr::find(Arg);
 
-  bool isAddressOfOperand = bool(R.getInt());
-  OverloadExpr *Ovl = R.getPointer();
+  OverloadExpr *Ovl = R.Expression;
+
+  // C++0x [temp.deduct.call]p4
+  unsigned TDF = 0;
+  if (ParamWasReference)
+    TDF |= TDF_ParamWithReferenceType;
+  if (R.IsAddressOfOperand)
+    TDF |= TDF_IgnoreQualifiers;
 
   // If there were explicit template arguments, we can only find
   // something via C++ [temp.arg.explicit]p3, i.e. if the arguments
@@ -1516,7 +1563,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
     // But we can still look for an explicit specialization.
     if (FunctionDecl *ExplicitSpec
           = S.ResolveSingleFunctionTemplateSpecialization(Ovl))
-      return GetTypeOfFunction(S.Context, isAddressOfOperand, ExplicitSpec);
+      return GetTypeOfFunction(S.Context, R, ExplicitSpec);
     return QualType();
   }
 
@@ -1541,8 +1588,14 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
       return QualType();
 
     FunctionDecl *Fn = cast<FunctionDecl>(D);
-    QualType ArgType = GetTypeOfFunction(S.Context, isAddressOfOperand, Fn);
+    QualType ArgType = GetTypeOfFunction(S.Context, R, Fn);
+    if (ArgType.isNull()) continue;
 
+    // Function-to-pointer conversion.
+    if (!ParamWasReference && ParamType->isPointerType() && 
+        ArgType->isFunctionType())
+      ArgType = S.Context.getPointerType(ArgType);
+    
     //   - If the argument is an overload set (not containing function
     //     templates), trial argument deduction is attempted using each
     //     of the members of the set. If deduction succeeds for only one
@@ -1557,9 +1610,7 @@ ResolveOverloadForDeduction(Sema &S, TemplateParameterList *TemplateParams,
     // So we do not reject deductions which were made elsewhere.
     llvm::SmallVector<DeducedTemplateArgument, 8> 
       Deduced(TemplateParams->size());
-    Sema::TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
-    unsigned TDF = 0;
-
+    TemplateDeductionInfo Info(S.Context, Ovl->getNameLoc());
     Sema::TemplateDeductionResult Result
       = DeduceTemplateArguments(S, TemplateParams,
                                 ParamType, ArgType,
@@ -1624,7 +1675,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
 
   // The types of the parameters from which we will perform template argument
   // deduction.
-  Sema::LocalInstantiationScope InstScope(*this);
+  LocalInstantiationScope InstScope(*this);
   TemplateParameterList *TemplateParams
     = FunctionTemplate->getTemplateParameters();
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
@@ -1654,20 +1705,40 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
     QualType ParamType = ParamTypes[I];
     QualType ArgType = Args[I]->getType();
 
+    // C++0x [temp.deduct.call]p3:
+    //   If P is a cv-qualified type, the top level cv-qualifiers of P’s type
+    //   are ignored for type deduction.
+    if (ParamType.getCVRQualifiers())
+      ParamType = ParamType.getLocalUnqualifiedType();
+    const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>();
+    if (ParamRefType) {
+      //   [...] If P is a reference type, the type referred to by P is used
+      //   for type deduction.
+      ParamType = ParamRefType->getPointeeType();
+    }
+    
     // Overload sets usually make this parameter an undeduced
     // context, but there are sometimes special circumstances.
     if (ArgType == Context.OverloadTy) {
       ArgType = ResolveOverloadForDeduction(*this, TemplateParams,
-                                            Args[I], ParamType);
+                                            Args[I], ParamType,
+                                            ParamRefType != 0);
       if (ArgType.isNull())
         continue;
     }
 
-    // C++ [temp.deduct.call]p2:
-    //   If P is not a reference type:
-    QualType CanonParamType = Context.getCanonicalType(ParamType);
-    bool ParamWasReference = isa<ReferenceType>(CanonParamType);
-    if (!ParamWasReference) {
+    if (ParamRefType) {
+      // C++0x [temp.deduct.call]p3:
+      //   [...] If P is of the form T&&, where T is a template parameter, and
+      //   the argument is an lvalue, the type A& is used in place of A for
+      //   type deduction.
+      if (ParamRefType->isRValueReferenceType() &&
+          ParamRefType->getAs<TemplateTypeParmType>() &&
+          Args[I]->isLvalue(Context) == Expr::LV_Valid)
+        ArgType = Context.getLValueReferenceType(ArgType);
+    } else {
+      // C++ [temp.deduct.call]p2:
+      //   If P is not a reference type:
       //   - If A is an array type, the pointer type produced by the
       //     array-to-pointer standard conversion (4.2) is used in place of
       //     A for type deduction; otherwise,
@@ -1682,30 +1753,11 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
         // - If A is a cv-qualified type, the top level cv-qualifiers of A’s
         //   type are ignored for type deduction.
         QualType CanonArgType = Context.getCanonicalType(ArgType);
-        if (CanonArgType.getLocalCVRQualifiers())
-          ArgType = CanonArgType.getLocalUnqualifiedType();
+        if (ArgType.getCVRQualifiers())
+          ArgType = ArgType.getUnqualifiedType();
       }
     }
 
-    // C++0x [temp.deduct.call]p3:
-    //   If P is a cv-qualified type, the top level cv-qualifiers of P’s type
-    //   are ignored for type deduction.
-    if (CanonParamType.getLocalCVRQualifiers())
-      ParamType = CanonParamType.getLocalUnqualifiedType();
-    if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
-      //   [...] If P is a reference type, the type referred to by P is used
-      //   for type deduction.
-      ParamType = ParamRefType->getPointeeType();
-
-      //   [...] If P is of the form T&&, where T is a template parameter, and
-      //   the argument is an lvalue, the type A& is used in place of A for
-      //   type deduction.
-      if (isa<RValueReferenceType>(ParamRefType) &&
-          ParamRefType->getAs<TemplateTypeParmType>() &&
-          Args[I]->isLvalue(Context) == Expr::LV_Valid)
-        ArgType = Context.getLValueReferenceType(ArgType);
-    }
-
     // C++0x [temp.deduct.call]p4:
     //   In general, the deduction process attempts to find template argument
     //   values that will make the deduced A identical to A (after the type A
@@ -1715,12 +1767,13 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
     //     - If the original P is a reference type, the deduced A (i.e., the
     //       type referred to by the reference) can be more cv-qualified than
     //       the transformed A.
-    if (ParamWasReference)
+    if (ParamRefType)
       TDF |= TDF_ParamWithReferenceType;
     //     - The transformed A can be another pointer or pointer to member
     //       type that can be converted to the deduced A via a qualification
     //       conversion (4.4).
-    if (ArgType->isPointerType() || ArgType->isMemberPointerType())
+    if (ArgType->isPointerType() || ArgType->isMemberPointerType() ||
+        ArgType->isObjCObjectPointerType())
       TDF |= TDF_IgnoreQualifiers;
     //     - If P is a class and P has the form simple-template-id, then the
     //       transformed A can be a derived class of the deduced A. Likewise,
@@ -1783,7 +1836,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
   QualType FunctionType = Function->getType();
 
   // Substitute any explicit template arguments.
-  Sema::LocalInstantiationScope InstScope(*this);
+  LocalInstantiationScope InstScope(*this);
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
   unsigned NumExplicitlySpecified = 0;
   llvm::SmallVector<QualType, 4> ParamTypes;
@@ -1915,7 +1968,7 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
   // modulo the various allowed differences.
 
   // Finish template argument deduction.
-  Sema::LocalInstantiationScope InstScope(*this);
+  LocalInstantiationScope InstScope(*this);
   FunctionDecl *Spec = 0;
   TemplateDeductionResult Result
     = FinishTemplateArgumentDeduction(FunctionTemplate, Deduced, 0, Spec, 
@@ -1979,7 +2032,7 @@ static Sema::TemplateDeductionResult
 DeduceTemplateArgumentsDuringPartialOrdering(Sema &S,
                                         TemplateParameterList *TemplateParams,
                                              QualType ParamIn, QualType ArgIn,
-                                             Sema::TemplateDeductionInfo &Info,
+                                             TemplateDeductionInfo &Info,
                       llvm::SmallVectorImpl<DeducedTemplateArgument> &Deduced,
    llvm::SmallVectorImpl<DeductionQualifierComparison> *QualifierComparisons) {
   CanQualType Param = S.Context.getCanonicalType(ParamIn);
@@ -2061,7 +2114,7 @@ static bool isAtLeastAsSpecializedAs(Sema &S,
   // C++0x [temp.deduct.partial]p3:
   //   The types used to determine the ordering depend on the context in which
   //   the partial ordering is done:
-  Sema::TemplateDeductionInfo Info(S.Context, Loc);
+  TemplateDeductionInfo Info(S.Context, Loc);
   switch (TPOC) {
   case TPOC_Call: {
     //   - In the context of a function call, the function parameter types are
@@ -2386,7 +2439,7 @@ Sema::getMoreSpecializedPartialSpecialization(
   // template partial specialization's template arguments, for
   // example.
   llvm::SmallVector<DeducedTemplateArgument, 4> Deduced;
-  Sema::TemplateDeductionInfo Info(Context, Loc);
+  TemplateDeductionInfo Info(Context, Loc);
 
   QualType PT1 = PS1->getInjectedSpecializationType();
   QualType PT2 = PS2->getInjectedSpecializationType();
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 0cdc8a1..4d4c181 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -10,17 +10,20 @@
 //
 //===----------------------------------------------------------------------===/
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "TreeTransform.h"
-#include "Lookup.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateDeduction.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/DeclTemplate.h"
-#include "clang/Parse/DeclSpec.h"
 #include "clang/Basic/LangOptions.h"
 
 using namespace clang;
+using namespace sema;
 
 //===----------------------------------------------------------------------===/
 // Template Instantiation Support
@@ -614,10 +617,10 @@ namespace {
     QualType RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
                                    NestedNameSpecifier *NNS, QualType T);
 
-    Sema::OwningExprResult TransformPredefinedExpr(PredefinedExpr *E);
-    Sema::OwningExprResult TransformDeclRefExpr(DeclRefExpr *E);
-    Sema::OwningExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
-    Sema::OwningExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
+    ExprResult TransformPredefinedExpr(PredefinedExpr *E);
+    ExprResult TransformDeclRefExpr(DeclRefExpr *E);
+    ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
                                                 NonTypeTemplateParmDecl *D);
 
     QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
@@ -631,9 +634,9 @@ namespace {
                                            TemplateTypeParmTypeLoc TL,
                                            QualType ObjectType);
 
-    Sema::OwningExprResult TransformCallExpr(CallExpr *CE) {
+    ExprResult TransformCallExpr(CallExpr *CE) {
       getSema().CallsUndergoingInstantiation.push_back(CE);
-      OwningExprResult Result =
+      ExprResult Result =
           TreeTransform<TemplateInstantiator>::TransformCallExpr(CE);
       getSema().CallsUndergoingInstantiation.pop_back();
       return move(Result);
@@ -768,7 +771,7 @@ TemplateInstantiator::RebuildElaboratedType(ElaboratedTypeKeyword Keyword,
                                                                     NNS, T);
 }
 
-Sema::OwningExprResult 
+ExprResult 
 TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   if (!E->isTypeDependent())
     return SemaRef.Owned(E->Retain());
@@ -790,7 +793,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
   return getSema().Owned(PE);
 }
 
-Sema::OwningExprResult
+ExprResult
 TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
                                                NonTypeTemplateParmDecl *NTTP) {
   // If the corresponding template argument is NULL or non-existent, it's
@@ -818,7 +821,7 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
                             getSema().FindInstantiatedDecl(E->getLocation(),
                                                            VD, TemplateArgs));
     if (!VD)
-      return SemaRef.ExprError();
+      return ExprError();
 
     // Derive the type we want the substituted decl to have.  This had
     // better be non-dependent, or these checks will have serious problems.
@@ -837,7 +840,7 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
 }
                                                    
 
-Sema::OwningExprResult
+ExprResult
 TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
   NamedDecl *D = E->getDecl();
   if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
@@ -851,7 +854,7 @@ TemplateInstantiator::TransformDeclRefExpr(DeclRefExpr *E) {
   return TreeTransform<TemplateInstantiator>::TransformDeclRefExpr(E);
 }
 
-Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
+ExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
     CXXDefaultArgExpr *E) {
   assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
              getDescribedFunctionTemplate() &&
@@ -865,7 +868,7 @@ QualType TemplateInstantiator::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                                         FunctionProtoTypeLoc TL,
                                                           QualType ObjectType) {
   // We need a local instantiation scope for this function prototype.
-  Sema::LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+  LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
   return inherited::TransformFunctionProtoType(TLB, TL, ObjectType);
 }
 
@@ -1067,7 +1070,8 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
   NewParm->setHasInheritedDefaultArg(OldParm->hasInheritedDefaultArg());
 
   CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
-  // Set DeclContext if inside a Block.
+  // FIXME: OldParm may come from a FunctionProtoType, in which case CurContext
+  // can be anything, is this right ?
   NewParm->setDeclContext(CurContext);
   
   return NewParm;  
@@ -1100,11 +1104,11 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
       continue;
     }
 
-    QualType BaseType = SubstType(Base->getType(),
-                                  TemplateArgs,
-                                  Base->getSourceRange().getBegin(),
-                                  DeclarationName());
-    if (BaseType.isNull()) {
+    TypeSourceInfo *BaseTypeLoc = SubstType(Base->getTypeSourceInfo(),
+                                            TemplateArgs,
+                                            Base->getSourceRange().getBegin(),
+                                            DeclarationName());
+    if (!BaseTypeLoc) {
       Invalid = true;
       continue;
     }
@@ -1114,9 +1118,7 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
                                Base->getSourceRange(),
                                Base->isVirtual(),
                                Base->getAccessSpecifierAsWritten(),
-                               BaseType,
-                               /*FIXME: Not totally accurate */
-                               Base->getSourceRange().getBegin()))
+                               BaseTypeLoc))
       InstantiatedBases.push_back(InstantiatedBase);
     else
       Invalid = true;
@@ -1199,13 +1201,16 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
   // PushDeclContext because we don't have a scope.
   ContextRAII SavedContext(*this, Instantiation);
   EnterExpressionEvaluationContext EvalContext(*this, 
-                                               Action::PotentiallyEvaluated);
+                                               Sema::PotentiallyEvaluated);
 
   // If this is an instantiation of a local class, merge this local
   // instantiation scope with the enclosing scope. Otherwise, every
   // instantiation of a class has its own local instantiation scope.
   bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
-  Sema::LocalInstantiationScope Scope(*this, MergeWithParentScope);
+  LocalInstantiationScope Scope(*this, MergeWithParentScope);
+
+  // Pull attributes from the pattern onto the instantiation.
+  InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
 
   // Start the definition of this instantiation.
   Instantiation->startDefinition();
@@ -1216,14 +1221,14 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
   if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
     Invalid = true;
 
-  llvm::SmallVector<DeclPtrTy, 4> Fields;
+  llvm::SmallVector<Decl*, 4> Fields;
   for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
          MemberEnd = Pattern->decls_end();
        Member != MemberEnd; ++Member) {
     Decl *NewMember = SubstDecl(*Member, Instantiation, TemplateArgs);
     if (NewMember) {
       if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember))
-        Fields.push_back(DeclPtrTy::make(Field));
+        Fields.push_back(Field);
       else if (NewMember->isInvalidDecl())
         Invalid = true;
     } else {
@@ -1234,7 +1239,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
   }
 
   // Finish checking fields.
-  ActOnFields(0, Instantiation->getLocation(), DeclPtrTy::make(Instantiation),
+  ActOnFields(0, Instantiation->getLocation(), Instantiation,
               Fields.data(), Fields.size(), SourceLocation(), SourceLocation(),
               0);
   CheckCompletedCXXClass(Instantiation);
@@ -1416,12 +1421,6 @@ Sema::InstantiateClassTemplateSpecialization(
                                  TSK,
                                  Complain);
 
-  for (unsigned I = 0, N = Matched.size(); I != N; ++I) {
-    // FIXME: Implement TemplateArgumentList::Destroy!
-    //    if (Matched[I].first != Pattern)
-    //      Matched[I].second->Destroy(Context);
-  }
-
   return Result;
 }
 
@@ -1583,7 +1582,7 @@ Sema::InstantiateClassTemplateSpecializationMembers(
                           TSK);
 }
 
-Sema::OwningStmtResult
+StmtResult
 Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!S)
     return Owned(S);
@@ -1594,7 +1593,7 @@ Sema::SubstStmt(Stmt *S, const MultiLevelTemplateArgumentList &TemplateArgs) {
   return Instantiator.TransformStmt(S);
 }
 
-Sema::OwningExprResult
+ExprResult
 Sema::SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (!E)
     return Owned(E);
@@ -1615,6 +1614,15 @@ Sema::SubstNestedNameSpecifier(NestedNameSpecifier *NNS,
   return Instantiator.TransformNestedNameSpecifier(NNS, Range);
 }
 
+/// \brief Do template substitution on declaration name info.
+DeclarationNameInfo
+Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                         const MultiLevelTemplateArgumentList &TemplateArgs) {
+  TemplateInstantiator Instantiator(*this, TemplateArgs, NameInfo.getLoc(),
+                                    NameInfo.getName());
+  return Instantiator.TransformDeclarationNameInfo(NameInfo);
+}
+
 TemplateName
 Sema::SubstTemplateName(TemplateName Name, SourceLocation Loc,
                         const MultiLevelTemplateArgumentList &TemplateArgs) {
@@ -1631,7 +1639,7 @@ bool Sema::Subst(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
   return Instantiator.TransformTemplateArgument(Input, Output);
 }
 
-Decl *Sema::LocalInstantiationScope::getInstantiationOf(const Decl *D) {
+Decl *LocalInstantiationScope::getInstantiationOf(const Decl *D) {
   for (LocalInstantiationScope *Current = this; Current; 
        Current = Current->Outer) {
     // Check if we found something within this scope.
@@ -1650,8 +1658,7 @@ Decl *Sema::LocalInstantiationScope::getInstantiationOf(const Decl *D) {
   return 0;
 }
 
-void Sema::LocalInstantiationScope::InstantiatedLocal(const Decl *D, 
-                                                      Decl *Inst) {
+void LocalInstantiationScope::InstantiatedLocal(const Decl *D, Decl *Inst) {
   Decl *&Stored = LocalDecls[D];
   assert((!Stored || Stored == Inst)&& "Already instantiated this local");
   Stored = Inst;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2fd3528..1c7869f 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -9,8 +9,10 @@
 //  This file implements C++ template instantiation for declarations.
 //
 //===----------------------------------------------------------------------===/
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Template.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclTemplate.h"
@@ -19,7 +21,6 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeLoc.h"
-#include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Lex/Preprocessor.h"
 
 using namespace clang;
@@ -31,11 +32,7 @@ namespace {
     DeclContext *Owner;
     const MultiLevelTemplateArgumentList &TemplateArgs;
 
-    void InstantiateAttrs(Decl *Tmpl, Decl *New);
-      
   public:
-    typedef Sema::OwningExprResult OwningExprResult;
-
     TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
                              const MultiLevelTemplateArgumentList &TemplateArgs)
       : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { }
@@ -87,10 +84,6 @@ namespace {
       return 0;
     }
 
-    const LangOptions &getLangOptions() {
-      return SemaRef.getLangOptions();
-    }
-
     // Helper functions for instantiating methods.
     TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
                              llvm::SmallVectorImpl<ParmVarDecl *> &Params);
@@ -144,28 +137,38 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
 }
 
 // FIXME: Is this still too simple?
-void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
-  for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
-       TmplAttr = TmplAttr->getNext()) {
+void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+                            Decl *Tmpl, Decl *New) {
+  for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+       i != e; ++i) {
+    const Attr *TmplAttr = *i;
     // FIXME: This should be generalized to more than just the AlignedAttr.
     if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
-      if (Aligned->isDependent()) {
+      if (Aligned->isAlignmentDependent()) {
         // The alignment expression is not potentially evaluated.
-        EnterExpressionEvaluationContext Unevaluated(SemaRef,
-                                                     Action::Unevaluated);
-
-        OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(),
-                                                    TemplateArgs);
-        if (!Result.isInvalid())
-          // FIXME: Is this the correct source location?
-          SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
-                                 New, Result.takeAs<Expr>());
+        EnterExpressionEvaluationContext Unevaluated(*this,
+                                                     Sema::Unevaluated);
+
+        if (Aligned->isAlignmentExpr()) {
+          ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+                                              TemplateArgs);
+          if (!Result.isInvalid())
+            AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+        }
+        else {
+          TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+                                              TemplateArgs,
+                                              Aligned->getLocation(), 
+                                              DeclarationName());
+          if (Result)
+            AddAlignedAttr(Aligned->getLocation(), New, Result);
+        }
         continue;
       }
     }
 
     // FIXME: Is cloning correct for all attributes?
-    Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
+    Attr *NewAttr = TmplAttr->clone(Context);
     New->addAttr(NewAttr);
   }
 }
@@ -234,7 +237,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
     Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
   }
 
-  InstantiateAttrs(D, Typedef);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
 
   Typedef->setAccess(D->getAccess());
   Owner->addDecl(Typedef);
@@ -249,14 +252,14 @@ static bool InstantiateInitializationArguments(Sema &SemaRef,
                                                Expr **Args, unsigned NumArgs,
                            const MultiLevelTemplateArgumentList &TemplateArgs,
                          llvm::SmallVectorImpl<SourceLocation> &FakeCommaLocs,
-                           ASTOwningVector<&ActionBase::DeleteExpr> &InitArgs) {
+                           ASTOwningVector<Expr*> &InitArgs) {
   for (unsigned I = 0; I != NumArgs; ++I) {
     // When we hit the first defaulted argument, break out of the loop:
     // we don't pass those default arguments on.
     if (Args[I]->isDefaultArgument())
       break;
   
-    Sema::OwningExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
+    ExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
     if (Arg.isInvalid())
       return true;
   
@@ -288,7 +291,7 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
                             const MultiLevelTemplateArgumentList &TemplateArgs,
                                    SourceLocation &LParenLoc,
                                llvm::SmallVector<SourceLocation, 4> &CommaLocs,
-                             ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
+                             ASTOwningVector<Expr*> &NewArgs,
                                    SourceLocation &RParenLoc) {
   NewArgs.clear();
   LParenLoc = SourceLocation();
@@ -331,7 +334,7 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
     }
   }
  
-  Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
+  ExprResult Result = S.SubstExpr(Init, TemplateArgs);
   if (Result.isInvalid())
     return true;
 
@@ -363,7 +366,6 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
                                  D->getStorageClassAsWritten());
   Var->setThreadSpecified(D->isThreadSpecified());
   Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
-  Var->setDeclaredInCondition(D->isDeclaredInCondition());
 
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(D, Var))
@@ -399,7 +401,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
     if (Owner->isFunctionOrMethod())
       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
   }
-  InstantiateAttrs(D, Var);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
   
   // Link instantiations of static data members back to the template from
   // which they were instantiated.
@@ -418,25 +420,23 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
     // Instantiate the initializer.
     SourceLocation LParenLoc, RParenLoc;
     llvm::SmallVector<SourceLocation, 4> CommaLocs;
-    ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
+    ASTOwningVector<Expr*> InitArgs(SemaRef);
     if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
                                 CommaLocs, InitArgs, RParenLoc)) {
       // Attach the initializer to the declaration.
       if (D->hasCXXDirectInitializer()) {
         // Add the direct initializer to the declaration.
-        SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
+        SemaRef.AddCXXDirectInitializerToDecl(Var,
                                               LParenLoc,
                                               move_arg(InitArgs),
                                               CommaLocs.data(),
                                               RParenLoc);
       } else if (InitArgs.size() == 1) {
-        Expr *Init = (Expr*)(InitArgs.take()[0]);
-        SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), 
-                                     SemaRef.Owned(Init),
-                                     false);        
+        Expr *Init = InitArgs.take()[0];
+        SemaRef.AddInitializerToDecl(Var, Init, false);
       } else {
         assert(InitArgs.size() == 0);
-        SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);    
+        SemaRef.ActOnUninitializedDecl(Var, false);    
       }
     } else {
       // FIXME: Not too happy about invalidating the declaration
@@ -446,12 +446,12 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
     
     SemaRef.PopExpressionEvaluationContext();
   } else if (!Var->isStaticDataMember() || Var->isOutOfLine())
-    SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+    SemaRef.ActOnUninitializedDecl(Var, false);
 
   // Diagnose unused local variables.
   if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed())
     SemaRef.DiagnoseUnusedDecl(Var);
-  
+
   return Var;
 }
 
@@ -493,9 +493,9 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
     BitWidth = 0;
   else if (BitWidth) {
     // The bit-width expression is not potentially evaluated.
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-    OwningExprResult InstantiatedBitWidth
+    ExprResult InstantiatedBitWidth
       = SemaRef.SubstExpr(BitWidth, TemplateArgs);
     if (InstantiatedBitWidth.isInvalid()) {
       Invalid = true;
@@ -518,7 +518,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
     return 0;
   }
 
-  InstantiateAttrs(D, Field);
+  SemaRef.InstantiateAttrs(TemplateArgs, D, Field);
   
   if (Invalid)
     Field->setInvalidDecl();
@@ -529,7 +529,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
   } 
   if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {
     if (Parent->isAnonymousStructOrUnion() &&
-        Parent->getLookupContext()->isFunctionOrMethod())
+        Parent->getRedeclContext()->isFunctionOrMethod())
       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field);
   }
 
@@ -581,20 +581,18 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
   Expr *AssertExpr = D->getAssertExpr();
 
   // The expression in a static assertion is not potentially evaluated.
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  OwningExprResult InstantiatedAssertExpr
+  ExprResult InstantiatedAssertExpr
     = SemaRef.SubstExpr(AssertExpr, TemplateArgs);
   if (InstantiatedAssertExpr.isInvalid())
     return 0;
 
-  OwningExprResult Message(SemaRef, D->getMessage());
+  ExprResult Message(D->getMessage());
   D->getMessage()->Retain();
-  Decl *StaticAssert
-    = SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
-                                           move(InstantiatedAssertExpr),
-                                           move(Message)).getAs<Decl>();
-  return StaticAssert;
+  return SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
+                                              InstantiatedAssertExpr.get(),
+                                              Message.get());
 }
 
 Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
@@ -611,18 +609,18 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
   if (D->getDeclContext()->isFunctionOrMethod())
     SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
     
-  llvm::SmallVector<Sema::DeclPtrTy, 4> Enumerators;
+  llvm::SmallVector<Decl*, 4> Enumerators;
 
   EnumConstantDecl *LastEnumConst = 0;
   for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
          ECEnd = D->enumerator_end();
        EC != ECEnd; ++EC) {
     // The specified value for the enumerator.
-    OwningExprResult Value = SemaRef.Owned((Expr *)0);
+    ExprResult Value = SemaRef.Owned((Expr *)0);
     if (Expr *UninstValue = EC->getInitExpr()) {
       // The enumerator's value expression is not potentially evaluated.
       EnterExpressionEvaluationContext Unevaluated(SemaRef,
-                                                   Action::Unevaluated);
+                                                   Sema::Unevaluated);
 
       Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);
     }
@@ -637,7 +635,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
     EnumConstantDecl *EnumConst
       = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
                                   EC->getLocation(), EC->getIdentifier(),
-                                  move(Value));
+                                  Value.get());
 
     if (isInvalid) {
       if (EnumConst)
@@ -648,7 +646,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
     if (EnumConst) {
       EnumConst->setAccess(Enum->getAccess());
       Enum->addDecl(EnumConst);
-      Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
+      Enumerators.push_back(EnumConst);
       LastEnumConst = EnumConst;
       
       if (D->getDeclContext()->isFunctionOrMethod()) {
@@ -662,8 +660,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
   // FIXME: Fixup LBraceLoc and RBraceLoc
   // FIXME: Empty Scope and AttributeList (required to handle attribute packed).
   SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), SourceLocation(),
-                        Sema::DeclPtrTy::make(Enum),
-                        &Enumerators[0], Enumerators.size(),
+                        Enum,
+                        Enumerators.data(), Enumerators.size(),
                         0, 0);
 
   return Enum;
@@ -679,7 +677,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
 
   // Create a local instantiation scope for this class template, which
   // will contain the instantiations of the template parameters.
-  Sema::LocalInstantiationScope Scope(SemaRef);
+  LocalInstantiationScope Scope(SemaRef);
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
   if (!InstParams)
@@ -857,16 +855,7 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(
   if (!InstClassTemplate)
     return 0;
   
-  Decl *DCanon = D->getCanonicalDecl();
-  for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
-            P = InstClassTemplate->getPartialSpecializations().begin(),
-         PEnd = InstClassTemplate->getPartialSpecializations().end();
-       P != PEnd; ++P) {
-    if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
-      return &*P;
-  }
-  
-  return 0;
+  return InstClassTemplate->findPartialSpecInstantiatedFromMember(D);
 }
 
 Decl *
@@ -875,7 +864,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
   // will contain the instantiations of the template parameters and then get
   // merged with the local instantiation scope for the function template 
   // itself.
-  Sema::LocalInstantiationScope Scope(SemaRef);
+  LocalInstantiationScope Scope(SemaRef);
 
   TemplateParameterList *TempParams = D->getTemplateParameters();
   TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
@@ -957,7 +946,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
   // Make sure that anonymous structs and unions are recorded.
   if (D->isAnonymousStructOrUnion()) {
     Record->setAnonymousStructOrUnion(true);
-    if (Record->getDeclContext()->getLookupContext()->isFunctionOrMethod())
+    if (Record->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
   }
 
@@ -977,20 +966,16 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
   FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
   void *InsertPos = 0;
   if (FunctionTemplate && !TemplateParams) {
-    llvm::FoldingSetNodeID ID;
     std::pair<const TemplateArgument *, unsigned> Innermost 
       = TemplateArgs.getInnermost();
-    FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
-                                                Innermost.second,
-                                                SemaRef.Context);
 
-    FunctionTemplateSpecializationInfo *Info
-      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
-                                                                   InsertPos);
+    FunctionDecl *SpecFunc
+      = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+                                             InsertPos);
 
     // If we already have a function template specialization, return it.
-    if (Info)
-      return Info->Function;
+    if (SpecFunc)
+      return SpecFunc;
   }
 
   bool isFriend;
@@ -1003,7 +988,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
     Owner->isFunctionOrMethod() ||
     !(isa<Decl>(Owner) && 
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
-  Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+  LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
 
   llvm::SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1181,7 +1166,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
 
     PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
     DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
-    
+
+    bool queuedInstantiation = false;
+
     if (!SemaRef.getLangOptions().CPlusPlus0x &&
         D->isThisDeclarationADefinition()) {
       // Check for a function body.
@@ -1198,21 +1185,36 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
       else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(),
                                            REnd = Function->redecls_end();
                 R != REnd; ++R) {
-        if (*R != Function && 
-            ((*R)->getFriendObjectKind() != Decl::FOK_None)) {
+        if (*R == Function)
+          continue;
+        switch (R->getFriendObjectKind()) {
+        case Decl::FOK_None:
+          if (!queuedInstantiation && R->isUsed(false)) {
+            if (MemberSpecializationInfo *MSInfo
+                = Function->getMemberSpecializationInfo()) {
+              if (MSInfo->getPointOfInstantiation().isInvalid()) {
+                SourceLocation Loc = R->getLocation(); // FIXME
+                MSInfo->setPointOfInstantiation(Loc);
+                SemaRef.PendingLocalImplicitInstantiations.push_back(
+                                                 std::make_pair(Function, Loc));
+                queuedInstantiation = true;
+              }
+            }
+          }
+          break;
+        default:
           if (const FunctionDecl *RPattern
-              = (*R)->getTemplateInstantiationPattern())
+              = R->getTemplateInstantiationPattern())
             if (RPattern->hasBody(RPattern)) {
               SemaRef.Diag(Function->getLocation(), diag::err_redefinition) 
                 << Function->getDeclName();
-              SemaRef.Diag((*R)->getLocation(), diag::note_previous_definition);
+              SemaRef.Diag(R->getLocation(), diag::note_previous_definition);
               Function->setInvalidDecl();
               break;
             }
         }
       }
     }
-      
   }
 
   if (Function->isOverloadedOperator() && !DC->isRecord() &&
@@ -1231,20 +1233,16 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
     // We are creating a function template specialization from a function
     // template. Check whether there is already a function template
     // specialization for this particular set of template arguments.
-    llvm::FoldingSetNodeID ID;
     std::pair<const TemplateArgument *, unsigned> Innermost 
       = TemplateArgs.getInnermost();
-    FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
-                                                Innermost.second,
-                                                SemaRef.Context);
 
-    FunctionTemplateSpecializationInfo *Info
-      = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
-                                                                   InsertPos);
+    FunctionDecl *SpecFunc
+      = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+                                             InsertPos);
 
     // If we already have a function template specialization, return it.
-    if (Info)
-      return Info->Function;
+    if (SpecFunc)
+      return SpecFunc;
   }
 
   bool isFriend;
@@ -1256,7 +1254,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
   bool MergeWithParentScope = (TemplateParams != 0) ||
     !(isa<Decl>(Owner) && 
       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
-  Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+  LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
 
   llvm::SmallVector<ParmVarDecl *, 4> Params;
   TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1313,39 +1311,27 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
   CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
   CXXMethodDecl *Method = 0;
 
-  DeclarationName Name = D->getDeclName();
+  DeclarationNameInfo NameInfo
+    = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
-    QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
-    Name = SemaRef.Context.DeclarationNames.getCXXConstructorName(
-                                    SemaRef.Context.getCanonicalType(ClassTy));
     Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
-                                        Constructor->getLocation(),
-                                        Name, T, TInfo,
+                                        NameInfo, T, TInfo,
                                         Constructor->isExplicit(),
                                         Constructor->isInlineSpecified(),
                                         false);
   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
-    QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
-    Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
-                                   SemaRef.Context.getCanonicalType(ClassTy));
     Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
-                                       Destructor->getLocation(), Name,
-                                       T, Destructor->isInlineSpecified(),
+                                       NameInfo, T,
+                                       Destructor->isInlineSpecified(),
                                        false);
   } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
-    CanQualType ConvTy
-      = SemaRef.Context.getCanonicalType(
-                                      T->getAs<FunctionType>()->getResultType());
-    Name = SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(
-                                                                      ConvTy);
     Method = CXXConversionDecl::Create(SemaRef.Context, Record,
-                                       Conversion->getLocation(), Name,
-                                       T, TInfo,
+                                       NameInfo, T, TInfo,
                                        Conversion->isInlineSpecified(),
                                        Conversion->isExplicit());
   } else {
-    Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
-                                   D->getDeclName(), T, TInfo,
+    Method = CXXMethodDecl::Create(SemaRef.Context, Record,
+                                   NameInfo, T, TInfo,
                                    D->isStatic(),
                                    D->getStorageClassAsWritten(),
                                    D->isInlineSpecified());
@@ -1409,8 +1395,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
   if (InitMethodInstantiation(Method, D))
     Method->setInvalidDecl();
 
-  LookupResult Previous(SemaRef, Name, SourceLocation(),
-                        Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+  LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
+                        Sema::ForRedeclaration);
 
   if (!FunctionTemplate || TemplateParams || isFriend) {
     SemaRef.LookupQualifiedName(Previous, Record);
@@ -1446,7 +1432,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
     else
       Owner->addDecl(DeclToAdd);
   }
-
+  
   return Method;
 }
 
@@ -1475,8 +1461,8 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
 
   TemplateTypeParmDecl *Inst =
     TemplateTypeParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
-                                 TTPT->getDepth() - 1, TTPT->getIndex(),
-                                 TTPT->getName(),
+                                 TTPT->getDepth() - TemplateArgs.getNumLevels(),
+                                 TTPT->getIndex(),TTPT->getName(),
                                  D->wasDeclaredWithTypename(),
                                  D->isParameterPack());
 
@@ -1517,8 +1503,9 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
   
   NonTypeTemplateParmDecl *Param
     = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
-                                      D->getDepth() - 1, D->getPosition(),
-                                      D->getIdentifier(), T, DI);
+                                    D->getDepth() - TemplateArgs.getNumLevels(), 
+                                      D->getPosition(), D->getIdentifier(), T, 
+                                      DI);
   if (Invalid)
     Param->setInvalidDecl();
   
@@ -1539,7 +1526,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
   {
     // Perform the actual substitution of template parameters within a new,
     // local instantiation scope.
-    Sema::LocalInstantiationScope Scope(SemaRef);
+    LocalInstantiationScope Scope(SemaRef);
     InstParams = SubstTemplateParams(TempParams);
     if (!InstParams)
       return NULL;
@@ -1548,8 +1535,9 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
   // Build the template template parameter.
   TemplateTemplateParmDecl *Param
     = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
-                                       D->getDepth() - 1, D->getPosition(),
-                                       D->getIdentifier(), InstParams);
+                                   D->getDepth() - TemplateArgs.getNumLevels(), 
+                                       D->getPosition(), D->getIdentifier(), 
+                                       InstParams);
   Param->setDefaultArgument(D->getDefaultArgument(), false);
   
   // Introduce this template parameter's instantiation into the instantiation 
@@ -1575,22 +1563,22 @@ Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
 
 Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
   // The nested name specifier is non-dependent, so no transformation
-  // is required.
+  // is required. The same holds for the name info.
+  DeclarationNameInfo NameInfo = D->getNameInfo();
 
   // We only need to do redeclaration lookups if we're in a class
   // scope (in fact, it's not really even possible in non-class
   // scopes).
   bool CheckRedeclaration = Owner->isRecord();
 
-  LookupResult Prev(SemaRef, D->getDeclName(), D->getLocation(),
-                    Sema::LookupUsingDeclName, Sema::ForRedeclaration);
+  LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
+                    Sema::ForRedeclaration);
 
   UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
-                                       D->getLocation(),
                                        D->getNestedNameRange(),
                                        D->getUsingLocation(),
                                        D->getTargetNestedNameDecl(),
-                                       D->getDeclName(),
+                                       NameInfo,
                                        D->isTypeName());
 
   CXXScopeSpec SS;
@@ -1666,10 +1654,12 @@ Decl * TemplateDeclInstantiator
   SS.setRange(D->getTargetNestedNameRange());
   SS.setScopeRep(NNS);
 
+  // Since NameInfo refers to a typename, it cannot be a C++ special name.
+  // Hence, no tranformation is required for it.
+  DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
   NamedDecl *UD =
     SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
-                                  D->getUsingLoc(), SS, D->getLocation(),
-                                  D->getDeclName(), 0,
+                                  D->getUsingLoc(), SS, NameInfo, 0,
                                   /*instantiation*/ true,
                                   /*typename*/ true, D->getTypenameLoc());
   if (UD)
@@ -1691,10 +1681,12 @@ Decl * TemplateDeclInstantiator
   SS.setRange(D->getTargetNestedNameRange());
   SS.setScopeRep(NNS);
 
+  DeclarationNameInfo NameInfo
+    = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
+
   NamedDecl *UD =
     SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
-                                  D->getUsingLoc(), SS, D->getLocation(),
-                                  D->getDeclName(), 0,
+                                  D->getUsingLoc(), SS, NameInfo, 0,
                                   /*instantiation*/ true,
                                   /*typename*/ false, SourceLocation());
   if (UD)
@@ -1735,13 +1727,8 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
   }
 
   // Clean up if we had an error.
-  if (Invalid) {
-    for (ParamVector::iterator PI = Params.begin(), PE = Params.end();
-         PI != PE; ++PI)
-      if (*PI)
-        (*PI)->Destroy(SemaRef.Context);
+  if (Invalid)
     return NULL;
-  }
 
   TemplateParameterList *InstL
     = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
@@ -1767,7 +1754,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
   // Create a local instantiation scope for this class template partial
   // specialization, which will contain the instantiations of the template
   // parameters.
-  Sema::LocalInstantiationScope Scope(SemaRef);
+  LocalInstantiationScope Scope(SemaRef);
   
   // Substitute into the template parameters of the class template partial
   // specialization.
@@ -1804,15 +1791,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
 
   // Figure out where to insert this class template partial specialization
   // in the member template's set of class template partial specializations.
-  llvm::FoldingSetNodeID ID;
-  ClassTemplatePartialSpecializationDecl::Profile(ID,
-                                                  Converted.getFlatArguments(),
-                                                  Converted.flatSize(),
-                                                  SemaRef.Context);
   void *InsertPos = 0;
   ClassTemplateSpecializationDecl *PrevDecl
-    = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
-                                                                     InsertPos);
+    = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+                                                Converted.flatSize(), InsertPos);
   
   // Build the canonical type that describes the converted template
   // arguments of the class template partial specialization.
@@ -1871,7 +1853,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
                                                      InstTemplateArgs,
                                                      CanonType,
                                                      0,
-                             ClassTemplate->getPartialSpecializations().size());
+                             ClassTemplate->getNextPartialSpecSequenceNumber());
   // Substitute the nested name specifier, if any.
   if (SubstQualifier(PartialSpec, InstPartialSpec))
     return 0;
@@ -1881,8 +1863,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
   
   // Add this partial specialization to the set of class template partial
   // specializations.
-  ClassTemplate->getPartialSpecializations().InsertNode(InstPartialSpec,
-                                                        InsertPos);
+  ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
   return false;
 }
 
@@ -2003,7 +1984,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
                                                  Proto->getExtInfo()));
   }
 
-  InstantiateAttrs(Tmpl, New);
+  SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
 
   return false;
 }
@@ -2078,8 +2059,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
         Diag(PatternDecl->getLocation(), 
              diag::note_explicit_instantiation_here);
       Function->setInvalidDecl();
+    } else if (Function->getTemplateSpecializationKind()
+                 == TSK_ExplicitInstantiationDefinition) {
+      PendingInstantiations.push_back(
+        std::make_pair(Function, PointOfInstantiation));
     }
-      
+
     return;
   }
 
@@ -2099,13 +2084,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
   // If we're performing recursive template instantiation, create our own
   // queue of pending implicit instantiations that we will instantiate later,
   // while we're still within our own instantiation context.
-  std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+  std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
   if (Recursive)
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
 
   EnterExpressionEvaluationContext EvalContext(*this, 
-                                               Action::PotentiallyEvaluated);
-  ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
+                                               Sema::PotentiallyEvaluated);
+  ActOnStartOfFunctionDef(0, Function);
 
   // Introduce a new scope where local variable instantiations will be
   // recorded, unless we're actually a member function within a local
@@ -2118,10 +2103,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
   LocalInstantiationScope Scope(*this, MergeWithParentScope);
 
   // Introduce the instantiated function parameters into the local
-  // instantiation scope.
-  for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I)
-    Scope.InstantiatedLocal(PatternDecl->getParamDecl(I),
-                            Function->getParamDecl(I));
+  // instantiation scope, and set the parameter names to those used
+  // in the template.
+  for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
+    const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
+    ParmVarDecl *FunctionParam = Function->getParamDecl(I);
+    FunctionParam->setDeclName(PatternParam->getDeclName());
+    Scope.InstantiatedLocal(PatternParam, FunctionParam);
+  }
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
@@ -2139,12 +2128,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
   }
 
   // Instantiate the function body.
-  OwningStmtResult Body = SubstStmt(Pattern, TemplateArgs);
+  StmtResult Body = SubstStmt(Pattern, TemplateArgs);
 
   if (Body.isInvalid())
     Function->setInvalidDecl();
   
-  ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body),
+  ActOnFinishFunctionBody(Function, Body.get(),
                           /*IsInstantiation=*/true);
 
   PerformDependentDiagnostics(PatternDecl, TemplateArgs);
@@ -2156,16 +2145,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
 
   // This class may have local implicit instantiations that need to be
   // instantiation within this scope.
-  PerformPendingImplicitInstantiations(/*LocalOnly=*/true);
+  PerformPendingInstantiations(/*LocalOnly=*/true);
   Scope.Exit();
 
   if (Recursive) {
     // Instantiate any pending implicit instantiations found during the
     // instantiation of this template.
-    PerformPendingImplicitInstantiations();
+    PerformPendingInstantiations();
 
     // Restore the set of pending implicit instantiations.
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
   }
 }
 
@@ -2210,8 +2199,12 @@ void Sema::InstantiateStaticDataMemberDefinition(
            diag::err_explicit_instantiation_undefined_member)
         << 2 << Var->getDeclName() << Var->getDeclContext();
       Diag(Def->getLocation(), diag::note_explicit_instantiation_here);
-    }    
-    
+    } else if (Var->getTemplateSpecializationKind()
+                 == TSK_ExplicitInstantiationDefinition) {
+      PendingInstantiations.push_back(
+        std::make_pair(Var, PointOfInstantiation));
+    }
+
     return;
   }
 
@@ -2234,9 +2227,9 @@ void Sema::InstantiateStaticDataMemberDefinition(
   // If we're performing recursive template instantiation, create our own
   // queue of pending implicit instantiations that we will instantiate later,
   // while we're still within our own instantiation context.
-  std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+  std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
   if (Recursive)
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
 
   // Enter the scope of this instantiation. We don't use
   // PushDeclContext because we don't have a scope.
@@ -2260,10 +2253,10 @@ void Sema::InstantiateStaticDataMemberDefinition(
   if (Recursive) {
     // Instantiate any pending implicit instantiations found during the
     // instantiation of this template.
-    PerformPendingImplicitInstantiations();
+    PerformPendingInstantiations();
 
     // Restore the set of pending implicit instantiations.
-    PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+    PendingInstantiations.swap(SavedPendingInstantiations);
   }
 }
 
@@ -2281,8 +2274,13 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
        Inits != InitsEnd; ++Inits) {
     CXXBaseOrMemberInitializer *Init = *Inits;
 
+    // Only instantiate written initializers, let Sema re-construct implicit
+    // ones.
+    if (!Init->isWritten())
+      continue;
+
     SourceLocation LParenLoc, RParenLoc;
-    ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+    ASTOwningVector<Expr*> NewArgs(*this);
     llvm::SmallVector<SourceLocation, 4> CommaLocs;
 
     // Instantiate the initializer.
@@ -2341,7 +2339,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
   }
 
   // Assign all the initializers to the new constructor.
-  ActOnMemInitializers(DeclPtrTy::make(New),
+  ActOnMemInitializers(New,
                        /*FIXME: ColonLoc */
                        SourceLocation(),
                        NewInits.data(), NewInits.size(),
@@ -2588,7 +2586,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
   DeclContext *ParentDC = D->getDeclContext();
   if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
       isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
-      ParentDC->isFunctionOrMethod()) {
+      (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) {
     // D is a local of some kind. Look into the map of local
     // declarations to their instantiations.
     return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D));
@@ -2729,14 +2727,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
 
 /// \brief Performs template instantiation for all implicit template
 /// instantiations we have seen until this point.
-void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
+void Sema::PerformPendingInstantiations(bool LocalOnly) {
   while (!PendingLocalImplicitInstantiations.empty() ||
-         (!LocalOnly && !PendingImplicitInstantiations.empty())) {
+         (!LocalOnly && !PendingInstantiations.empty())) {
     PendingImplicitInstantiation Inst;
 
     if (PendingLocalImplicitInstantiations.empty()) {
-      Inst = PendingImplicitInstantiations.front();
-      PendingImplicitInstantiations.pop_front();
+      Inst = PendingInstantiations.front();
+      PendingInstantiations.pop_front();
     } else {
       Inst = PendingLocalImplicitInstantiations.front();
       PendingLocalImplicitInstantiations.pop_front();
@@ -2744,12 +2742,12 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
 
     // Instantiate function definitions
     if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) {
-      PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Function),
-                                            Function->getLocation(), *this,
-                                            Context.getSourceManager(),
-                                           "instantiating function definition");
-
-      InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
+      PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(),
+                                          "instantiating function definition");
+      bool DefinitionRequired = Function->getTemplateSpecializationKind() ==
+                                TSK_ExplicitInstantiationDefinition;
+      InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true,
+                                    DefinitionRequired);
       continue;
     }
 
@@ -2768,20 +2766,24 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
     case TSK_Undeclared:
       assert(false && "Cannot instantitiate an undeclared specialization.");
     case TSK_ExplicitInstantiationDeclaration:
-    case TSK_ExplicitInstantiationDefinition:
     case TSK_ExplicitSpecialization:
-      continue;  // No longer need implicit instantiation.
+      continue;  // No longer need to instantiate this type.
+    case TSK_ExplicitInstantiationDefinition:
+      // We only need an instantiation if the pending instantiation *is* the
+      // explicit instantiation.
+      if (Var != Var->getMostRecentDeclaration()) continue;
     case TSK_ImplicitInstantiation:
       break;
     }
 
-    PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var),
-                                          Var->getLocation(), *this,
-                                          Context.getSourceManager(),
-                                          "instantiating static data member "
-                                          "definition");
+    PrettyDeclStackTraceEntry CrashInfo(*this, Var, Var->getLocation(),
+                                        "instantiating static data member "
+                                        "definition");
 
-    InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true);
+    bool DefinitionRequired = Var->getTemplateSpecializationKind() ==
+                              TSK_ExplicitInstantiationDefinition;
+    InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true,
+                                          DefinitionRequired);
   }
 }
 
@@ -2798,3 +2800,4 @@ void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
     }
   }
 }
+
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index a4fc98c..aa30b5c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -11,7 +11,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Template.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
@@ -20,13 +21,12 @@
 #include "clang/AST/TypeLocVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Parse/DeclSpec.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Sema/DeclSpec.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace clang;
 
-#include <iostream>
-
 /// \brief Perform adjustment on the parameter type of a function.
 ///
 /// This routine adjusts the given parameter type @p T to the actual
@@ -266,8 +266,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
   case DeclSpec::TST_enum:
   case DeclSpec::TST_union:
   case DeclSpec::TST_struct: {
-    TypeDecl *D 
-      = dyn_cast_or_null<TypeDecl>(static_cast<Decl *>(DS.getTypeRep()));
+    TypeDecl *D = dyn_cast_or_null<TypeDecl>(DS.getRepAsDecl());
     if (!D) {
       // This can happen in C++ with ambiguous lookups.
       Result = Context.IntTy;
@@ -299,9 +298,11 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
     assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
            DS.getTypeSpecSign() == 0 &&
            "Can't handle qualifiers on typedef names yet!");
-    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
-
-    if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
+    Result = TheSema.GetTypeFromParser(DS.getRepAsType());
+    if (Result.isNull())
+      TheDeclarator.setInvalidType(true);
+    else if (DeclSpec::ProtocolQualifierListTy PQ
+               = DS.getProtocolQualifiers()) {
       if (const ObjCObjectType *ObjT = Result->getAs<ObjCObjectType>()) {
         // Silently drop any existing protocol qualifiers.
         // TODO: determine whether that's the right thing to do.
@@ -336,13 +337,13 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
   }
   case DeclSpec::TST_typeofType:
     // FIXME: Preserve type source info.
-    Result = TheSema.GetTypeFromParser(DS.getTypeRep());
+    Result = TheSema.GetTypeFromParser(DS.getRepAsType());
     assert(!Result.isNull() && "Didn't get a type for typeof?");
     // TypeQuals handled by caller.
     Result = Context.getTypeOfType(Result);
     break;
   case DeclSpec::TST_typeofExpr: {
-    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    Expr *E = DS.getRepAsExpr();
     assert(E && "Didn't get an expression for typeof?");
     // TypeQuals handled by caller.
     Result = TheSema.BuildTypeofExprType(E);
@@ -353,7 +354,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
     break;
   }
   case DeclSpec::TST_decltype: {
-    Expr *E = static_cast<Expr *>(DS.getTypeRep());
+    Expr *E = DS.getRepAsExpr();
     assert(E && "Didn't get an expression for decltype?");
     // TypeQuals handled by caller.
     Result = TheSema.BuildDecltypeType(E);
@@ -674,10 +675,9 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
       !ArraySize->getType()->isIntegerType()) {
     Diag(ArraySize->getLocStart(), diag::err_array_size_non_int)
       << ArraySize->getType() << ArraySize->getSourceRange();
-    ArraySize->Destroy(Context);
     return QualType();
   }
-  llvm::APSInt ConstVal(32);
+  llvm::APSInt ConstVal(Context.getTypeSize(Context.getSizeType()));
   if (!ArraySize) {
     if (ASM == ArrayType::Star)
       T = Context.getVariableArrayType(T, 0, ASM, Quals, Brackets);
@@ -707,7 +707,17 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
            isSFINAEContext()? diag::err_typecheck_zero_array_size
                             : diag::ext_typecheck_zero_array_size)
         << ArraySize->getSourceRange();
+    } else if (!T->isDependentType() && !T->isVariablyModifiedType() && 
+               !T->isIncompleteType()) {
+      // Is the array too large?      
+      unsigned ActiveSizeBits
+        = ConstantArrayType::getNumAddressingBits(Context, T, ConstVal);
+      if (ActiveSizeBits > ConstantArrayType::getMaxSizeBits(Context))
+        Diag(ArraySize->getLocStart(), diag::err_array_too_large)
+          << ConstVal.toString(10)
+          << ArraySize->getSourceRange();
     }
+    
     T = Context.getConstantArrayType(T, ConstVal, ASM, Quals);
   }
   // If this is not C99, extwarn about VLA's and C99 array size modifiers.
@@ -740,11 +750,8 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM,
 /// \brief Build an ext-vector type.
 ///
 /// Run the required checks for the extended vector type.
-QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
+QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize,
                                   SourceLocation AttrLoc) {
-
-  Expr *Arg = (Expr *)ArraySize.get();
-
   // unlike gcc's vector_size attribute, we do not allow vectors to be defined
   // in conjunction with complex types (pointers, arrays, functions, etc.).
   if (!T->isDependentType() &&
@@ -753,11 +760,11 @@ QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
     return QualType();
   }
 
-  if (!Arg->isTypeDependent() && !Arg->isValueDependent()) {
+  if (!ArraySize->isTypeDependent() && !ArraySize->isValueDependent()) {
     llvm::APSInt vecSize(32);
-    if (!Arg->isIntegerConstantExpr(vecSize, Context)) {
+    if (!ArraySize->isIntegerConstantExpr(vecSize, Context)) {
       Diag(AttrLoc, diag::err_attribute_argument_not_int)
-      << "ext_vector_type" << Arg->getSourceRange();
+        << "ext_vector_type" << ArraySize->getSourceRange();
       return QualType();
     }
 
@@ -767,7 +774,7 @@ QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
 
     if (vectorSize == 0) {
       Diag(AttrLoc, diag::err_attribute_zero_size)
-      << Arg->getSourceRange();
+      << ArraySize->getSourceRange();
       return QualType();
     }
 
@@ -775,8 +782,7 @@ QualType Sema::BuildExtVectorType(QualType T, ExprArg ArraySize,
       return Context.getExtVectorType(T, vectorSize);
   }
 
-  return Context.getDependentSizedExtVectorType(T, ArraySize.takeAs<Expr>(),
-                                                AttrLoc);
+  return Context.getDependentSizedExtVectorType(T, ArraySize, AttrLoc);
 }
 
 /// \brief Build a function type.
@@ -812,7 +818,8 @@ QualType Sema::BuildFunctionType(QualType T,
                                  QualType *ParamTypes,
                                  unsigned NumParamTypes,
                                  bool Variadic, unsigned Quals,
-                                 SourceLocation Loc, DeclarationName Entity) {
+                                 SourceLocation Loc, DeclarationName Entity,
+                                 const FunctionType::ExtInfo &Info) {
   if (T->isArrayType() || T->isFunctionType()) {
     Diag(Loc, diag::err_func_returning_array_function) 
       << T->isFunctionType() << T;
@@ -834,8 +841,7 @@ QualType Sema::BuildFunctionType(QualType T,
     return QualType();
 
   return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
-                                 Quals, false, false, 0, 0,
-                                 FunctionType::ExtInfo());
+                                 Quals, false, false, 0, 0, Info);
 }
 
 /// \brief Build a member pointer type \c T Class::*.
@@ -883,6 +889,14 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
     return QualType();
   }
 
+  // In the Microsoft ABI, the class is allowed to be an incomplete
+  // type. In such cases, the compiler makes a worst-case assumption.
+  // We make no such assumption right now, so emit an error if the
+  // class isn't a complete type.
+  if (Context.Target.getCXXABI() == CXXABI_Microsoft &&
+      RequireCompleteType(Loc, Class, diag::err_incomplete_type))
+    return QualType();
+
   return Context.getMemberPointerType(T, Class.getTypePtr());
 }
 
@@ -912,8 +926,8 @@ QualType Sema::BuildBlockPointerType(QualType T,
   return Context.getBlockPointerType(T);
 }
 
-QualType Sema::GetTypeFromParser(TypeTy *Ty, TypeSourceInfo **TInfo) {
-  QualType QT = QualType::getFromOpaquePtr(Ty);
+QualType Sema::GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo) {
+  QualType QT = Ty.get();
   if (QT.isNull()) {
     if (TInfo) *TInfo = 0;
     return QualType();
@@ -955,7 +969,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
     T = ConvertDeclSpecToType(*this, D, FnAttrsFromDeclSpec);
     
     if (!D.isInvalidType() && D.getDeclSpec().isTypeSpecOwned()) {
-      TagDecl* Owned = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+      TagDecl* Owned = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
       // Owned is embedded if it was defined here, or if it is the
       // very first (i.e., canonical) declaration of this tag type.
       Owned->setEmbeddedInDeclarator(Owned->isDefinition() ||
@@ -1174,7 +1188,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
       if (getLangOptions().CPlusPlus && D.getDeclSpec().isTypeSpecOwned()) {
         // C++ [dcl.fct]p6:
         //   Types shall not be defined in return or parameter types.
-        TagDecl *Tag = cast<TagDecl>((Decl *)D.getDeclSpec().getTypeRep());
+        TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
         if (Tag->isDefinition())
           Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
             << Context.getTypeDeclType(Tag);
@@ -1221,8 +1235,7 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
         ArgTys.reserve(FTI.NumArgs);
 
         for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) {
-          ParmVarDecl *Param =
-            cast<ParmVarDecl>(FTI.ArgInfo[i].Param.getAs<Decl>());
+          ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
           QualType ArgTy = Param->getType();
           assert(!ArgTy.isNull() && "Couldn't parse type?");
 
@@ -1295,19 +1308,19 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
     }
     case DeclaratorChunk::MemberPointer:
       // The scope spec must refer to a class, or be dependent.
+      CXXScopeSpec &SS = DeclType.Mem.Scope();
       QualType ClsType;
-      if (DeclType.Mem.Scope().isInvalid()) {
+      if (SS.isInvalid()) {
         // Avoid emitting extra errors if we already errored on the scope.
         D.setInvalidType(true);
-      } else if (isDependentScopeSpecifier(DeclType.Mem.Scope())
-                 || dyn_cast_or_null<CXXRecordDecl>(
-                                   computeDeclContext(DeclType.Mem.Scope()))) {
+      } else if (isDependentScopeSpecifier(SS) ||
+                 dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS))) {
         NestedNameSpecifier *NNS
-          = (NestedNameSpecifier *)DeclType.Mem.Scope().getScopeRep();
+          = static_cast<NestedNameSpecifier*>(SS.getScopeRep());
         NestedNameSpecifier *NNSPrefix = NNS->getPrefix();
         switch (NNS->getKind()) {
         case NestedNameSpecifier::Identifier:
-          ClsType = Context.getDependentNameType(ETK_None, NNSPrefix, 
+          ClsType = Context.getDependentNameType(ETK_None, NNSPrefix,
                                                  NNS->getAsIdentifier());
           break;
 
@@ -1315,11 +1328,15 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
         case NestedNameSpecifier::Global:
           llvm_unreachable("Nested-name-specifier must name a type");
           break;
-            
+
         case NestedNameSpecifier::TypeSpec:
         case NestedNameSpecifier::TypeSpecWithTemplate:
           ClsType = QualType(NNS->getAsType(), 0);
-          if (NNSPrefix)
+          // Note: if NNS is dependent, then its prefix (if any) is already
+          // included in ClsType; this does not hold if the NNS is
+          // nondependent: in this case (if there is indeed a prefix)
+          // ClsType needs to be wrapped into an elaborated type.
+          if (NNSPrefix && !NNS->isDependent())
             ClsType = Context.getElaboratedType(ETK_None, NNSPrefix, ClsType);
           break;
         }
@@ -1455,7 +1472,7 @@ namespace {
     }
     void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
       TypeSourceInfo *TInfo = 0;
-      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
 
       // If we got no declarator info from previous Sema routines,
       // just fill with the typespec loc.
@@ -1483,9 +1500,9 @@ namespace {
       assert(DS.getTypeSpecType() == DeclSpec::TST_typeofType);
       TL.setTypeofLoc(DS.getTypeSpecTypeLoc());
       TL.setParensRange(DS.getTypeofParensRange());
-      assert(DS.getTypeRep());
+      assert(DS.getRepAsType());
       TypeSourceInfo *TInfo = 0;
-      Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+      Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
       TL.setUnderlyingTInfo(TInfo);
     }
     void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
@@ -1508,7 +1525,7 @@ namespace {
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (Keyword == ETK_Typename) {
         TypeSourceInfo *TInfo = 0;
-        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(cast<ElaboratedTypeLoc>(TInfo->getTypeLoc()));
           return;
@@ -1526,7 +1543,7 @@ namespace {
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (Keyword == ETK_Typename) {
         TypeSourceInfo *TInfo = 0;
-        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(cast<DependentNameTypeLoc>(TInfo->getTypeLoc()));
           return;
@@ -1546,7 +1563,7 @@ namespace {
         = TypeWithKeyword::getKeywordForTypeSpec(DS.getTypeSpecType());
       if (Keyword == ETK_Typename) {
         TypeSourceInfo *TInfo = 0;
-        Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo);
+        Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
         if (TInfo) {
           TL.copy(cast<DependentTemplateSpecializationTypeLoc>(
                     TInfo->getTypeLoc()));
@@ -1620,7 +1637,7 @@ namespace {
 
       const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
       for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) {
-        ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs<ParmVarDecl>();
+        ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param);
         TL.setArg(tpi++, Param);
       }
       // FIXME: exception specs
@@ -1651,24 +1668,21 @@ Sema::GetTypeSourceInfoForDeclarator(Declarator &D, QualType T,
     CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc();
   }
   
-  TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
-  
-  // We have source information for the return type that was not in the
-  // declaration specifiers; copy that information into the current type
-  // location so that it will be retained. This occurs, for example, with 
-  // a C++ conversion function, where the return type occurs within the
-  // declarator-id rather than in the declaration specifiers.
-  if (ReturnTypeInfo && D.getDeclSpec().getTypeSpecType() == TST_unspecified) {
+  // If we have different source information for the return type, use
+  // that.  This really only applies to C++ conversion functions.
+  if (ReturnTypeInfo) {
     TypeLoc TL = ReturnTypeInfo->getTypeLoc();
     assert(TL.getFullDataSize() == CurrTL.getFullDataSize());
     memcpy(CurrTL.getOpaqueData(), TL.getOpaqueData(), TL.getFullDataSize());
+  } else {
+    TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL);
   }
       
   return TInfo;
 }
 
 /// \brief Create a LocInfoType to hold the given QualType and TypeSourceInfo.
-QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
+ParsedType Sema::CreateParsedType(QualType T, TypeSourceInfo *TInfo) {
   // FIXME: LocInfoTypes are "transient", only needed for passing to/from Parser
   // and Sema during declaration parsing. Try deallocating/caching them when
   // it's appropriate, instead of allocating them and keeping them around.
@@ -1676,7 +1690,7 @@ QualType Sema::CreateLocInfoType(QualType T, TypeSourceInfo *TInfo) {
   new (LocT) LocInfoType(T, TInfo);
   assert(LocT->getTypeClass() != T->getTypeClass() &&
          "LocInfoType's TypeClass conflicts with an existing Type class");
-  return QualType(LocT, 0);
+  return ParsedType::make(QualType(LocT, 0));
 }
 
 void LocInfoType::getAsStringInternal(std::string &Str,
@@ -1686,7 +1700,7 @@ void LocInfoType::getAsStringInternal(std::string &Str,
          " GetTypeFromParser");
 }
 
-Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
+TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
   // C99 6.7.6: Type names have no identifier.  This is already validated by
   // the parser.
   assert(D.getIdentifier() == 0 && "Type name should have no identifier!");
@@ -1710,8 +1724,7 @@ Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
         << Context.getTypeDeclType(OwnedTag);
   }
 
-  T = CreateLocInfoType(T, TInfo);
-  return T.getAsOpaquePtr();
+  return CreateParsedType(T, TInfo);
 }
 
 
@@ -1825,9 +1838,10 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
     // Delay if this is not a function or pointer to block.
     if (!Type->isFunctionPointerType()
         && !Type->isBlockPointerType()
-        && !Type->isFunctionType())
+        && !Type->isFunctionType()
+        && !Type->isMemberFunctionPointerType())
       return true;
-
+    
     // Otherwise we can process right away.
     Type = S.Context.getNoReturnType(Type);
     return false;
@@ -1842,7 +1856,8 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
     // Delay if this is not a function or pointer to block.
     if (!Type->isFunctionPointerType()
         && !Type->isBlockPointerType()
-        && !Type->isFunctionType())
+        && !Type->isFunctionType()
+        && !Type->isMemberFunctionPointerType())
       return true;
 
     // Otherwise we can process right away.
@@ -1868,6 +1883,12 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
   QualType T = Type;
   if (const PointerType *PT = Type->getAs<PointerType>())
     T = PT->getPointeeType();
+  else if (const BlockPointerType *BPT = Type->getAs<BlockPointerType>())
+    T = BPT->getPointeeType();
+  else if (const MemberPointerType *MPT = Type->getAs<MemberPointerType>())
+    T = MPT->getPointeeType();
+  else if (const ReferenceType *RT = Type->getAs<ReferenceType>())
+    T = RT->getPointeeType();
   const FunctionType *Fn = T->getAs<FunctionType>();
 
   // Delay if the type didn't work out to a function.
@@ -1880,6 +1901,7 @@ bool ProcessFnAttr(Sema &S, QualType &Type, const AttributeList &Attr) {
   case AttributeList::AT_fastcall: CC = CC_X86FastCall; break;
   case AttributeList::AT_stdcall: CC = CC_X86StdCall; break;
   case AttributeList::AT_thiscall: CC = CC_X86ThisCall; break;
+  case AttributeList::AT_pascal: CC = CC_X86Pascal; break;
   default: llvm_unreachable("unexpected attribute kind"); return false;
   }
 
@@ -1946,8 +1968,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
     return;
   }
   // the base type must be integer or float, and can't already be a vector.
-  if (CurType->isVectorType() ||
-      (!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
+  if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
     S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
     Attr.setInvalid();
     return;
@@ -2008,6 +2029,7 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result,
     case AttributeList::AT_fastcall:
     case AttributeList::AT_stdcall:
     case AttributeList::AT_thiscall:
+    case AttributeList::AT_pascal:
     case AttributeList::AT_regparm:
       // Don't process these on the DeclSpec.
       if (IsDeclSpec ||
diff --git a/lib/Sema/TargetAttributesSema.cpp b/lib/Sema/TargetAttributesSema.cpp
index 87e7b9d..1854e74 100644
--- a/lib/Sema/TargetAttributesSema.cpp
+++ b/lib/Sema/TargetAttributesSema.cpp
@@ -12,9 +12,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "Sema.h"
 #include "TargetAttributesSema.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/AST/DeclCXX.h"
 #include "llvm/ADT/Triple.h"
 
 using namespace clang;
@@ -51,8 +52,8 @@ static void HandleMSP430InterruptAttr(Decl *d,
       return;
     }
 
-    d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
-    d->addAttr(::new (S.Context) UsedAttr());
+    d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+    d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
   }
 
 namespace {
@@ -97,7 +98,7 @@ static void HandleX86ForceAlignArgPointerAttr(Decl *D,
     return;
   }
 
-  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+  D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -109,7 +110,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLImportAttr());
+    D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -146,7 +147,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLImportAttr());
+  D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
 }
 
 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -158,7 +159,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
 
   // Attribute can be applied only to functions or variables.
   if (isa<VarDecl>(D)) {
-    D->addAttr(::new (S.Context) DLLExportAttr());
+    D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
     return;
   }
 
@@ -177,7 +178,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
     return;
   }
 
-  D->addAttr(::new (S.Context) DLLExportAttr());
+  D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
 }
 
 namespace {
diff --git a/lib/Sema/TargetAttributesSema.h b/lib/Sema/TargetAttributesSema.h
index 8794e40..410c900 100644
--- a/lib/Sema/TargetAttributesSema.h
+++ b/lib/Sema/TargetAttributesSema.h
@@ -13,7 +13,7 @@
 namespace clang {
   class Scope;
   class Decl;
-  class Attr;
+  class AttributeList;
   class Sema;
 
   class TargetAttributesSema {
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 17103c5..e7bfbe6 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -13,10 +13,12 @@
 #ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
 #define LLVM_CLANG_SEMA_TREETRANSFORM_H
 
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclObjC.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -24,13 +26,14 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/AST/TypeLocBuilder.h"
-#include "clang/Parse/Ownership.h"
-#include "clang/Parse/Designator.h"
+#include "clang/Sema/Ownership.h"
+#include "clang/Sema/Designator.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <algorithm>
 
 namespace clang {
+using namespace sema;
 
 /// \brief A semantic tree transformation that allows one to transform one
 /// abstract syntax tree into another.
@@ -89,14 +92,6 @@ protected:
   Sema &SemaRef;
 
 public:
-  typedef Sema::OwningStmtResult OwningStmtResult;
-  typedef Sema::OwningExprResult OwningExprResult;
-  typedef Sema::StmtArg StmtArg;
-  typedef Sema::ExprArg ExprArg;
-  typedef Sema::MultiExprArg MultiExprArg;
-  typedef Sema::MultiStmtArg MultiStmtArg;
-  typedef Sema::DeclPtrTy DeclPtrTy;
-  
   /// \brief Initializes a new tree transformer.
   TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
 
@@ -108,6 +103,9 @@ public:
     return static_cast<const Derived&>(*this);
   }
 
+  static inline ExprResult Owned(Expr *E) { return E; }
+  static inline StmtResult Owned(Stmt *S) { return S; }
+
   /// \brief Retrieves a reference to the semantic analysis object used for
   /// this tree transform.
   Sema &getSema() const { return SemaRef; }
@@ -220,7 +218,7 @@ public:
   /// other mechanism.
   ///
   /// \returns the transformed statement.
-  OwningStmtResult TransformStmt(Stmt *S);
+  StmtResult TransformStmt(Stmt *S);
 
   /// \brief Transform the given expression.
   ///
@@ -230,7 +228,7 @@ public:
   /// other mechanism.
   ///
   /// \returns the transformed expression.
-  OwningExprResult TransformExpr(Expr *E);
+  ExprResult TransformExpr(Expr *E);
 
   /// \brief Transform the given declaration, which is referenced from a type
   /// or expression.
@@ -276,9 +274,9 @@ public:
   /// and destructor names and then (if needed) rebuilds the declaration name.
   /// Identifiers and selectors are returned unmodified. Sublcasses may
   /// override this function to provide alternate behavior.
-  DeclarationName TransformDeclarationName(DeclarationName Name,
-                                           SourceLocation Loc,
-                                           QualType ObjectType = QualType());
+  DeclarationNameInfo
+  TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                               QualType ObjectType = QualType());
 
   /// \brief Transform the given template name.
   ///
@@ -337,13 +335,13 @@ public:
   TransformTemplateSpecializationType(const TemplateSpecializationType *T,
                                       QualType ObjectType);
 
-  OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
-  OwningExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
+  StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
+  ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
 
 #define STMT(Node, Parent)                        \
-  OwningStmtResult Transform##Node(Node *S);
+  StmtResult Transform##Node(Node *S);
 #define EXPR(Node, Parent)                        \
-  OwningExprResult Transform##Node(Node *E);
+  ExprResult Transform##Node(Node *E);
 #define ABSTRACT_STMT(Stmt)
 #include "clang/AST/StmtNodes.inc"
 
@@ -421,7 +419,7 @@ public:
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildVariableArrayType(QualType ElementType,
                                     ArrayType::ArraySizeModifier SizeMod,
-                                    ExprArg SizeExpr,
+                                    Expr *SizeExpr,
                                     unsigned IndexTypeQuals,
                                     SourceRange BracketsRange);
 
@@ -432,7 +430,7 @@ public:
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildDependentSizedArrayType(QualType ElementType,
                                           ArrayType::ArraySizeModifier SizeMod,
-                                          ExprArg SizeExpr,
+                                          Expr *SizeExpr,
                                           unsigned IndexTypeQuals,
                                           SourceRange BracketsRange);
 
@@ -458,7 +456,7 @@ public:
   /// By default, performs semantic analysis when building the vector type.
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildDependentSizedExtVectorType(QualType ElementType,
-                                              ExprArg SizeExpr,
+                                              Expr *SizeExpr,
                                               SourceLocation AttributeLoc);
 
   /// \brief Build a new function type.
@@ -468,7 +466,8 @@ public:
   QualType RebuildFunctionProtoType(QualType T,
                                     QualType *ParamTypes,
                                     unsigned NumParamTypes,
-                                    bool Variadic, unsigned Quals);
+                                    bool Variadic, unsigned Quals,
+                                    const FunctionType::ExtInfo &Info);
 
   /// \brief Build a new unprototyped function type.
   QualType RebuildFunctionNoProtoType(QualType ResultType);
@@ -496,7 +495,7 @@ public:
   ///
   /// By default, performs semantic analysis when building the typeof type.
   /// Subclasses may override this routine to provide different behavior.
-  QualType RebuildTypeOfExprType(ExprArg Underlying);
+  QualType RebuildTypeOfExprType(Expr *Underlying);
 
   /// \brief Build a new typeof(type) type.
   ///
@@ -507,7 +506,7 @@ public:
   ///
   /// By default, performs semantic analysis when building the decltype type.
   /// Subclasses may override this routine to provide different behavior.
-  QualType RebuildDecltypeType(ExprArg Underlying);
+  QualType RebuildDecltypeType(Expr *Underlying);
 
   /// \brief Build a new template specialization type.
   ///
@@ -558,7 +557,8 @@ public:
       getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
     if (T.isNull()) return QualType();
 
-    return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
+    // NOTE: NNS is already recorded in template specialization type T.
+    return SemaRef.Context.getElaboratedType(Keyword, /*NNS=*/0, T);
   }
 
   /// \brief Build a new typename type that refers to an identifier.
@@ -707,11 +707,11 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
+  StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
                                        MultiStmtArg Statements,
                                        SourceLocation RBraceLoc,
                                        bool IsStmtExpr) {
-    return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
+    return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
                                        IsStmtExpr);
   }
 
@@ -719,12 +719,12 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
-                                   ExprArg LHS,
+  StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
+                                   Expr *LHS,
                                    SourceLocation EllipsisLoc,
-                                   ExprArg RHS,
+                                   Expr *RHS,
                                    SourceLocation ColonLoc) {
-    return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
+    return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
                                    ColonLoc);
   }
 
@@ -732,19 +732,19 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
-    getSema().ActOnCaseStmtBody(S.get(), move(Body));
-    return move(S);
+  StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
+    getSema().ActOnCaseStmtBody(S, Body);
+    return S;
   }
 
   /// \brief Build a new default statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
+  StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
                                       SourceLocation ColonLoc,
-                                      StmtArg SubStmt) {
-    return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
+                                      Stmt *SubStmt) {
+    return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
                                       /*CurScope=*/0);
   }
 
@@ -752,89 +752,85 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
+  StmtResult RebuildLabelStmt(SourceLocation IdentLoc,
                                     IdentifierInfo *Id,
                                     SourceLocation ColonLoc,
-                                    StmtArg SubStmt) {
-    return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
+                                    Stmt *SubStmt) {
+    return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, SubStmt);
   }
 
   /// \brief Build a new "if" statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
-                                 VarDecl *CondVar, StmtArg Then, 
-                                 SourceLocation ElseLoc, StmtArg Else) {
-    return getSema().ActOnIfStmt(IfLoc, Cond, DeclPtrTy::make(CondVar), 
-                                 move(Then), ElseLoc, move(Else));
+  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
+                                 VarDecl *CondVar, Stmt *Then, 
+                                 SourceLocation ElseLoc, Stmt *Else) {
+    return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
   }
 
   /// \brief Start building a new switch statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
-                                          Sema::ExprArg Cond, 
-                                          VarDecl *CondVar) {
-    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, move(Cond), 
-                                            DeclPtrTy::make(CondVar));
+  StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
+                                          Expr *Cond, VarDecl *CondVar) {
+    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond, 
+                                            CondVar);
   }
 
   /// \brief Attach the body to the switch statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
-                                         StmtArg Switch, StmtArg Body) {
-    return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
-                                         move(Body));
+  StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
+                                         Stmt *Switch, Stmt *Body) {
+    return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
   }
 
   /// \brief Build a new while statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
+  StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
                                     Sema::FullExprArg Cond,
                                     VarDecl *CondVar,
-                                    StmtArg Body) {
-    return getSema().ActOnWhileStmt(WhileLoc, Cond, 
-                                    DeclPtrTy::make(CondVar), move(Body));
+                                    Stmt *Body) {
+    return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);
   }
 
   /// \brief Build a new do-while statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
+  StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
                                  SourceLocation WhileLoc,
                                  SourceLocation LParenLoc,
-                                 ExprArg Cond,
+                                 Expr *Cond,
                                  SourceLocation RParenLoc) {
-    return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
-                                 move(Cond), RParenLoc);
+    return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
+                                 Cond, RParenLoc);
   }
 
   /// \brief Build a new for statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
+  StmtResult RebuildForStmt(SourceLocation ForLoc,
                                   SourceLocation LParenLoc,
-                                  StmtArg Init, Sema::FullExprArg Cond, 
+                                  Stmt *Init, Sema::FullExprArg Cond, 
                                   VarDecl *CondVar, Sema::FullExprArg Inc,
-                                  SourceLocation RParenLoc, StmtArg Body) {
-    return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), Cond, 
-                                  DeclPtrTy::make(CondVar),
-                                  Inc, RParenLoc, move(Body));
+                                  SourceLocation RParenLoc, Stmt *Body) {
+    return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, 
+                                  CondVar,
+                                  Inc, RParenLoc, Body);
   }
 
   /// \brief Build a new goto statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
+  StmtResult RebuildGotoStmt(SourceLocation GotoLoc,
                                    SourceLocation LabelLoc,
                                    LabelStmt *Label) {
     return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
@@ -844,27 +840,27 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
+  StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
                                            SourceLocation StarLoc,
-                                           ExprArg Target) {
-    return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
+                                           Expr *Target) {
+    return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
   }
 
   /// \brief Build a new return statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
-                                     ExprArg Result) {
+  StmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
+                                     Expr *Result) {
 
-    return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
+    return getSema().ActOnReturnStmt(ReturnLoc, Result);
   }
 
   /// \brief Build a new declaration statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
+  StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
                                    SourceLocation StartLoc,
                                    SourceLocation EndLoc) {
     return getSema().Owned(
@@ -878,7 +874,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildAsmStmt(SourceLocation AsmLoc,
+  StmtResult RebuildAsmStmt(SourceLocation AsmLoc,
                                   bool IsSimple,
                                   bool IsVolatile,
                                   unsigned NumOutputs,
@@ -886,13 +882,13 @@ public:
                                   IdentifierInfo **Names,
                                   MultiExprArg Constraints,
                                   MultiExprArg Exprs,
-                                  ExprArg AsmString,
+                                  Expr *AsmString,
                                   MultiExprArg Clobbers,
                                   SourceLocation RParenLoc,
                                   bool MSAsm) {
     return getSema().ActOnAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, 
                                   NumInputs, Names, move(Constraints),
-                                  move(Exprs), move(AsmString), move(Clobbers),
+                                  Exprs, AsmString, Clobbers,
                                   RParenLoc, MSAsm);
   }
 
@@ -900,12 +896,12 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
-                                        StmtArg TryBody,
+  StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
+                                        Stmt *TryBody,
                                         MultiStmtArg CatchStmts,
-                                        StmtArg Finally) {
-    return getSema().ActOnObjCAtTryStmt(AtLoc, move(TryBody), move(CatchStmts),
-                                        move(Finally));
+                                        Stmt *Finally) {
+    return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, move(CatchStmts),
+                                        Finally);
   }
 
   /// \brief Rebuild an Objective-C exception declaration.
@@ -923,59 +919,58 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
+  StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
                                           SourceLocation RParenLoc,
                                           VarDecl *Var,
-                                          StmtArg Body) {
+                                          Stmt *Body) {
     return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
-                                          Sema::DeclPtrTy::make(Var),
-                                          move(Body));
+                                          Var, Body);
   }
   
   /// \brief Build a new Objective-C @finally statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
-                                            StmtArg Body) {
-    return getSema().ActOnObjCAtFinallyStmt(AtLoc, move(Body));
+  StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
+                                            Stmt *Body) {
+    return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
   }
   
   /// \brief Build a new Objective-C @throw statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
-                                          ExprArg Operand) {
-    return getSema().BuildObjCAtThrowStmt(AtLoc, move(Operand));
+  StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
+                                          Expr *Operand) {
+    return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
   }
   
   /// \brief Build a new Objective-C @synchronized statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
-                                                 ExprArg Object,
-                                                 StmtArg Body) {
-    return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, move(Object),
-                                                 move(Body));
+  StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
+                                                 Expr *Object,
+                                                 Stmt *Body) {
+    return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object,
+                                                 Body);
   }
 
   /// \brief Build a new Objective-C fast enumeration statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
-                                                SourceLocation LParenLoc,
-                                                StmtArg Element,
-                                                ExprArg Collection,
-                                                SourceLocation RParenLoc,
-                                                StmtArg Body) {
+  StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
+                                          SourceLocation LParenLoc,
+                                          Stmt *Element,
+                                          Expr *Collection,
+                                          SourceLocation RParenLoc,
+                                          Stmt *Body) {
     return getSema().ActOnObjCForCollectionStmt(ForLoc, LParenLoc,
-                                                move(Element), 
-                                                move(Collection),
+                                                Element, 
+                                                Collection,
                                                 RParenLoc,
-                                                move(Body));
+                                                Body);
   }
   
   /// \brief Build a new C++ exception declaration.
@@ -995,31 +990,30 @@ public:
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
-                                       VarDecl *ExceptionDecl,
-                                       StmtArg Handler) {
-    return getSema().Owned(
-             new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
-                                                  Handler.takeAs<Stmt>()));
+  StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
+                                 VarDecl *ExceptionDecl,
+                                 Stmt *Handler) {
+    return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
+                                                      Handler));
   }
 
   /// \brief Build a new C++ try statement.
   ///
   /// By default, performs semantic analysis to build the new statement.
   /// Subclasses may override this routine to provide different behavior.
-  OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
-                                     StmtArg TryBlock,
-                                     MultiStmtArg Handlers) {
-    return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
+  StmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
+                               Stmt *TryBlock,
+                               MultiStmtArg Handlers) {
+    return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, move(Handlers));
   }
 
   /// \brief Build a new expression that references a declaration.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
-                                              LookupResult &R,
-                                              bool RequiresADL) {
+  ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
+                                        LookupResult &R,
+                                        bool RequiresADL) {
     return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
   }
 
@@ -1028,33 +1022,34 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
-                                      SourceRange QualifierRange,
-                                      ValueDecl *VD, SourceLocation Loc,
-                                      TemplateArgumentListInfo *TemplateArgs) {
+  ExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
+                                SourceRange QualifierRange,
+                                ValueDecl *VD,
+                                const DeclarationNameInfo &NameInfo,
+                                TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setScopeRep(Qualifier);
     SS.setRange(QualifierRange);
 
     // FIXME: loses template args.
-    
-    return getSema().BuildDeclarationNameExpr(SS, Loc, VD);
+
+    return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD);
   }
 
   /// \brief Build a new expression in parentheses.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
+  ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
                                     SourceLocation RParen) {
-    return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
+    return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
   }
 
   /// \brief Build a new pseudo-destructor expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
+  ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
                                                   SourceLocation OperatorLoc,
                                                   bool isArrow,
                                                 NestedNameSpecifier *Qualifier,
@@ -1068,19 +1063,19 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
-                                        UnaryOperator::Opcode Opc,
-                                        ExprArg SubExpr) {
-    return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
+  ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
+                                        UnaryOperatorKind Opc,
+                                        Expr *SubExpr) {
+    return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, SubExpr);
   }
 
   /// \brief Build a new builtin offsetof expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
+  ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
                                        TypeSourceInfo *Type,
-                                       Action::OffsetOfComponent *Components,
+                                       Sema::OffsetOfComponent *Components,
                                        unsigned NumComponents,
                                        SourceLocation RParenLoc) {
     return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
@@ -1091,7 +1086,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildSizeOfAlignOf(TypeSourceInfo *TInfo,
+  ExprResult RebuildSizeOfAlignOf(TypeSourceInfo *TInfo,
                                         SourceLocation OpLoc,
                                         bool isSizeOf, SourceRange R) {
     return getSema().CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeOf, R);
@@ -1102,15 +1097,13 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
+  ExprResult RebuildSizeOfAlignOf(Expr *SubExpr, SourceLocation OpLoc,
                                         bool isSizeOf, SourceRange R) {
-    OwningExprResult Result
-      = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
-                                          OpLoc, isSizeOf, R);
+    ExprResult Result
+      = getSema().CreateSizeOfAlignOfExpr(SubExpr, OpLoc, isSizeOf, R);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
 
-    SubExpr.release();
     return move(Result);
   }
 
@@ -1118,12 +1111,12 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
+  ExprResult RebuildArraySubscriptExpr(Expr *LHS,
                                              SourceLocation LBracketLoc,
-                                             ExprArg RHS,
+                                             Expr *RHS,
                                              SourceLocation RBracketLoc) {
-    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
-                                             LBracketLoc, move(RHS),
+    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, LHS,
+                                             LBracketLoc, RHS,
                                              RBracketLoc);
   }
 
@@ -1131,11 +1124,11 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
+  ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
                                    MultiExprArg Args,
                                    SourceLocation *CommaLocs,
                                    SourceLocation RParenLoc) {
-    return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
+    return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc,
                                    move(Args), CommaLocs, RParenLoc);
   }
 
@@ -1143,11 +1136,11 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
+  ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
                                      bool isArrow,
                                      NestedNameSpecifier *Qualifier,
                                      SourceRange QualifierRange,
-                                     SourceLocation MemberLoc,
+                                     const DeclarationNameInfo &MemberNameInfo,
                                      ValueDecl *Member,
                                      NamedDecl *FoundDecl,
                         const TemplateArgumentListInfo *ExplicitTemplateArgs,
@@ -1156,14 +1149,13 @@ public:
       // We have a reference to an unnamed field.
       assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
 
-      Expr *BaseExpr = Base.takeAs<Expr>();
-      if (getSema().PerformObjectMemberConversion(BaseExpr, Qualifier,
+      if (getSema().PerformObjectMemberConversion(Base, Qualifier,
                                                   FoundDecl, Member))
-        return getSema().ExprError();
+        return ExprError();
 
       MemberExpr *ME =
-        new (getSema().Context) MemberExpr(BaseExpr, isArrow,
-                                           Member, MemberLoc,
+        new (getSema().Context) MemberExpr(Base, isArrow,
+                                           Member, MemberNameInfo,
                                            cast<FieldDecl>(Member)->getType());
       return getSema().Owned(ME);
     }
@@ -1174,19 +1166,16 @@ public:
       SS.setScopeRep(Qualifier);
     }
 
-    Expr *BaseExpr = Base.takeAs<Expr>();
-    getSema().DefaultFunctionArrayConversion(BaseExpr);
-    QualType BaseType = BaseExpr->getType();
+    getSema().DefaultFunctionArrayConversion(Base);
+    QualType BaseType = Base->getType();
 
     // FIXME: this involves duplicating earlier analysis in a lot of
     // cases; we should avoid this when possible.
-    LookupResult R(getSema(), Member->getDeclName(), MemberLoc,
-                   Sema::LookupMemberName);
+    LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
     R.addDecl(FoundDecl);
     R.resolveKind();
 
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(BaseExpr),
-                                              BaseType, OpLoc, isArrow,
+    return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
                                               SS, FirstQualifierInScope,
                                               R, ExplicitTemplateArgs);
   }
@@ -1195,66 +1184,64 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
-                                         BinaryOperator::Opcode Opc,
-                                         ExprArg LHS, ExprArg RHS) {
-    return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, 
-                                LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
+  ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
+                                         BinaryOperatorKind Opc,
+                                         Expr *LHS, Expr *RHS) {
+    return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, LHS, RHS);
   }
 
   /// \brief Build a new conditional operator expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildConditionalOperator(ExprArg Cond,
+  ExprResult RebuildConditionalOperator(Expr *Cond,
                                               SourceLocation QuestionLoc,
-                                              ExprArg LHS,
+                                              Expr *LHS,
                                               SourceLocation ColonLoc,
-                                              ExprArg RHS) {
-    return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
-                                        move(LHS), move(RHS));
+                                              Expr *RHS) {
+    return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
+                                        LHS, RHS);
   }
 
   /// \brief Build a new C-style cast expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
+  ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
                                          TypeSourceInfo *TInfo,
                                          SourceLocation RParenLoc,
-                                         ExprArg SubExpr) {
+                                         Expr *SubExpr) {
     return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
-                                         move(SubExpr));
+                                         SubExpr);
   }
 
   /// \brief Build a new compound literal expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
+  ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
                                               TypeSourceInfo *TInfo,
                                               SourceLocation RParenLoc,
-                                              ExprArg Init) {
+                                              Expr *Init) {
     return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
-                                              move(Init));
+                                              Init);
   }
 
   /// \brief Build a new extended vector element access expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
+  ExprResult RebuildExtVectorElementExpr(Expr *Base,
                                                SourceLocation OpLoc,
                                                SourceLocation AccessorLoc,
                                                IdentifierInfo &Accessor) {
 
     CXXScopeSpec SS;
-    QualType BaseType = ((Expr*) Base.get())->getType();
-    return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+    DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               OpLoc, /*IsArrow*/ false,
                                               SS, /*FirstQualifierInScope*/ 0,
-                                              DeclarationName(&Accessor),
-                                              AccessorLoc,
+                                              NameInfo,
                                               /* TemplateArgs */ 0);
   }
 
@@ -1262,11 +1249,11 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
+  ExprResult RebuildInitList(SourceLocation LBraceLoc,
                                    MultiExprArg Inits,
                                    SourceLocation RBraceLoc,
                                    QualType ResultTy) {
-    OwningExprResult Result
+    ExprResult Result
       = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
     if (Result.isInvalid() || ResultTy->isDependentType())
       return move(Result);
@@ -1282,16 +1269,16 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
+  ExprResult RebuildDesignatedInitExpr(Designation &Desig,
                                              MultiExprArg ArrayExprs,
                                              SourceLocation EqualOrColonLoc,
                                              bool GNUSyntax,
-                                             ExprArg Init) {
-    OwningExprResult Result
+                                             Expr *Init) {
+    ExprResult Result
       = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
-                                           move(Init));
+                                           Init);
     if (Result.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArrayExprs.release();
     return move(Result);
@@ -1302,7 +1289,7 @@ public:
   /// By default, builds the implicit value initialization without performing
   /// any semantic analysis. Subclasses may override this routine to provide
   /// different behavior.
-  OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
+  ExprResult RebuildImplicitValueInitExpr(QualType T) {
     return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
   }
 
@@ -1310,17 +1297,19 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
-                                    QualType T, SourceLocation RParenLoc) {
-    return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
-                                RParenLoc);
+  ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
+                                    Expr *SubExpr, TypeSourceInfo *TInfo,
+                                    SourceLocation RParenLoc) {
+    return getSema().BuildVAArgExpr(BuiltinLoc,
+                                    SubExpr, TInfo,
+                                    RParenLoc);
   }
 
   /// \brief Build a new expression list in parentheses.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
+  ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
                                         MultiExprArg SubExprs,
                                         SourceLocation RParenLoc) {
     return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc, 
@@ -1332,7 +1321,7 @@ public:
   /// By default, performs semantic analysis, using the name of the label
   /// rather than attempting to map the label statement itself.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
+  ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
                                         SourceLocation LabelLoc,
                                         LabelStmt *Label) {
     return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
@@ -1342,22 +1331,22 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
-                                   StmtArg SubStmt,
+  ExprResult RebuildStmtExpr(SourceLocation LParenLoc,
+                                   Stmt *SubStmt,
                                    SourceLocation RParenLoc) {
-    return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
+    return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc);
   }
 
   /// \brief Build a new __builtin_types_compatible_p expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
-                                              QualType T1, QualType T2,
+  ExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+                                              TypeSourceInfo *TInfo1,
+                                              TypeSourceInfo *TInfo2,
                                               SourceLocation RParenLoc) {
-    return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
-                                              T1.getAsOpaquePtr(),
-                                              T2.getAsOpaquePtr(),
+    return getSema().BuildTypesCompatibleExpr(BuiltinLoc,
+                                              TInfo1, TInfo2,
                                               RParenLoc);
   }
 
@@ -1365,11 +1354,11 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
-                                     ExprArg Cond, ExprArg LHS, ExprArg RHS,
+  ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
+                                     Expr *Cond, Expr *LHS, Expr *RHS,
                                      SourceLocation RParenLoc) {
     return SemaRef.ActOnChooseExpr(BuiltinLoc,
-                                   move(Cond), move(LHS), move(RHS),
+                                   Cond, LHS, RHS,
                                    RParenLoc);
   }
 
@@ -1381,11 +1370,11 @@ public:
   /// operator call into a use of a builtin operator, performing
   /// argument-dependent lookup, etc. Subclasses may override this routine to
   /// provide different behavior.
-  OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
+  ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
                                               SourceLocation OpLoc,
-                                              ExprArg Callee,
-                                              ExprArg First,
-                                              ExprArg Second);
+                                              Expr *Callee,
+                                              Expr *First,
+                                              Expr *Second);
 
   /// \brief Build a new C++ "named" cast expression, such as static_cast or
   /// reinterpret_cast.
@@ -1393,57 +1382,57 @@ public:
   /// By default, this routine dispatches to one of the more-specific routines
   /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
                                            Stmt::StmtClass Class,
                                            SourceLocation LAngleLoc,
                                            TypeSourceInfo *TInfo,
                                            SourceLocation RAngleLoc,
                                            SourceLocation LParenLoc,
-                                           ExprArg SubExpr,
+                                           Expr *SubExpr,
                                            SourceLocation RParenLoc) {
     switch (Class) {
     case Stmt::CXXStaticCastExprClass:
       return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
                                                    RAngleLoc, LParenLoc,
-                                                   move(SubExpr), RParenLoc);
+                                                   SubExpr, RParenLoc);
 
     case Stmt::CXXDynamicCastExprClass:
       return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
                                                     RAngleLoc, LParenLoc,
-                                                    move(SubExpr), RParenLoc);
+                                                    SubExpr, RParenLoc);
 
     case Stmt::CXXReinterpretCastExprClass:
       return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
                                                         RAngleLoc, LParenLoc,
-                                                        move(SubExpr),
+                                                        SubExpr,
                                                         RParenLoc);
 
     case Stmt::CXXConstCastExprClass:
       return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
                                                    RAngleLoc, LParenLoc,
-                                                   move(SubExpr), RParenLoc);
+                                                   SubExpr, RParenLoc);
 
     default:
       assert(false && "Invalid C++ named cast");
       break;
     }
 
-    return getSema().ExprError();
+    return ExprError();
   }
 
   /// \brief Build a new C++ static_cast expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
                                             SourceLocation LAngleLoc,
                                             TypeSourceInfo *TInfo,
                                             SourceLocation RAngleLoc,
                                             SourceLocation LParenLoc,
-                                            ExprArg SubExpr,
+                                            Expr *SubExpr,
                                             SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1452,15 +1441,15 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
                                              SourceLocation LAngleLoc,
                                              TypeSourceInfo *TInfo,
                                              SourceLocation RAngleLoc,
                                              SourceLocation LParenLoc,
-                                             ExprArg SubExpr,
+                                             Expr *SubExpr,
                                              SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1469,15 +1458,15 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
                                                  SourceLocation LAngleLoc,
                                                  TypeSourceInfo *TInfo,
                                                  SourceLocation RAngleLoc,
                                                  SourceLocation LParenLoc,
-                                                 ExprArg SubExpr,
+                                                 Expr *SubExpr,
                                                  SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1486,15 +1475,15 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
+  ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
                                            SourceLocation LAngleLoc,
                                            TypeSourceInfo *TInfo,
                                            SourceLocation RAngleLoc,
                                            SourceLocation LParenLoc,
-                                           ExprArg SubExpr,
+                                           Expr *SubExpr,
                                            SourceLocation RParenLoc) {
     return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
-                                       TInfo, move(SubExpr),
+                                       TInfo, SubExpr,
                                        SourceRange(LAngleLoc, RAngleLoc),
                                        SourceRange(LParenLoc, RParenLoc));
   }
@@ -1503,16 +1492,15 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
+  ExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
                                                 TypeSourceInfo *TInfo,
                                                 SourceLocation LParenLoc,
-                                                ExprArg SubExpr,
+                                                Expr *Sub,
                                                 SourceLocation RParenLoc) {
-    void *Sub = SubExpr.takeAs<Expr>();
     return getSema().ActOnCXXTypeConstructExpr(TypeRange,
-                                               TInfo->getType().getAsOpaquePtr(),
+                                             ParsedType::make(TInfo->getType()),
                                                LParenLoc,
-                                         Sema::MultiExprArg(getSema(), &Sub, 1),
+                                               MultiExprArg(&Sub, 1),
                                                /*CommaLocs=*/0,
                                                RParenLoc);
   }
@@ -1521,7 +1509,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+  ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
                                         SourceLocation TypeidLoc,
                                         TypeSourceInfo *Operand,
                                         SourceLocation RParenLoc) {
@@ -1533,11 +1521,11 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
+  ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
                                         SourceLocation TypeidLoc,
-                                        ExprArg Operand,
+                                        Expr *Operand,
                                         SourceLocation RParenLoc) {
-    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, move(Operand),
+    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
                                     RParenLoc);
   }
 
@@ -1546,7 +1534,7 @@ public:
   /// By default, builds a new "this" expression without performing any
   /// semantic analysis. Subclasses may override this routine to provide
   /// different behavior.
-  OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
+  ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
                                       QualType ThisType,
                                       bool isImplicit) {
     return getSema().Owned(
@@ -1558,8 +1546,8 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
-    return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
+  ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub) {
+    return getSema().ActOnCXXThrow(ThrowLoc, Sub);
   }
 
   /// \brief Build a new C++ default-argument expression.
@@ -1567,7 +1555,7 @@ public:
   /// By default, builds a new default-argument expression, which does not
   /// require any semantic analysis. Subclasses may override this routine to
   /// provide different behavior.
-  OwningExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 
+  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 
                                             ParmVarDecl *Param) {
     return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
                                                      Param));
@@ -1577,12 +1565,12 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
+  ExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
                                                SourceLocation LParenLoc,
                                                QualType T,
                                                SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
-                                               T.getAsOpaquePtr(), LParenLoc,
+                                               ParsedType::make(T), LParenLoc,
                                                MultiExprArg(getSema(), 0, 0),
                                                0, RParenLoc);
   }
@@ -1591,7 +1579,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
+  ExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
                                      bool UseGlobal,
                                      SourceLocation PlacementLParen,
                                      MultiExprArg PlacementArgs,
@@ -1600,7 +1588,7 @@ public:
                                      QualType AllocType,
                                      SourceLocation TypeLoc,
                                      SourceRange TypeRange,
-                                     ExprArg ArraySize,
+                                     Expr *ArraySize,
                                      SourceLocation ConstructorLParen,
                                      MultiExprArg ConstructorArgs,
                                      SourceLocation ConstructorRParen) {
@@ -1612,7 +1600,7 @@ public:
                                  AllocType,
                                  TypeLoc,
                                  TypeRange,
-                                 move(ArraySize),
+                                 ArraySize,
                                  ConstructorLParen,
                                  move(ConstructorArgs),
                                  ConstructorRParen);
@@ -1622,25 +1610,25 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
+  ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
                                         bool IsGlobalDelete,
                                         bool IsArrayForm,
-                                        ExprArg Operand) {
+                                        Expr *Operand) {
     return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
-                                    move(Operand));
+                                    Operand);
   }
 
   /// \brief Build a new unary type trait expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
+  ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,
                                          QualType T,
                                          SourceLocation RParenLoc) {
     return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
-                                         T.getAsOpaquePtr(), RParenLoc);
+                                         ParsedType::make(T), RParenLoc);
   }
 
   /// \brief Build a new (previously unresolved) declaration reference
@@ -1648,27 +1636,26 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
+  ExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
                                                 SourceRange QualifierRange,
-                                                DeclarationName Name,
-                                                SourceLocation Location,
+                                       const DeclarationNameInfo &NameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setRange(QualifierRange);
     SS.setScopeRep(NNS);
 
     if (TemplateArgs)
-      return getSema().BuildQualifiedTemplateIdExpr(SS, Name, Location,
+      return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo,
                                                     *TemplateArgs);
 
-    return getSema().BuildQualifiedDeclarationNameExpr(SS, Name, Location);
+    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo);
   }
 
   /// \brief Build a new template-id expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
+  ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
                                          LookupResult &R,
                                          bool RequiresADL,
                               const TemplateArgumentListInfo &TemplateArgs) {
@@ -1679,32 +1666,35 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXConstructExpr(QualType T,
+  ExprResult RebuildCXXConstructExpr(QualType T,
                                            SourceLocation Loc,
                                            CXXConstructorDecl *Constructor,
                                            bool IsElidable,
-                                           MultiExprArg Args) {
-    ASTOwningVector<&ActionBase::DeleteExpr> ConvertedArgs(SemaRef);
+                                           MultiExprArg Args,
+                                           bool RequiresZeroInit,
+                             CXXConstructExpr::ConstructionKind ConstructKind) {
+    ASTOwningVector<Expr*> ConvertedArgs(SemaRef);
     if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc, 
                                           ConvertedArgs))
-      return getSema().ExprError();
+      return ExprError();
     
     return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
-                                           move_arg(ConvertedArgs));
+                                           move_arg(ConvertedArgs),
+                                           RequiresZeroInit, ConstructKind);
   }
 
   /// \brief Build a new object-construction expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
+  ExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
                                                  QualType T,
                                                  SourceLocation LParenLoc,
                                                  MultiExprArg Args,
                                                  SourceLocation *Commas,
                                                  SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
-                                               T.getAsOpaquePtr(),
+                                               ParsedType::make(T),
                                                LParenLoc,
                                                move(Args),
                                                Commas,
@@ -1715,7 +1705,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
+  ExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
                                                      QualType T,
                                                      SourceLocation LParenLoc,
                                                      MultiExprArg Args,
@@ -1723,7 +1713,7 @@ public:
                                                      SourceLocation RParenLoc) {
     return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
                                                            /*FIXME*/LParenLoc),
-                                               T.getAsOpaquePtr(),
+                                               ParsedType::make(T),
                                                LParenLoc,
                                                move(Args),
                                                Commas,
@@ -1734,31 +1724,31 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
+  ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
                                                   QualType BaseType,
                                                   bool IsArrow,
                                                   SourceLocation OperatorLoc,
                                               NestedNameSpecifier *Qualifier,
                                                   SourceRange QualifierRange,
                                             NamedDecl *FirstQualifierInScope,
-                                                  DeclarationName Name,
-                                                  SourceLocation MemberLoc,
+                                   const DeclarationNameInfo &MemberNameInfo,
                               const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
     SS.setRange(QualifierRange);
     SS.setScopeRep(Qualifier);
 
-    return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+    return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
                                             SS, FirstQualifierInScope,
-                                            Name, MemberLoc, TemplateArgs);
+                                            MemberNameInfo,
+                                            TemplateArgs);
   }
 
   /// \brief Build a new member reference expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildUnresolvedMemberExpr(ExprArg BaseE,
+  ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE,
                                                QualType BaseType,
                                                SourceLocation OperatorLoc,
                                                bool IsArrow,
@@ -1771,7 +1761,7 @@ public:
     SS.setRange(QualifierRange);
     SS.setScopeRep(Qualifier);
 
-    return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
+    return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
                                             OperatorLoc, IsArrow,
                                             SS, FirstQualifierInScope,
                                             R, TemplateArgs);
@@ -1781,7 +1771,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
+  ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
                                          TypeSourceInfo *EncodeTypeInfo,
                                          SourceLocation RParenLoc) {
     return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
@@ -1789,7 +1779,7 @@ public:
   }
 
   /// \brief Build a new Objective-C class message.
-  OwningExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
+  ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
                                           Selector Sel,
                                           ObjCMethodDecl *Method,
                                           SourceLocation LBracLoc, 
@@ -1803,15 +1793,14 @@ public:
   }
 
   /// \brief Build a new Objective-C instance message.
-  OwningExprResult RebuildObjCMessageExpr(ExprArg Receiver,
+  ExprResult RebuildObjCMessageExpr(Expr *Receiver,
                                           Selector Sel,
                                           ObjCMethodDecl *Method,
                                           SourceLocation LBracLoc, 
                                           MultiExprArg Args,
                                           SourceLocation RBracLoc) {
-    QualType ReceiverType = static_cast<Expr *>(Receiver.get())->getType();
-    return SemaRef.BuildInstanceMessage(move(Receiver),
-                                        ReceiverType,
+    return SemaRef.BuildInstanceMessage(Receiver,
+                                        Receiver->getType(),
                                         /*SuperLoc=*/SourceLocation(),
                                         Sel, Method, LBracLoc, RBracLoc,
                                         move(Args));
@@ -1821,26 +1810,25 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildObjCIvarRefExpr(ExprArg BaseArg, ObjCIvarDecl *Ivar,
+  ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
                                           SourceLocation IvarLoc,
                                           bool IsArrow, bool IsFreeIvar) {
     // FIXME: We lose track of the IsFreeIvar bit.
     CXXScopeSpec SS;
-    Expr *Base = BaseArg.takeAs<Expr>();
+    Expr *Base = BaseArg;
     LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
                    Sema::LookupMemberName);
-    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
                                                          /*FIME:*/IvarLoc,
-                                                         SS, DeclPtrTy(),
+                                                         SS, 0,
                                                          false);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
     
     if (Result.get())
       return move(Result);
     
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
-                                              Base->getType(),
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               /*FIXME:*/IvarLoc, IsArrow, SS, 
                                               /*FirstQualifierInScope=*/0,
                                               R, 
@@ -1851,26 +1839,24 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildObjCPropertyRefExpr(ExprArg BaseArg, 
+  ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, 
                                               ObjCPropertyDecl *Property,
                                               SourceLocation PropertyLoc) {
     CXXScopeSpec SS;
-    Expr *Base = BaseArg.takeAs<Expr>();
+    Expr *Base = BaseArg;
     LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
                    Sema::LookupMemberName);
     bool IsArrow = false;
-    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
                                                          /*FIME:*/PropertyLoc,
-                                                         SS, DeclPtrTy(),
-                                                         false);
+                                                         SS, 0, false);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
     
     if (Result.get())
       return move(Result);
     
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
-                                              Base->getType(),
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               /*FIXME:*/PropertyLoc, IsArrow, 
                                               SS, 
                                               /*FirstQualifierInScope=*/0,
@@ -1883,43 +1869,41 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.  
-  OwningExprResult RebuildObjCImplicitSetterGetterRefExpr(
+  ExprResult RebuildObjCImplicitSetterGetterRefExpr(
                                                         ObjCMethodDecl *Getter,
                                                           QualType T,
                                                         ObjCMethodDecl *Setter,
                                                         SourceLocation NameLoc,
-                                                          ExprArg Base) {
+                                                          Expr *Base) {
     // Since these expressions can only be value-dependent, we do not need to
     // perform semantic analysis again.
-    return getSema().Owned(
+    return Owned(
              new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T,
                                                                      Setter,
                                                                      NameLoc,
-                                                          Base.takeAs<Expr>()));
+                                                                     Base));
   }
 
   /// \brief Build a new Objective-C "isa" expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildObjCIsaExpr(ExprArg BaseArg, SourceLocation IsaLoc,
+  ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
                                       bool IsArrow) {
     CXXScopeSpec SS;
-    Expr *Base = BaseArg.takeAs<Expr>();
+    Expr *Base = BaseArg;
     LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
                    Sema::LookupMemberName);
-    OwningExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
+    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
                                                          /*FIME:*/IsaLoc,
-                                                         SS, DeclPtrTy(),
-                                                         false);
+                                                         SS, 0, false);
     if (Result.isInvalid())
-      return getSema().ExprError();
+      return ExprError();
     
     if (Result.get())
       return move(Result);
     
-    return getSema().BuildMemberReferenceExpr(getSema().Owned(Base), 
-                                              Base->getType(),
+    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
                                               /*FIXME:*/IsaLoc, IsArrow, SS, 
                                               /*FirstQualifierInScope=*/0,
                                               R, 
@@ -1930,7 +1914,7 @@ public:
   ///
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
-  OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
+  ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
                                             MultiExprArg SubExprs,
                                             SourceLocation RParenLoc) {
     // Find the declaration for __builtin_shufflevector
@@ -1954,12 +1938,12 @@ public:
                                                        Subs, NumSubExprs,
                                                    Builtin->getCallResultType(),
                                                        RParenLoc);
-    OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
+    ExprResult OwnedCall(SemaRef.Owned(TheCall));
 
     // Type-check the __builtin_shufflevector expression.
-    OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
+    ExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
     if (Result.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     OwnedCall.release();
     return move(Result);
@@ -1967,7 +1951,7 @@ public:
 };
 
 template<typename Derived>
-Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
+StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
   if (!S)
     return SemaRef.Owned(S);
 
@@ -1986,11 +1970,11 @@ Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
 #define EXPR(Node, Parent) case Stmt::Node##Class:
 #include "clang/AST/StmtNodes.inc"
     {
-      Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
+      ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
       if (E.isInvalid())
-        return getSema().StmtError();
+        return StmtError();
 
-      return getSema().ActOnExprStmt(getSema().MakeFullExpr(E));
+      return getSema().ActOnExprStmt(getSema().MakeFullExpr(E.take()));
     }
   }
 
@@ -1999,7 +1983,7 @@ Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
 
 
 template<typename Derived>
-Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
+ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
   if (!E)
     return SemaRef.Owned(E);
 
@@ -2094,12 +2078,13 @@ TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
 }
 
 template<typename Derived>
-DeclarationName
-TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
-                                                 SourceLocation Loc,
-                                                 QualType ObjectType) {
+DeclarationNameInfo
+TreeTransform<Derived>
+::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
+                               QualType ObjectType) {
+  DeclarationName Name = NameInfo.getName();
   if (!Name)
-    return Name;
+    return DeclarationNameInfo();
 
   switch (Name.getNameKind()) {
   case DeclarationName::Identifier:
@@ -2109,24 +2094,41 @@ TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
   case DeclarationName::CXXOperatorName:
   case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
-    return Name;
+    return NameInfo;
 
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName: {
-    TemporaryBase Rebase(*this, Loc, Name);
-    QualType T = getDerived().TransformType(Name.getCXXNameType(), 
-                                            ObjectType);
-    if (T.isNull())
-      return DeclarationName();
+    TypeSourceInfo *NewTInfo;
+    CanQualType NewCanTy;
+    if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
+       NewTInfo = getDerived().TransformType(OldTInfo, ObjectType);
+       if (!NewTInfo)
+         return DeclarationNameInfo();
+       NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
+    }
+    else {
+      NewTInfo = 0;
+      TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
+      QualType NewT = getDerived().TransformType(Name.getCXXNameType(),
+                                                 ObjectType);
+      if (NewT.isNull())
+        return DeclarationNameInfo();
+      NewCanTy = SemaRef.Context.getCanonicalType(NewT);
+    }
 
-    return SemaRef.Context.DeclarationNames.getCXXSpecialName(
-                                                           Name.getNameKind(),
-                                          SemaRef.Context.getCanonicalType(T));
+    DeclarationName NewName
+      = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
+                                                           NewCanTy);
+    DeclarationNameInfo NewNameInfo(NameInfo);
+    NewNameInfo.setName(NewName);
+    NewNameInfo.setNamedTypeInfo(NewTInfo);
+    return NewNameInfo;
   }
   }
 
-  return DeclarationName();
+  assert(0 && "Unknown name kind.");
+  return DeclarationNameInfo();
 }
 
 template<typename Derived>
@@ -2268,14 +2270,9 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
     Expr *SourceExpr = Input.getSourceDeclExpression();
     if (SourceExpr) {
       EnterExpressionEvaluationContext Unevaluated(getSema(),
-                                                   Action::Unevaluated);
-      Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
-      if (E.isInvalid())
-        SourceExpr = NULL;
-      else {
-        SourceExpr = E.takeAs<Expr>();
-        SourceExpr->Retain();
-      }
+                                                   Sema::Unevaluated);
+      ExprResult E = getDerived().TransformExpr(SourceExpr);
+      SourceExpr = (E.isInvalid() ? 0 : E.take());
     }
 
     Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
@@ -2298,18 +2295,15 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
   case TemplateArgument::Expression: {
     // Template argument expressions are not potentially evaluated.
     EnterExpressionEvaluationContext Unevaluated(getSema(),
-                                                 Action::Unevaluated);
+                                                 Sema::Unevaluated);
 
     Expr *InputExpr = Input.getSourceExpression();
     if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
 
-    Sema::OwningExprResult E
+    ExprResult E
       = getDerived().TransformExpr(InputExpr);
     if (E.isInvalid()) return true;
-
-    Expr *ETaken = E.takeAs<Expr>();
-    ETaken->Retain();
-    Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
+    Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
     return false;
   }
 
@@ -2631,7 +2625,7 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
 
   Expr *Size = TL.getSizeExpr();
   if (Size) {
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
     Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
   }
   NewTL.setSizeExpr(Size);
@@ -2679,14 +2673,14 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
     return QualType();
 
   // Array bounds are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult SizeResult
+  ExprResult SizeResult
     = getDerived().TransformExpr(T->getSizeExpr());
   if (SizeResult.isInvalid())
     return QualType();
 
-  Expr *Size = static_cast<Expr*>(SizeResult.get());
+  Expr *Size = SizeResult.take();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
@@ -2694,13 +2688,12 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
       Size != T->getSizeExpr()) {
     Result = getDerived().RebuildVariableArrayType(ElementType,
                                                    T->getSizeModifier(),
-                                                   move(SizeResult),
+                                                   Size,
                                              T->getIndexTypeCVRQualifiers(),
                                                    TL.getBracketsRange());
     if (Result.isNull())
       return QualType();
   }
-  else SizeResult.take();
   
   VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
   NewTL.setLBracketLoc(TL.getLBracketLoc());
@@ -2721,9 +2714,9 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
     return QualType();
 
   // Array bounds are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult SizeResult
+  ExprResult SizeResult
     = getDerived().TransformExpr(T->getSizeExpr());
   if (SizeResult.isInvalid())
     return QualType();
@@ -2736,7 +2729,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
       Size != T->getSizeExpr()) {
     Result = getDerived().RebuildDependentSizedArrayType(ElementType,
                                                          T->getSizeModifier(),
-                                                         move(SizeResult),
+                                                         Size,
                                                 T->getIndexTypeCVRQualifiers(),
                                                         TL.getBracketsRange());
     if (Result.isNull())
@@ -2767,9 +2760,9 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
     return QualType();
 
   // Vector sizes are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
+  ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
   if (Size.isInvalid())
     return QualType();
 
@@ -2778,12 +2771,11 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
       ElementType != T->getElementType() ||
       Size.get() != T->getSizeExpr()) {
     Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
-                                                         move(Size),
+                                                             Size.take(),
                                                          T->getAttributeLoc());
     if (Result.isNull())
       return QualType();
   }
-  else Size.take();
 
   // Result might be dependent or not.
   if (isa<DependentSizedExtVectorType>(Result)) {
@@ -2911,18 +2903,25 @@ QualType
 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                                    FunctionProtoTypeLoc TL,
                                                    QualType ObjectType) {
-  // Transform the parameters. We do this first for the benefit of template
-  // instantiations, so that the ParmVarDecls get/ placed into the template
-  // instantiation scope before we transform the function type.
+  // Transform the parameters and return type.
+  //
+  // We instantiate in source order, with the return type first followed by
+  // the parameters, because users tend to expect this (even if they shouldn't
+  // rely on it!).
+  //
+  // FIXME: When we implement late-specified return types, we'll need to
+  // instantiate the return tpe *after* the parameter types in that case,
+  // since the return type can then refer to the parameters themselves (via
+  // decltype, sizeof, etc.).
   llvm::SmallVector<QualType, 4> ParamTypes;
   llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
-  if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls))
-    return QualType();
-  
   FunctionProtoType *T = TL.getTypePtr();
   QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
   if (ResultType.isNull())
     return QualType();
+
+  if (getDerived().TransformFunctionTypeParams(TL, ParamTypes, ParamDecls))
+    return QualType();  
   
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
@@ -2932,7 +2931,8 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
                                                    ParamTypes.data(),
                                                    ParamTypes.size(),
                                                    T->isVariadic(),
-                                                   T->getTypeQuals());
+                                                   T->getTypeQuals(),
+                                                   T->getExtInfo());
     if (Result.isNull())
       return QualType();
   }
@@ -3022,16 +3022,16 @@ QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
                                                       TypeOfExprTypeLoc TL,
                                                        QualType ObjectType) {
   // typeof expressions are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
+  ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
   if (E.isInvalid())
     return QualType();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       E.get() != TL.getUnderlyingExpr()) {
-    Result = getDerived().RebuildTypeOfExprType(move(E));
+    Result = getDerived().RebuildTypeOfExprType(E.get());
     if (Result.isNull())
       return QualType();
   }
@@ -3077,16 +3077,16 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
   DecltypeType *T = TL.getTypePtr();
 
   // decltype expressions are not potentially evaluated contexts
-  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
-  Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
+  ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
   if (E.isInvalid())
     return QualType();
 
   QualType Result = TL.getType();
   if (getDerived().AlwaysRebuild() ||
       E.get() != T->getUnderlyingExpr()) {
-    Result = getDerived().RebuildDecltypeType(move(E));
+    Result = getDerived().RebuildDecltypeType(E.get());
     if (Result.isNull())
       return QualType();
   }
@@ -3432,33 +3432,45 @@ TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
 // Statement transformation
 //===----------------------------------------------------------------------===//
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
   return getDerived().TransformCompoundStmt(S, false);
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
                                               bool IsStmtExpr) {
+  bool SubStmtInvalid = false;
   bool SubStmtChanged = false;
-  ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
+  ASTOwningVector<Stmt*> Statements(getSema());
   for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
        B != BEnd; ++B) {
-    OwningStmtResult Result = getDerived().TransformStmt(*B);
-    if (Result.isInvalid())
-      return getSema().StmtError();
+    StmtResult Result = getDerived().TransformStmt(*B);
+    if (Result.isInvalid()) {
+      // Immediately fail if this was a DeclStmt, since it's very
+      // likely that this will cause problems for future statements.
+      if (isa<DeclStmt>(*B))
+        return StmtError();
+
+      // Otherwise, just keep processing substatements and fail later.
+      SubStmtInvalid = true;
+      continue;
+    }
 
     SubStmtChanged = SubStmtChanged || Result.get() != *B;
     Statements.push_back(Result.takeAs<Stmt>());
   }
 
+  if (SubStmtInvalid)
+    return StmtError();
+
   if (!getDerived().AlwaysRebuild() &&
       !SubStmtChanged)
     return SemaRef.Owned(S->Retain());
@@ -3470,75 +3482,75 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
-  OwningExprResult LHS(SemaRef), RHS(SemaRef);
+  ExprResult LHS, RHS;
   {
     // The case value expressions are not potentially evaluated.
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
     // Transform the left-hand case value.
     LHS = getDerived().TransformExpr(S->getLHS());
     if (LHS.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
 
     // Transform the right-hand case value (for the GNU case-range extension).
     RHS = getDerived().TransformExpr(S->getRHS());
     if (RHS.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
   }
 
   // Build the case statement.
   // Case statements are always rebuilt so that they will attached to their
   // transformed switch statement.
-  OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
-                                                       move(LHS),
+  StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
+                                                       LHS.get(),
                                                        S->getEllipsisLoc(),
-                                                       move(RHS),
+                                                       RHS.get(),
                                                        S->getColonLoc());
   if (Case.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the statement following the case
-  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Attach the body to the case statement
-  return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
+  return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
   // Transform the statement following the default case
-  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Default statements are always rebuilt
   return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
-                                         move(SubStmt));
+                                         SubStmt.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
-  OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
+  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
   if (SubStmt.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // FIXME: Pass the real colon location in.
   SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
   return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
-                                       move(SubStmt));
+                                       SubStmt.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
   // Transform the condition
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3547,56 +3559,56 @@ TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
   
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     
     // Convert the condition to a boolean value.
     if (S->getCond()) {
-      OwningExprResult CondE = getSema().ActOnBooleanCondition(0, 
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, 
                                                                S->getIfLoc(), 
-                                                               move(Cond));
+                                                               Cond.get());
       if (CondE.isInvalid())
-        return getSema().StmtError();
+        return StmtError();
     
-      Cond = move(CondE);
+      Cond = CondE.get();
     }
   }
   
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
-  if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
-    return SemaRef.StmtError();
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+    return StmtError();
   
   // Transform the "then" branch.
-  OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
+  StmtResult Then = getDerived().TransformStmt(S->getThen());
   if (Then.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the "else" branch.
-  OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
+  StmtResult Else = getDerived().TransformStmt(S->getElse());
   if (Else.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
-      FullCond->get() == S->getCond() &&
+      FullCond.get() == S->getCond() &&
       ConditionVar == S->getConditionVariable() &&
       Then.get() == S->getThen() &&
       Else.get() == S->getElse())
     return SemaRef.Owned(S->Retain());
 
   return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
-                                    move(Then),
-                                    S->getElseLoc(), move(Else));
+                                    Then.get(),
+                                    S->getElseLoc(), Else.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
   // Transform the condition.
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3605,36 +3617,36 @@ TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
     
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
   }
 
   // Rebuild the switch statement.
-  OwningStmtResult Switch
-    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), move(Cond),
+  StmtResult Switch
+    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),
                                           ConditionVar);
   if (Switch.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the body of the switch statement.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Complete the switch statement.
-  return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
-                                            move(Body));
+  return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
+                                            Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
   // Transform the condition
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3643,76 +3655,76 @@ TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
     
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
 
     if (S->getCond()) {
       // Convert the condition to a boolean value.
-      OwningExprResult CondE = getSema().ActOnBooleanCondition(0, 
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, 
                                                              S->getWhileLoc(), 
-                                                               move(Cond));
+                                                               Cond.get());
       if (CondE.isInvalid())
-        return getSema().StmtError();
-      Cond = move(CondE);
+        return StmtError();
+      Cond = CondE;
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));
-  if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
-    return SemaRef.StmtError();
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+    return StmtError();
 
   // Transform the body
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
-      FullCond->get() == S->getCond() &&
+      FullCond.get() == S->getCond() &&
       ConditionVar == S->getConditionVariable() &&
       Body.get() == S->getBody())
-    return SemaRef.Owned(S->Retain());
+    return Owned(S);
 
   return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
-                                       ConditionVar, move(Body));
+                                       ConditionVar, Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
   // Transform the body
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the condition
-  OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
+  ExprResult Cond = getDerived().TransformExpr(S->getCond());
   if (Cond.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == S->getCond() &&
       Body.get() == S->getBody())
     return SemaRef.Owned(S->Retain());
 
-  return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
-                                    /*FIXME:*/S->getWhileLoc(), move(Cond),
+  return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
+                                    /*FIXME:*/S->getWhileLoc(), Cond.get(),
                                     S->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
   // Transform the initialization statement
-  OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
+  StmtResult Init = getDerived().TransformStmt(S->getInit());
   if (Init.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the condition
-  OwningExprResult Cond(SemaRef);
+  ExprResult Cond;
   VarDecl *ConditionVar = 0;
   if (S->getConditionVariable()) {
     ConditionVar 
@@ -3721,57 +3733,57 @@ TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
                                       S->getConditionVariable()->getLocation(),
                                                     S->getConditionVariable()));
     if (!ConditionVar)
-      return SemaRef.StmtError();
+      return StmtError();
   } else {
     Cond = getDerived().TransformExpr(S->getCond());
     
     if (Cond.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
 
     if (S->getCond()) {
       // Convert the condition to a boolean value.
-      OwningExprResult CondE = getSema().ActOnBooleanCondition(0, 
+      ExprResult CondE = getSema().ActOnBooleanCondition(0, 
                                                                S->getForLoc(), 
-                                                               move(Cond));
+                                                               Cond.get());
       if (CondE.isInvalid())
-        return getSema().StmtError();
+        return StmtError();
 
-      Cond = move(CondE);
+      Cond = CondE.get();
     }
   }
 
-  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond));  
-  if (!S->getConditionVariable() && S->getCond() && !FullCond->get())
-    return SemaRef.StmtError();
+  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));  
+  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+    return StmtError();
 
   // Transform the increment
-  OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
+  ExprResult Inc = getDerived().TransformExpr(S->getInc());
   if (Inc.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
-  Sema::FullExprArg FullInc(getSema().MakeFullExpr(Inc));
-  if (S->getInc() && !FullInc->get())
-    return SemaRef.StmtError();
+  Sema::FullExprArg FullInc(getSema().MakeFullExpr(Inc.get()));
+  if (S->getInc() && !FullInc.get())
+    return StmtError();
 
   // Transform the body
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
       Init.get() == S->getInit() &&
-      FullCond->get() == S->getCond() &&
+      FullCond.get() == S->getCond() &&
       Inc.get() == S->getInc() &&
       Body.get() == S->getBody())
     return SemaRef.Owned(S->Retain());
 
   return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
-                                     move(Init), FullCond, ConditionVar,
-                                     FullInc, S->getRParenLoc(), move(Body));
+                                     Init.get(), FullCond, ConditionVar,
+                                     FullInc, S->getRParenLoc(), Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
   // Goto statements must always be rebuilt, to resolve the label.
   return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
@@ -3779,46 +3791,46 @@ TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
-  OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
+  ExprResult Target = getDerived().TransformExpr(S->getTarget());
   if (Target.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
       Target.get() == S->getTarget())
     return SemaRef.Owned(S->Retain());
 
   return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
-                                              move(Target));
+                                              Target.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
-  Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
+  ExprResult Result = getDerived().TransformExpr(S->getRetValue());
   if (Result.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // FIXME: We always rebuild the return statement because there is no way
   // to tell whether the return type of the function has changed.
-  return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
+  return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
   bool DeclChanged = false;
   llvm::SmallVector<Decl *, 4> Decls;
@@ -3827,7 +3839,7 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
     Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(),
                                                          *D);
     if (!Transformed)
-      return SemaRef.StmtError();
+      return StmtError();
 
     if (Transformed != *D)
       DeclChanged = true;
@@ -3843,22 +3855,22 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
   assert(false && "SwitchCase is abstract and cannot be transformed");
   return SemaRef.Owned(S->Retain());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
   
-  ASTOwningVector<&ActionBase::DeleteExpr> Constraints(getSema());
-  ASTOwningVector<&ActionBase::DeleteExpr> Exprs(getSema());
+  ASTOwningVector<Expr*> Constraints(getSema());
+  ASTOwningVector<Expr*> Exprs(getSema());
   llvm::SmallVector<IdentifierInfo *, 4> Names;
 
-  OwningExprResult AsmString(SemaRef);
-  ASTOwningVector<&ActionBase::DeleteExpr> Clobbers(getSema());
+  ExprResult AsmString;
+  ASTOwningVector<Expr*> Clobbers(getSema());
 
   bool ExprsChanged = false;
   
@@ -3871,13 +3883,13 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
     
     // Transform the output expr.
     Expr *OutputExpr = S->getOutputExpr(I);
-    OwningExprResult Result = getDerived().TransformExpr(OutputExpr);
+    ExprResult Result = getDerived().TransformExpr(OutputExpr);
     if (Result.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     
     ExprsChanged |= Result.get() != OutputExpr;
     
-    Exprs.push_back(Result.takeAs<Expr>());
+    Exprs.push_back(Result.get());
   }
   
   // Go through the inputs.
@@ -3889,13 +3901,13 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
     
     // Transform the input expr.
     Expr *InputExpr = S->getInputExpr(I);
-    OwningExprResult Result = getDerived().TransformExpr(InputExpr);
+    ExprResult Result = getDerived().TransformExpr(InputExpr);
     if (Result.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     
     ExprsChanged |= Result.get() != InputExpr;
     
-    Exprs.push_back(Result.takeAs<Expr>());
+    Exprs.push_back(Result.get());
   }
   
   if (!getDerived().AlwaysRebuild() && !ExprsChanged)
@@ -3916,7 +3928,7 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
                                      Names.data(),
                                      move_arg(Constraints),
                                      move_arg(Exprs),
-                                     move(AsmString),
+                                     AsmString.get(),
                                      move_arg(Clobbers),
                                      S->getRParenLoc(),
                                      S->isMSAsm());
@@ -3924,31 +3936,31 @@ TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
 
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
   // Transform the body of the @try.
-  OwningStmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
+  StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
   if (TryBody.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the @catch statements (if present).
   bool AnyCatchChanged = false;
-  ASTOwningVector<&ActionBase::DeleteStmt> CatchStmts(SemaRef);
+  ASTOwningVector<Stmt*> CatchStmts(SemaRef);
   for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
-    OwningStmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
+    StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
     if (Catch.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
     if (Catch.get() != S->getCatchStmt(I))
       AnyCatchChanged = true;
     CatchStmts.push_back(Catch.release());
   }
   
   // Transform the @finally statement (if present).
-  OwningStmtResult Finally(SemaRef);
+  StmtResult Finally;
   if (S->getFinallyStmt()) {
     Finally = getDerived().TransformStmt(S->getFinallyStmt());
     if (Finally.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
   }
 
   // If nothing changed, just retain this statement.
@@ -3959,12 +3971,12 @@ TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
     return SemaRef.Owned(S->Retain());
   
   // Build a new statement.
-  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), move(TryBody),
-                                           move_arg(CatchStmts), move(Finally));
+  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
+                                           move_arg(CatchStmts), Finally.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
   // Transform the @catch parameter, if there is one.
   VarDecl *Var = 0;
@@ -3973,7 +3985,7 @@ TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
     if (FromVar->getTypeSourceInfo()) {
       TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
       if (!TSInfo)
-        return SemaRef.StmtError();
+        return StmtError();
     }
     
     QualType T;
@@ -3982,30 +3994,30 @@ TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
     else {
       T = getDerived().TransformType(FromVar->getType());
       if (T.isNull())
-        return SemaRef.StmtError();        
+        return StmtError();        
     }
     
     Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
     if (!Var)
-      return SemaRef.StmtError();
+      return StmtError();
   }
   
-  OwningStmtResult Body = getDerived().TransformStmt(S->getCatchBody());
+  StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), 
                                              S->getRParenLoc(),
-                                             Var, move(Body));
+                                             Var, Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
   // Transform the body.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
+  StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
@@ -4014,39 +4026,39 @@ TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
 
   // Build a new statement.
   return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
-                                               move(Body));
+                                               Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
-  OwningExprResult Operand(SemaRef);
+  ExprResult Operand;
   if (S->getThrowExpr()) {
     Operand = getDerived().TransformExpr(S->getThrowExpr());
     if (Operand.isInvalid())
-      return getSema().StmtError();
+      return StmtError();
   }
   
   if (!getDerived().AlwaysRebuild() &&
       Operand.get() == S->getThrowExpr())
     return getSema().Owned(S->Retain());
     
-  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), move(Operand));
+  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
                                                   ObjCAtSynchronizedStmt *S) {
   // Transform the object we are locking.
-  OwningExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
+  ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
   if (Object.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the body.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getSynchBody());
+  StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // If nothing change, just retain the current statement.
   if (!getDerived().AlwaysRebuild() &&
@@ -4056,27 +4068,27 @@ TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
 
   // Build a new statement.
   return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
-                                                    move(Object), move(Body));
+                                                    Object.get(), Body.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformObjCForCollectionStmt(
                                                   ObjCForCollectionStmt *S) {
   // Transform the element statement.
-  OwningStmtResult Element = getDerived().TransformStmt(S->getElement());
+  StmtResult Element = getDerived().TransformStmt(S->getElement());
   if (Element.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the collection expression.
-  OwningExprResult Collection = getDerived().TransformExpr(S->getCollection());
+  ExprResult Collection = getDerived().TransformExpr(S->getCollection());
   if (Collection.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // Transform the body.
-  OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
+  StmtResult Body = getDerived().TransformStmt(S->getBody());
   if (Body.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
   
   // If nothing changed, just retain this statement.
   if (!getDerived().AlwaysRebuild() &&
@@ -4088,15 +4100,15 @@ TreeTransform<Derived>::TransformObjCForCollectionStmt(
   // Build a new statement.
   return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
                                                    /*FIXME:*/S->getForLoc(),
-                                                   move(Element),
-                                                   move(Collection),
+                                                   Element.get(),
+                                                   Collection.get(),
                                                    S->getRParenLoc(),
-                                                   move(Body));
+                                                   Body.get());
 }
 
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
   // Transform the exception declaration, if any.
   VarDecl *Var = 0;
@@ -4107,7 +4119,7 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
 
     QualType T = getDerived().TransformType(ExceptionDecl->getType());
     if (T.isNull())
-      return SemaRef.StmtError();
+      return StmtError();
 
     Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
                                             T,
@@ -4116,20 +4128,14 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
                                             ExceptionDecl->getLocation(),
                                             /*FIXME: Inaccurate*/
                                     SourceRange(ExceptionDecl->getLocation()));
-    if (!Var || Var->isInvalidDecl()) {
-      if (Var)
-        Var->Destroy(SemaRef.Context);
-      return SemaRef.StmtError();
-    }
+    if (!Var || Var->isInvalidDecl())
+      return StmtError();
   }
 
   // Transform the actual exception handler.
-  OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
-  if (Handler.isInvalid()) {
-    if (Var)
-      Var->Destroy(SemaRef.Context);
-    return SemaRef.StmtError();
-  }
+  StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
+  if (Handler.isInvalid())
+    return StmtError();
 
   if (!getDerived().AlwaysRebuild() &&
       !Var &&
@@ -4138,26 +4144,26 @@ TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
 
   return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
                                           Var,
-                                          move(Handler));
+                                          Handler.get());
 }
 
 template<typename Derived>
-Sema::OwningStmtResult
+StmtResult
 TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
   // Transform the try block itself.
-  OwningStmtResult TryBlock
+  StmtResult TryBlock
     = getDerived().TransformCompoundStmt(S->getTryBlock());
   if (TryBlock.isInvalid())
-    return SemaRef.StmtError();
+    return StmtError();
 
   // Transform the handlers.
   bool HandlerChanged = false;
-  ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
+  ASTOwningVector<Stmt*> Handlers(SemaRef);
   for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
-    OwningStmtResult Handler
+    StmtResult Handler
       = getDerived().TransformCXXCatchStmt(S->getHandler(I));
     if (Handler.isInvalid())
-      return SemaRef.StmtError();
+      return StmtError();
 
     HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
     Handlers.push_back(Handler.takeAs<Stmt>());
@@ -4168,7 +4174,7 @@ TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
       !HandlerChanged)
     return SemaRef.Owned(S->Retain());
 
-  return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
+  return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
                                         move_arg(Handlers));
 }
 
@@ -4176,32 +4182,40 @@ TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
 // Expression transformation
 //===----------------------------------------------------------------------===//
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
   NestedNameSpecifier *Qualifier = 0;
   if (E->getQualifier()) {
     Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                        E->getQualifierRange());
     if (!Qualifier)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   ValueDecl *ND
     = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
                                                          E->getDecl()));
   if (!ND)
-    return SemaRef.ExprError();
+    return ExprError();
 
-  if (!getDerived().AlwaysRebuild() && 
+  DeclarationNameInfo NameInfo = E->getNameInfo();
+  if (NameInfo.getName()) {
+    NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+    if (!NameInfo.getName())
+      return ExprError();
+  }
+
+  if (!getDerived().AlwaysRebuild() &&
       Qualifier == E->getQualifier() &&
       ND == E->getDecl() &&
-      !E->hasExplicitTemplateArgumentList()) {
+      NameInfo.getName() == E->getDecl()->getDeclName() &&
+      !E->hasExplicitTemplateArgs()) {
 
     // Mark it referenced in the new context regardless.
     // FIXME: this is a bit instantiation-specific.
@@ -4211,88 +4225,88 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
   }
 
   TemplateArgumentListInfo TransArgs, *TemplateArgs = 0;
-  if (E->hasExplicitTemplateArgumentList()) {
+  if (E->hasExplicitTemplateArgs()) {
     TemplateArgs = &TransArgs;
     TransArgs.setLAngleLoc(E->getLAngleLoc());
     TransArgs.setRAngleLoc(E->getRAngleLoc());
     for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
       TemplateArgumentLoc Loc;
       if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
-        return SemaRef.ExprError();
+        return ExprError();
       TransArgs.addArgument(Loc);
     }
   }
 
   return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
-                                         ND, E->getLocation(), TemplateArgs);
+                                         ND, NameInfo, TemplateArgs);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
+  return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
                                        E->getRParen());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
                                            E->getOpcode(),
-                                           move(SubExpr));
+                                           SubExpr.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
   // Transform the type.
   TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
   if (!Type)
-    return getSema().ExprError();
+    return ExprError();
   
   // Transform all of the components into components similar to what the
   // parser uses.
@@ -4301,7 +4315,7 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
   // the fields again. However, __builtin_offsetof is rare enough in 
   // template code that we don't care.
   bool ExprChanged = false;
-  typedef Action::OffsetOfComponent Component;
+  typedef Sema::OffsetOfComponent Component;
   typedef OffsetOfExpr::OffsetOfNode Node;
   llvm::SmallVector<Component, 4> Components;
   for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
@@ -4313,13 +4327,13 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
     switch (ON.getKind()) {
     case Node::Array: {
       Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
-      OwningExprResult Index = getDerived().TransformExpr(FromIndex);
+      ExprResult Index = getDerived().TransformExpr(FromIndex);
       if (Index.isInvalid())
-        return getSema().ExprError();
+        return ExprError();
       
       ExprChanged = ExprChanged || Index.get() != FromIndex;
       Comp.isBrackets = true;
-      Comp.U.E = Index.takeAs<Expr>(); // FIXME: leaked
+      Comp.U.E = Index.get();
       break;
     }
         
@@ -4353,14 +4367,14 @@ TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
   if (E->isArgumentType()) {
     TypeSourceInfo *OldT = E->getArgumentTypeInfo();
 
     TypeSourceInfo *NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
 
     if (!getDerived().AlwaysRebuild() && OldT == NewT)
       return SemaRef.Owned(E->Retain());
@@ -4370,36 +4384,36 @@ TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
                                              E->getSourceRange());
   }
 
-  Sema::OwningExprResult SubExpr(SemaRef);
+  ExprResult SubExpr;
   {
     // C++0x [expr.sizeof]p1:
     //   The operand is either an expression, which is an unevaluated operand
     //   [...]
-    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
 
     SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
     if (SubExpr.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
       return SemaRef.Owned(E->Retain());
   }
 
-  return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
+  return getDerived().RebuildSizeOfAlignOf(SubExpr.get(), E->getOperatorLoc(),
                                            E->isSizeOf(),
                                            E->getSourceRange());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4407,35 +4421,35 @@ TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
       RHS.get() == E->getRHS())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildArraySubscriptExpr(move(LHS),
+  return getDerived().RebuildArraySubscriptExpr(LHS.get(),
                                            /*FIXME:*/E->getLHS()->getLocStart(),
-                                                move(RHS),
+                                                RHS.get(),
                                                 E->getRBracketLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
   // Transform the callee.
-  OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
   if (Callee.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform arguments.
   bool ArgChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     // FIXME: Wrong source location information for the ','.
     FakeCommaLocs.push_back(
        SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
 
     ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
-    Args.push_back(Arg.takeAs<Expr>());
+    Args.push_back(Arg.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4446,18 +4460,18 @@ TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
   // FIXME: Wrong source location information for the '('.
   SourceLocation FakeLParenLoc
     = ((Expr *)Callee.get())->getSourceRange().getBegin();
-  return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
+  return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
                                       move_arg(Args),
                                       FakeCommaLocs.data(),
                                       E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   NestedNameSpecifier *Qualifier = 0;
   if (E->hasQualifier()) {
@@ -4465,14 +4479,14 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
       = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                   E->getQualifierRange());
     if (Qualifier == 0)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   ValueDecl *Member
     = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
                                                          E->getMemberDecl()));
   if (!Member)
-    return SemaRef.ExprError();
+    return ExprError();
 
   NamedDecl *FoundDecl = E->getFoundDecl();
   if (FoundDecl == E->getMemberDecl()) {
@@ -4481,7 +4495,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
     FoundDecl = cast_or_null<NamedDecl>(
                    getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
     if (!FoundDecl)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -4489,7 +4503,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
       Qualifier == E->getQualifier() &&
       Member == E->getMemberDecl() &&
       FoundDecl == E->getFoundDecl() &&
-      !E->hasExplicitTemplateArgumentList()) {
+      !E->hasExplicitTemplateArgs()) {
     
     // Mark it referenced in the new context regardless.
     // FIXME: this is a bit instantiation-specific.
@@ -4498,13 +4512,13 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
   }
 
   TemplateArgumentListInfo TransArgs;
-  if (E->hasExplicitTemplateArgumentList()) {
+  if (E->hasExplicitTemplateArgs()) {
     TransArgs.setLAngleLoc(E->getLAngleLoc());
     TransArgs.setRAngleLoc(E->getRAngleLoc());
     for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
       TemplateArgumentLoc Loc;
       if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
-        return SemaRef.ExprError();
+        return ExprError();
       TransArgs.addArgument(Loc);
     }
   }
@@ -4519,28 +4533,28 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
   // nested-name-qualifier (and therefore could do the lookup).
   NamedDecl *FirstQualifierInScope = 0;
 
-  return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
+  return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
                                         E->isArrow(),
                                         Qualifier,
                                         E->getQualifierRange(),
-                                        E->getMemberLoc(),
+                                        E->getMemberNameInfo(),
                                         Member,
                                         FoundDecl,
-                                        (E->hasExplicitTemplateArgumentList()
+                                        (E->hasExplicitTemplateArgs()
                                            ? &TransArgs : 0),
                                         FirstQualifierInScope);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       LHS.get() == E->getLHS() &&
@@ -4548,30 +4562,30 @@ TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
-                                            move(LHS), move(RHS));
+                                            LHS.get(), RHS.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCompoundAssignOperator(
                                                       CompoundAssignOperator *E) {
   return getDerived().TransformBinaryOperator(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
-  OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+  ExprResult Cond = getDerived().TransformExpr(E->getCond());
   if (Cond.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == E->getCond() &&
@@ -4579,15 +4593,15 @@ TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
       RHS.get() == E->getRHS())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildConditionalOperator(move(Cond),
+  return getDerived().RebuildConditionalOperator(Cond.get(),
                                                  E->getQuestionLoc(),
-                                                 move(LHS),
+                                                 LHS.get(),
                                                  E->getColonLoc(),
-                                                 move(RHS));
+                                                 RHS.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
   // Implicit casts are eliminated during transformation, since they
   // will be recomputed by semantic analysis after transformation.
@@ -4595,7 +4609,7 @@ TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
   TypeSourceInfo *OldT;
   TypeSourceInfo *NewT;
@@ -4608,13 +4622,13 @@ TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
     OldT = E->getTypeInfoAsWritten();
     NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  OwningExprResult SubExpr
+  ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -4624,20 +4638,20 @@ TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
   return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
                                             NewT,
                                             E->getRParenLoc(),
-                                            move(SubExpr));
+                                            SubExpr.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
   TypeSourceInfo *OldT = E->getTypeSourceInfo();
   TypeSourceInfo *NewT = getDerived().TransformType(OldT);
   if (!NewT)
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
+  ExprResult Init = getDerived().TransformExpr(E->getInitializer());
   if (Init.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -4650,15 +4664,15 @@ TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
 
   return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT,
                                    /*FIXME:*/E->getInitializer()->getLocEnd(),
-                                                 move(Init));
+                                                 Init.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
@@ -4667,24 +4681,24 @@ TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
   // FIXME: Bad source location
   SourceLocation FakeOperatorLoc
     = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
-  return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
+  return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc,
                                                   E->getAccessorLoc(),
                                                   E->getAccessor());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
   bool InitChanged = false;
 
-  ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+  ASTOwningVector<Expr*, 4> Inits(SemaRef);
   for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
-    OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
+    ExprResult Init = getDerived().TransformExpr(E->getInit(I));
     if (Init.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     InitChanged = InitChanged || Init.get() != E->getInit(I);
-    Inits.push_back(Init.takeAs<Expr>());
+    Inits.push_back(Init.get());
   }
 
   if (!getDerived().AlwaysRebuild() && !InitChanged)
@@ -4695,17 +4709,17 @@ TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
   Designation Desig;
 
   // transform the initializer value
-  OwningExprResult Init = getDerived().TransformExpr(E->getInit());
+  ExprResult Init = getDerived().TransformExpr(E->getInit());
   if (Init.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // transform the designators.
-  ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
+  ASTOwningVector<Expr*, 4> ArrayExprs(SemaRef);
   bool ExprChanged = false;
   for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
                                              DEnd = E->designators_end();
@@ -4718,9 +4732,9 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
     }
 
     if (D->isArrayDesignator()) {
-      OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
+      ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
       if (Index.isInvalid())
-        return SemaRef.ExprError();
+        return ExprError();
 
       Desig.AddDesignator(Designator::getArray(Index.get(),
                                                D->getLBracketLoc()));
@@ -4731,14 +4745,14 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
     }
 
     assert(D->isArrayRangeDesignator() && "New kind of designator?");
-    OwningExprResult Start
+    ExprResult Start
       = getDerived().TransformExpr(E->getArrayRangeStart(*D));
     if (Start.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
-    OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
+    ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
     if (End.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     Desig.AddDesignator(Designator::getArrayRange(Start.get(),
                                                   End.get(),
@@ -4759,11 +4773,11 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
 
   return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
                                                 E->getEqualOrColonLoc(),
-                                                E->usesGNUSyntax(), move(Init));
+                                                E->usesGNUSyntax(), Init.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformImplicitValueInitExpr(
                                                      ImplicitValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
@@ -4772,7 +4786,7 @@ TreeTransform<Derived>::TransformImplicitValueInitExpr(
   // need to transform the type?
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
@@ -4782,44 +4796,37 @@ TreeTransform<Derived>::TransformImplicitValueInitExpr(
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
-  // FIXME: Do we want the type as written?
-  QualType T;
+  TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
+  if (!TInfo)
+    return ExprError();
 
-  {
-    // FIXME: Source location isn't quite accurate.
-    TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
-    T = getDerived().TransformType(E->getType());
-    if (T.isNull())
-      return SemaRef.ExprError();
-  }
-
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
-      T == E->getType() &&
+      TInfo == E->getWrittenTypeInfo() &&
       SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
-                                       T, E->getRParenLoc());
+  return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
+                                       TInfo, E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
+  ASTOwningVector<Expr*, 4> Inits(SemaRef);
   for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
-    OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
+    ExprResult Init = getDerived().TransformExpr(E->getExpr(I));
     if (Init.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
-    Inits.push_back(Init.takeAs<Expr>());
+    Inits.push_back(Init.get());
   }
 
   return getDerived().RebuildParenListExpr(E->getLParenLoc(),
@@ -4833,69 +4840,67 @@ TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
 /// rebuilds the expression, so that the label identifier can be resolved to
 /// the corresponding label statement by semantic analysis.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
   return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
                                            E->getLabel());
 }
 
 template<typename Derived>
-Sema::OwningExprResult 
+ExprResult 
 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
-  OwningStmtResult SubStmt
+  StmtResult SubStmt
     = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
   if (SubStmt.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       SubStmt.get() == E->getSubStmt())
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildStmtExpr(E->getLParenLoc(),
-                                      move(SubStmt),
+                                      SubStmt.get(),
                                       E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
-  QualType T1, T2;
-  {
-    // FIXME: Source location isn't quite accurate.
-    TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
-
-    T1 = getDerived().TransformType(E->getArgType1());
-    if (T1.isNull())
-      return SemaRef.ExprError();
+  TypeSourceInfo *TInfo1;
+  TypeSourceInfo *TInfo2;
+  
+  TInfo1 = getDerived().TransformType(E->getArgTInfo1());
+  if (!TInfo1)
+    return ExprError();
 
-    T2 = getDerived().TransformType(E->getArgType2());
-    if (T2.isNull())
-      return SemaRef.ExprError();
-  }
+  TInfo2 = getDerived().TransformType(E->getArgTInfo2());
+  if (!TInfo2)
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
-      T1 == E->getArgType1() &&
-      T2 == E->getArgType2())
+      TInfo1 == E->getArgTInfo1() &&
+      TInfo2 == E->getArgTInfo2())
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
-                                                 T1, T2, E->getRParenLoc());
+                                                 TInfo1, TInfo2,
+                                                 E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
-  OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
+  ExprResult Cond = getDerived().TransformExpr(E->getCond());
   if (Cond.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
+  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
   if (LHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
+  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
   if (RHS.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Cond.get() == E->getCond() &&
@@ -4904,18 +4909,18 @@ TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
     return SemaRef.Owned(E->Retain());
 
   return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
-                                        move(Cond), move(LHS), move(RHS),
+                                        Cond.get(), LHS.get(), RHS.get(),
                                         E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   switch (E->getOperator()) {
   case OO_New:
@@ -4923,16 +4928,16 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
   case OO_Array_New:
   case OO_Array_Delete:
     llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
-    return SemaRef.ExprError();
+    return ExprError();
     
   case OO_Call: {
     // This is a call to an object's operator().
     assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
 
     // Transform the object itself.
-    OwningExprResult Object = getDerived().TransformExpr(E->getArg(0));
+    ExprResult Object = getDerived().TransformExpr(E->getArg(0));
     if (Object.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     // FIXME: Poor location information
     SourceLocation FakeLParenLoc
@@ -4940,15 +4945,15 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
                               static_cast<Expr *>(Object.get())->getLocEnd());
 
     // Transform the call arguments.
-    ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+    ASTOwningVector<Expr*> Args(SemaRef);
     llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
     for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) {
       if (getDerived().DropCallArgument(E->getArg(I)))
         break;
       
-      OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+      ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
       if (Arg.isInvalid())
-        return SemaRef.ExprError();
+        return ExprError();
 
       // FIXME: Poor source location information.
       SourceLocation FakeCommaLoc
@@ -4958,7 +4963,7 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
       Args.push_back(Arg.release());
     }
 
-    return getDerived().RebuildCallExpr(move(Object), FakeLParenLoc,
+    return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc,
                                         move_arg(Args),
                                         FakeCommaLocs.data(),
                                         E->getLocEnd());
@@ -4974,27 +4979,27 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
 
   case OO_Conditional:
     llvm_unreachable("conditional operator is not actually overloadable");
-    return SemaRef.ExprError();
+    return ExprError();
 
   case OO_None:
   case NUM_OVERLOADED_OPERATORS:
     llvm_unreachable("not an overloaded operator?");
-    return SemaRef.ExprError();
+    return ExprError();
   }
 
-  OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
+  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
   if (Callee.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
+  ExprResult First = getDerived().TransformExpr(E->getArg(0));
   if (First.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  OwningExprResult Second(SemaRef);
+  ExprResult Second;
   if (E->getNumArgs() == 2) {
     Second = getDerived().TransformExpr(E->getArg(1));
     if (Second.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -5005,19 +5010,19 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
 
   return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
                                                  E->getOperatorLoc(),
-                                                 move(Callee),
-                                                 move(First),
-                                                 move(Second));
+                                                 Callee.get(),
+                                                 First.get(),
+                                                 Second.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
   return getDerived().TransformCallExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
   TypeSourceInfo *OldT;
   TypeSourceInfo *NewT;
@@ -5030,13 +5035,13 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
     OldT = E->getTypeInfoAsWritten();
     NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  OwningExprResult SubExpr
+  ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -5056,37 +5061,37 @@ TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
                                               NewT,
                                               FakeRAngleLoc,
                                               FakeRAngleLoc,
-                                              move(SubExpr),
+                                              SubExpr.get(),
                                               FakeRParenLoc);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
                                                       CXXReinterpretCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
   return getDerived().TransformCXXNamedCastExpr(E);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
                                                      CXXFunctionalCastExpr *E) {
   TypeSourceInfo *OldT;
@@ -5097,13 +5102,13 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
     OldT = E->getTypeInfoAsWritten();
     NewT = getDerived().TransformType(OldT);
     if (!NewT)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  OwningExprResult SubExpr
+  ExprResult SubExpr
     = getDerived().TransformExpr(E->getSubExprAsWritten());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       OldT == NewT &&
@@ -5115,18 +5120,18 @@ TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
                                   /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
                                                    NewT,
                                       /*FIXME:*/E->getSubExpr()->getLocStart(),
-                                                   move(SubExpr),
+                                                   SubExpr.get(),
                                                    E->getRParenLoc());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
   if (E->isTypeOperand()) {
     TypeSourceInfo *TInfo
       = getDerived().TransformType(E->getTypeOperandSourceInfo());
     if (!TInfo)
-      return SemaRef.ExprError();
+      return ExprError();
 
     if (!getDerived().AlwaysRebuild() &&
         TInfo == E->getTypeOperandSourceInfo())
@@ -5142,11 +5147,11 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
   // after we perform semantic analysis, so the expression is potentially
   // potentially evaluated.
   EnterExpressionEvaluationContext Unevaluated(SemaRef,
-                                      Action::PotentiallyPotentiallyEvaluated);
+                                      Sema::PotentiallyPotentiallyEvaluated);
 
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getExprOperand())
@@ -5154,31 +5159,31 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
 
   return getDerived().RebuildCXXTypeidExpr(E->getType(),
                                            E->getLocStart(),
-                                           move(SubExpr),
+                                           SubExpr.get(),
                                            E->getLocEnd());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
                                                      CXXNullPtrLiteralExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
@@ -5188,27 +5193,27 @@ TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
-  OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
+  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
   if (SubExpr.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       SubExpr.get() == E->getSubExpr())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
+  return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   ParmVarDecl *Param
     = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(),
                                                            E->getParam()));
   if (!Param)
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       Param == E->getParam())
@@ -5218,13 +5223,13 @@ TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType())
@@ -5237,40 +5242,40 @@ TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
   // Transform the type that we're allocating
   TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
   QualType AllocType = getDerived().TransformType(E->getAllocatedType());
   if (AllocType.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform the size of the array we're allocating (if any).
-  OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
+  ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
   if (ArraySize.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform the placement arguments (if any).
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
+  ASTOwningVector<Expr*> PlacementArgs(SemaRef);
   for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
     PlacementArgs.push_back(Arg.take());
   }
 
   // transform the constructor arguments (if any).
-  ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
+  ASTOwningVector<Expr*> ConstructorArgs(SemaRef);
   for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
     if (getDerived().DropCallArgument(E->getConstructorArg(I)))
       break;
     
-    OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
     ConstructorArgs.push_back(Arg.take());
@@ -5283,7 +5288,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
                                    getDerived().TransformDecl(E->getLocStart(),
                                                          E->getConstructor()));
     if (!Constructor)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   FunctionDecl *OperatorNew = 0;
@@ -5292,7 +5297,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
                                  getDerived().TransformDecl(E->getLocStart(),
                                                          E->getOperatorNew()));
     if (!OperatorNew)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
   FunctionDecl *OperatorDelete = 0;
@@ -5301,7 +5306,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
                                    getDerived().TransformDecl(E->getLocStart(),
                                                        E->getOperatorDelete()));
     if (!OperatorDelete)
-      return SemaRef.ExprError();
+      return ExprError();
   }
   
   if (!getDerived().AlwaysRebuild() &&
@@ -5334,10 +5339,10 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
     } else if (const ConstantArrayType *ConsArrayT
                                      = dyn_cast<ConstantArrayType>(ArrayT)) {
       ArraySize 
-        = SemaRef.Owned(new (SemaRef.Context) IntegerLiteral(
-                                                  ConsArrayT->getSize(), 
-                                                  SemaRef.Context.getSizeType(),
-                                                  /*FIXME:*/E->getLocStart()));
+        = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
+                                               ConsArrayT->getSize(), 
+                                               SemaRef.Context.getSizeType(),
+                                               /*FIXME:*/E->getLocStart()));
       AllocType = ConsArrayT->getElementType();
     } else if (const DependentSizedArrayType *DepArrayT
                               = dyn_cast<DependentSizedArrayType>(ArrayT)) {
@@ -5356,18 +5361,18 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
                                         AllocType,
                                         /*FIXME:*/E->getLocStart(),
                                         /*FIXME:*/SourceRange(),
-                                        move(ArraySize),
+                                        ArraySize.get(),
                                         /*FIXME:*/E->getLocStart(),
                                         move_arg(ConstructorArgs),
                                         E->getLocEnd());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
-  OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
+  ExprResult Operand = getDerived().TransformExpr(E->getArgument());
   if (Operand.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // Transform the delete operator, if known.
   FunctionDecl *OperatorDelete = 0;
@@ -5376,7 +5381,7 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
                                    getDerived().TransformDecl(E->getLocStart(),
                                                        E->getOperatorDelete()));
     if (!OperatorDelete)
-      return SemaRef.ExprError();
+      return ExprError();
   }
   
   if (!getDerived().AlwaysRebuild() &&
@@ -5392,41 +5397,41 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
   return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
                                            E->isGlobalDelete(),
                                            E->isArrayForm(),
-                                           move(Operand));
+                                           Operand.get());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
                                                      CXXPseudoDestructorExpr *E) {
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  Sema::TypeTy *ObjectTypePtr = 0;
+  ParsedType ObjectTypePtr;
   bool MayBePseudoDestructor = false;
-  Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base), 
+  Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(), 
                                               E->getOperatorLoc(),
                                         E->isArrow()? tok::arrow : tok::period,
                                               ObjectTypePtr,
                                               MayBePseudoDestructor);
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
                                               
-  QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+  QualType ObjectType = ObjectTypePtr.get();
   NestedNameSpecifier *Qualifier
     = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                 E->getQualifierRange(),
                                                 ObjectType);
   if (E->getQualifier() && !Qualifier)
-    return SemaRef.ExprError();
+    return ExprError();
 
   PseudoDestructorTypeStorage Destroyed;
   if (E->getDestroyedTypeInfo()) {
     TypeSourceInfo *DestroyedTypeInfo
       = getDerived().TransformType(E->getDestroyedTypeInfo(), ObjectType);
     if (!DestroyedTypeInfo)
-      return SemaRef.ExprError();
+      return ExprError();
     Destroyed = DestroyedTypeInfo;
   } else if (ObjectType->isDependentType()) {
     // We aren't likely to be able to resolve the identifier down to a type
@@ -5441,14 +5446,14 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
       SS.setRange(E->getQualifierRange());
     }
     
-    Sema::TypeTy *T = SemaRef.getDestructorName(E->getTildeLoc(),
+    ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
                                               *E->getDestroyedTypeIdentifier(),
                                                 E->getDestroyedTypeLoc(),
                                                 /*Scope=*/0,
                                                 SS, ObjectTypePtr,
                                                 false);
     if (!T)
-      return SemaRef.ExprError();
+      return ExprError();
     
     Destroyed
       = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
@@ -5460,10 +5465,10 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
     ScopeTypeInfo = getDerived().TransformType(E->getScopeTypeInfo(), 
                                                ObjectType);
     if (!ScopeTypeInfo)
-      return SemaRef.ExprError();
+      return ExprError();
   }
   
-  return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
+  return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
                                                      E->getOperatorLoc(),
                                                      E->isArrow(),
                                                      Qualifier,
@@ -5475,7 +5480,7 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
                                                   UnresolvedLookupExpr *Old) {
   TemporaryBase Rebase(*this, Old->getNameLoc(), DeclarationName());
@@ -5495,7 +5500,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
       if (isa<UsingShadowDecl>(*I))
         continue;
       else
-        return SemaRef.ExprError();
+        return ExprError();
     }
 
     // Expand using declarations.
@@ -5521,7 +5526,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
     Qualifier = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
                                                     Old->getQualifierRange());
     if (!Qualifier)
-      return SemaRef.ExprError();
+      return ExprError();
     
     SS.setScopeRep(Qualifier);
     SS.setRange(Old->getQualifierRange());
@@ -5533,7 +5538,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
                                                             Old->getNameLoc(),
                                                         Old->getNamingClass()));
     if (!NamingClass)
-      return SemaRef.ExprError();
+      return ExprError();
     
     R.setNamingClass(NamingClass);
   }
@@ -5548,7 +5553,7 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
   for (unsigned I = 0, N = Old->getNumTemplateArgs(); I != N; ++I) {
     TemplateArgumentLoc Loc;
     if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I], Loc))
-      return SemaRef.ExprError();
+      return ExprError();
     TransArgs.addArgument(Loc);
   }
 
@@ -5557,13 +5562,13 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr(
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
   TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getQueriedType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       T == E->getQueriedType())
@@ -5581,29 +5586,31 @@ TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
-                                                  DependentScopeDeclRefExpr *E) {
+                                               DependentScopeDeclRefExpr *E) {
   NestedNameSpecifier *NNS
     = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
                                                 E->getQualifierRange());
   if (!NNS)
-    return SemaRef.ExprError();
+    return ExprError();
 
-  DeclarationName Name
-    = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
-  if (!Name)
-    return SemaRef.ExprError();
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
+  if (!NameInfo.getName())
+    return ExprError();
 
   if (!E->hasExplicitTemplateArgs()) {
     if (!getDerived().AlwaysRebuild() &&
         NNS == E->getQualifier() &&
-        Name == E->getDeclName())
+        // Note: it is sufficient to compare the Name component of NameInfo:
+        // if name has not changed, DNLoc has not changed either.
+        NameInfo.getName() == E->getDeclName())
       return SemaRef.Owned(E->Retain());
 
     return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
                                                          E->getQualifierRange(),
-                                                         Name, E->getLocation(),
+                                                         NameInfo,
                                                          /*TemplateArgs*/ 0);
   }
 
@@ -5611,18 +5618,18 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
     TemplateArgumentLoc Loc;
     if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
-      return SemaRef.ExprError();
+      return ExprError();
     TransArgs.addArgument(Loc);
   }
 
   return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
                                                        E->getQualifierRange(),
-                                                       Name, E->getLocation(),
+                                                       NameInfo,
                                                        &TransArgs);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
   // CXXConstructExprs are always implicit, so when we have a
   // 1-argument construction we just transform that argument.
@@ -5634,17 +5641,17 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
 
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
                                 getDerived().TransformDecl(E->getLocStart(),
                                                          E->getConstructor()));
   if (!Constructor)
-    return SemaRef.ExprError();
+    return ExprError();
 
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
        ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg) {
@@ -5653,12 +5660,12 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
       break;
     }
 
-    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    ExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
-    Args.push_back(TransArg.takeAs<Expr>());
+    Args.push_back(TransArg.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -5673,7 +5680,9 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
 
   return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
                                               Constructor, E->isElidable(),
-                                              move_arg(Args));
+                                              move_arg(Args),
+                                              E->requiresZeroInitialization(),
+                                              E->getConstructionKind());
 }
 
 /// \brief Transform a C++ temporary-binding expression.
@@ -5681,51 +5690,41 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
 /// transform the subexpression and return that.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
   return getDerived().TransformExpr(E->getSubExpr());
 }
 
-/// \brief Transform a C++ reference-binding expression.
-///
-/// Since CXXBindReferenceExpr nodes are implicitly generated, we just
-/// transform the subexpression and return that.
-template<typename Derived>
-Sema::OwningExprResult
-TreeTransform<Derived>::TransformCXXBindReferenceExpr(CXXBindReferenceExpr *E) {
-  return getDerived().TransformExpr(E->getSubExpr());
-}
-
 /// \brief Transform a C++ expression that contains temporaries that should
 /// be destroyed after the expression is evaluated.
 ///
 /// Since CXXExprWithTemporaries nodes are implicitly generated, we
 /// just transform the subexpression and return that.
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXExprWithTemporaries(
                                                     CXXExprWithTemporaries *E) {
   return getDerived().TransformExpr(E->getSubExpr());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
                                                       CXXTemporaryObjectExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
   QualType T = getDerived().TransformType(E->getType());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
                                   getDerived().TransformDecl(E->getLocStart(), 
                                                          E->getConstructor()));
   if (!Constructor)
-    return SemaRef.ExprError();
+    return ExprError();
 
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   Args.reserve(E->getNumArgs());
   for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
                                          ArgEnd = E->arg_end();
@@ -5735,9 +5734,9 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
       break;
     }
 
-    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    ExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
     Args.push_back((Expr *)TransArg.release());
@@ -5768,28 +5767,28 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
                                                   CXXUnresolvedConstructExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
   QualType T = getDerived().TransformType(E->getTypeAsWritten());
   if (T.isNull())
-    return SemaRef.ExprError();
+    return ExprError();
 
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
   for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
                                              ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg) {
-    OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
+    ExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
     FakeCommaLocs.push_back(
                         SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
-    Args.push_back(TransArg.takeAs<Expr>());
+    Args.push_back(TransArg.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -5807,11 +5806,11 @@ TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
-                                                     CXXDependentScopeMemberExpr *E) {
+                                             CXXDependentScopeMemberExpr *E) {
   // Transform the base of the expression.
-  OwningExprResult Base(SemaRef, (Expr*) 0);
+  ExprResult Base((Expr*) 0);
   Expr *OldBase;
   QualType BaseType;
   QualType ObjectType;
@@ -5819,20 +5818,20 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
     OldBase = E->getBase();
     Base = getDerived().TransformExpr(OldBase);
     if (Base.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     // Start the member reference and compute the object's type.
-    Sema::TypeTy *ObjectTy = 0;
+    ParsedType ObjectTy;
     bool MayBePseudoDestructor = false;
-    Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
+    Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
                                                 E->getOperatorLoc(),
                                       E->isArrow()? tok::arrow : tok::period,
                                                 ObjectTy,
                                                 MayBePseudoDestructor);
     if (Base.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
-    ObjectType = QualType::getFromOpaquePtr(ObjectTy);
+    ObjectType = ObjectTy.get();
     BaseType = ((Expr*) Base.get())->getType();
   } else {
     OldBase = 0;
@@ -5854,14 +5853,14 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
                                                       ObjectType,
                                                       FirstQualifierInScope);
     if (!Qualifier)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  DeclarationName Name
-    = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
-                                            ObjectType);
-  if (!Name)
-    return SemaRef.ExprError();
+  DeclarationNameInfo NameInfo
+    = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo(),
+                                                ObjectType);
+  if (!NameInfo.getName())
+    return ExprError();
 
   if (!E->hasExplicitTemplateArgs()) {
     // This is a reference to a member without an explicitly-specified
@@ -5870,19 +5869,18 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
         Base.get() == OldBase &&
         BaseType == E->getBaseType() &&
         Qualifier == E->getQualifier() &&
-        Name == E->getMember() &&
+        NameInfo.getName() == E->getMember() &&
         FirstQualifierInScope == E->getFirstQualifierFoundInScope())
       return SemaRef.Owned(E->Retain());
 
-    return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+    return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
                                                        BaseType,
                                                        E->isArrow(),
                                                        E->getOperatorLoc(),
                                                        Qualifier,
                                                        E->getQualifierRange(),
                                                        FirstQualifierInScope,
-                                                       Name,
-                                                       E->getMemberLoc(),
+                                                       NameInfo,
                                                        /*TemplateArgs*/ 0);
   }
 
@@ -5890,32 +5888,31 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
   for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
     TemplateArgumentLoc Loc;
     if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
-      return SemaRef.ExprError();
+      return ExprError();
     TransArgs.addArgument(Loc);
   }
 
-  return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
+  return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
                                                      BaseType,
                                                      E->isArrow(),
                                                      E->getOperatorLoc(),
                                                      Qualifier,
                                                      E->getQualifierRange(),
                                                      FirstQualifierInScope,
-                                                     Name,
-                                                     E->getMemberLoc(),
+                                                     NameInfo,
                                                      &TransArgs);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
   // Transform the base of the expression.
-  OwningExprResult Base(SemaRef, (Expr*) 0);
+  ExprResult Base((Expr*) 0);
   QualType BaseType;
   if (!Old->isImplicitAccess()) {
     Base = getDerived().TransformExpr(Old->getBase());
     if (Base.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
     BaseType = ((Expr*) Base.get())->getType();
   } else {
     BaseType = getDerived().TransformType(Old->getBaseType());
@@ -5927,10 +5924,10 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
       = getDerived().TransformNestedNameSpecifier(Old->getQualifier(),
                                                   Old->getQualifierRange());
     if (Qualifier == 0)
-      return SemaRef.ExprError();
+      return ExprError();
   }
 
-  LookupResult R(SemaRef, Old->getMemberName(), Old->getMemberLoc(),
+  LookupResult R(SemaRef, Old->getMemberNameInfo(),
                  Sema::LookupOrdinaryName);
 
   // Transform all the decls.
@@ -5945,7 +5942,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
       if (isa<UsingShadowDecl>(*I))
         continue;
       else
-        return SemaRef.ExprError();
+        return ExprError();
     }
 
     // Expand using declarations.
@@ -5969,7 +5966,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
                                                           Old->getMemberLoc(),
                                                         Old->getNamingClass()));
     if (!NamingClass)
-      return SemaRef.ExprError();
+      return ExprError();
     
     R.setNamingClass(NamingClass);
   }
@@ -5982,7 +5979,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
       TemplateArgumentLoc Loc;
       if (getDerived().TransformTemplateArgument(Old->getTemplateArgs()[I],
                                                  Loc))
-        return SemaRef.ExprError();
+        return ExprError();
       TransArgs.addArgument(Loc);
     }
   }
@@ -5993,7 +5990,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
   // nested-name-qualifier (and therefore could do the lookup).
   NamedDecl *FirstQualifierInScope = 0;
   
-  return getDerived().RebuildUnresolvedMemberExpr(move(Base),
+  return getDerived().RebuildUnresolvedMemberExpr(Base.get(),
                                                   BaseType,
                                                   Old->getOperatorLoc(),
                                                   Old->isArrow(),
@@ -6006,18 +6003,18 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old)
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
   TypeSourceInfo *EncodedTypeInfo
     = getDerived().TransformType(E->getEncodedTypeSourceInfo());
   if (!EncodedTypeInfo)
-    return SemaRef.ExprError();
+    return ExprError();
 
   if (!getDerived().AlwaysRebuild() &&
       EncodedTypeInfo == E->getEncodedTypeSourceInfo())
@@ -6029,18 +6026,18 @@ TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
   // Transform arguments.
   bool ArgChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+  ASTOwningVector<Expr*> Args(SemaRef);
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
-    OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+    ExprResult Arg = getDerived().TransformExpr(E->getArg(I));
     if (Arg.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
     
     ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
-    Args.push_back(Arg.takeAs<Expr>());
+    Args.push_back(Arg.get());
   }
 
   if (E->getReceiverKind() == ObjCMessageExpr::Class) {
@@ -6048,7 +6045,7 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
     TypeSourceInfo *ReceiverTypeInfo
       = getDerived().TransformType(E->getClassReceiverTypeInfo());
     if (!ReceiverTypeInfo)
-      return SemaRef.ExprError();
+      return ExprError();
     
     // If nothing changed, just retain the existing message send.
     if (!getDerived().AlwaysRebuild() &&
@@ -6067,10 +6064,10 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
   // Instance message: transform the receiver
   assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
          "Only class and instance messages may be instantiated");
-  OwningExprResult Receiver
+  ExprResult Receiver
     = getDerived().TransformExpr(E->getInstanceReceiver());
   if (Receiver.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // If nothing changed, just retain the existing message send.
   if (!getDerived().AlwaysRebuild() &&
@@ -6078,7 +6075,7 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
     return SemaRef.Owned(E->Retain());
   
   // Build a new instance message send.
-  return getDerived().RebuildObjCMessageExpr(move(Receiver),
+  return getDerived().RebuildObjCMessageExpr(Receiver.get(),
                                              E->getSelector(),
                                              E->getMethodDecl(),
                                              E->getLeftLoc(),
@@ -6087,24 +6084,24 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
   // We don't need to transform the ivar; it will never change.
   
@@ -6113,18 +6110,18 @@ TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
       Base.get() == E->getBase())
     return SemaRef.Owned(E->Retain());
   
-  return getDerived().RebuildObjCIvarRefExpr(move(Base), E->getDecl(),
+  return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
                                              E->getLocation(),
                                              E->isArrow(), E->isFreeIvar());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
   
   // We don't need to transform the property; it will never change.
   
@@ -6133,12 +6130,12 @@ TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
       Base.get() == E->getBase())
     return SemaRef.Owned(E->Retain());
   
-  return getDerived().RebuildObjCPropertyRefExpr(move(Base), E->getProperty(),
+  return getDerived().RebuildObjCPropertyRefExpr(Base.get(), E->getProperty(),
                                                  E->getLocation());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
                                           ObjCImplicitSetterGetterRefExpr *E) {
   // If this implicit setter/getter refers to class methods, it cannot have any
@@ -6147,9 +6144,9 @@ TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
     return SemaRef.Owned(E->Retain());
   
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
   
   // We don't need to transform the getters/setters; they will never change.
   
@@ -6163,46 +6160,46 @@ TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
                                                              E->getType(),
                                                           E->getSetterMethod(),
                                                              E->getLocation(),
-                                                             move(Base));
+                                                             Base.get());
                                                              
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
   // Can never occur in a dependent context.
   return SemaRef.Owned(E->Retain());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
   // Transform the base expression.
-  OwningExprResult Base = getDerived().TransformExpr(E->getBase());
+  ExprResult Base = getDerived().TransformExpr(E->getBase());
   if (Base.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
   
   // If nothing changed, just retain the existing expression.
   if (!getDerived().AlwaysRebuild() &&
       Base.get() == E->getBase())
     return SemaRef.Owned(E->Retain());
   
-  return getDerived().RebuildObjCIsaExpr(move(Base), E->getIsaMemberLoc(),
+  return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
                                          E->isArrow());
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
   bool ArgumentChanged = false;
-  ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
+  ASTOwningVector<Expr*> SubExprs(SemaRef);
   for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
-    OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
+    ExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
     if (SubExpr.isInvalid())
-      return SemaRef.ExprError();
+      return ExprError();
 
     ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
-    SubExprs.push_back(SubExpr.takeAs<Expr>());
+    SubExprs.push_back(SubExpr.get());
   }
 
   if (!getDerived().AlwaysRebuild() &&
@@ -6215,7 +6212,7 @@ TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
   SourceLocation CaretLoc(E->getExprLoc());
   
@@ -6246,9 +6243,9 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
   }
     
   // Transform the body
-  OwningStmtResult Body = getDerived().TransformStmt(E->getBody());
+  StmtResult Body = getDerived().TransformStmt(E->getBody());
   if (Body.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
   // Set the parameters on the block decl.
   if (!Params.empty())
     CurBlock->TheDecl->setParams(Params.data(), Params.size());
@@ -6258,14 +6255,15 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
                                                         ParamTypes.data(),
                                                         ParamTypes.size(),
                                                         BD->isVariadic(),
-                                                        0);
+                                                        0,
+                                               BExprFunctionType->getExtInfo());
   
   CurBlock->FunctionType = FunctionType;
-  return SemaRef.ActOnBlockStmtExpr(CaretLoc, move(Body), /*Scope=*/0);
+  return SemaRef.ActOnBlockStmtExpr(CaretLoc, Body.get(), /*Scope=*/0);
 }
 
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
   NestedNameSpecifier *Qualifier = 0;
     
@@ -6273,8 +6271,8 @@ TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
   = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
                                                        E->getDecl()));
   if (!ND)
-    return SemaRef.ExprError();
-  
+    return ExprError();
+
   if (!getDerived().AlwaysRebuild() &&
       ND == E->getDecl()) {
     // Mark it referenced in the new context regardless.
@@ -6284,8 +6282,9 @@ TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
     return SemaRef.Owned(E->Retain());
   }
   
+  DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation());
   return getDerived().RebuildDeclRefExpr(Qualifier, SourceLocation(),
-                                         ND, E->getLocation(), 0);
+                                         ND, NameInfo, 0);
 }
 
 //===----------------------------------------------------------------------===//
@@ -6350,7 +6349,8 @@ TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
       break;
     }
 
-  IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
+  IntegerLiteral ArraySize(SemaRef.Context, *Size, SizeType,
+                           /*FIXME*/BracketsRange.getBegin());
   return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
                                 IndexTypeQuals, BracketsRange,
                                 getDerived().getBaseEntity());
@@ -6381,11 +6381,11 @@ template<typename Derived>
 QualType
 TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
                                           ArrayType::ArraySizeModifier SizeMod,
-                                                 ExprArg SizeExpr,
+                                                 Expr *SizeExpr,
                                                  unsigned IndexTypeQuals,
                                                  SourceRange BracketsRange) {
   return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
-                                       SizeExpr.takeAs<Expr>(),
+                                       SizeExpr,
                                        IndexTypeQuals, BracketsRange);
 }
 
@@ -6393,11 +6393,11 @@ template<typename Derived>
 QualType
 TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
                                           ArrayType::ArraySizeModifier SizeMod,
-                                                       ExprArg SizeExpr,
+                                                       Expr *SizeExpr,
                                                        unsigned IndexTypeQuals,
                                                    SourceRange BracketsRange) {
   return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
-                                       SizeExpr.takeAs<Expr>(),
+                                       SizeExpr,
                                        IndexTypeQuals, BracketsRange);
 }
 
@@ -6416,18 +6416,17 @@ QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
   llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
                           NumElements, true);
   IntegerLiteral *VectorSize
-    = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
-                                           AttributeLoc);
-  return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
-                                    AttributeLoc);
+    = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
+                             AttributeLoc);
+  return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
 }
 
 template<typename Derived>
 QualType
 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
-                                                           ExprArg SizeExpr,
+                                                           Expr *SizeExpr,
                                                   SourceLocation AttributeLoc) {
-  return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
+  return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
 }
 
 template<typename Derived>
@@ -6435,11 +6434,13 @@ QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
                                                           QualType *ParamTypes,
                                                         unsigned NumParamTypes,
                                                           bool Variadic,
-                                                          unsigned Quals) {
+                                                          unsigned Quals,
+                                            const FunctionType::ExtInfo &Info) {
   return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
                                    Quals,
                                    getDerived().getBaseLocation(),
-                                   getDerived().getBaseEntity());
+                                   getDerived().getBaseEntity(),
+                                   Info);
 }
 
 template<typename Derived>
@@ -6473,8 +6474,8 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) {
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
-  return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
+QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E) {
+  return SemaRef.BuildTypeofExprType(E);
 }
 
 template<typename Derived>
@@ -6483,8 +6484,8 @@ QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
-  return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
+QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E) {
+  return SemaRef.BuildDecltypeType(E);
 }
 
 template<typename Derived>
@@ -6563,7 +6564,7 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
                                        /*FIXME:*/getDerived().getBaseLocation(),
                                        SS,
                                        Name,
-                                       ObjectType.getAsOpaquePtr(),
+                                       ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
                                        Template);
   return Template.template getAsVal<TemplateName>();
@@ -6586,56 +6587,52 @@ TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
                                        /*FIXME:*/getDerived().getBaseLocation(),
                                        SS,
                                        Name,
-                                       ObjectType.getAsOpaquePtr(),
+                                       ParsedType::make(ObjectType),
                                        /*EnteringContext=*/false,
                                        Template);
   return Template.template getAsVal<TemplateName>();
 }
   
 template<typename Derived>
-Sema::OwningExprResult
+ExprResult
 TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
                                                    SourceLocation OpLoc,
-                                                   ExprArg Callee,
-                                                   ExprArg First,
-                                                   ExprArg Second) {
-  Expr *FirstExpr = (Expr *)First.get();
-  Expr *SecondExpr = (Expr *)Second.get();
-  Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
-  bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
+                                                   Expr *OrigCallee,
+                                                   Expr *First,
+                                                   Expr *Second) {
+  Expr *Callee = OrigCallee->IgnoreParenCasts();
+  bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
 
   // Determine whether this should be a builtin operation.
   if (Op == OO_Subscript) {
-    if (!FirstExpr->getType()->isOverloadableType() &&
-        !SecondExpr->getType()->isOverloadableType())
-      return getSema().CreateBuiltinArraySubscriptExpr(move(First),
-                                                 CalleeExpr->getLocStart(),
-                                                       move(Second), OpLoc);
+    if (!First->getType()->isOverloadableType() &&
+        !Second->getType()->isOverloadableType())
+      return getSema().CreateBuiltinArraySubscriptExpr(First,
+                                                       Callee->getLocStart(),
+                                                       Second, OpLoc);
   } else if (Op == OO_Arrow) {
     // -> is never a builtin operation.
-    return SemaRef.BuildOverloadedArrowExpr(0, move(First), OpLoc);
-  } else if (SecondExpr == 0 || isPostIncDec) {
-    if (!FirstExpr->getType()->isOverloadableType()) {
+    return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc);
+  } else if (Second == 0 || isPostIncDec) {
+    if (!First->getType()->isOverloadableType()) {
       // The argument is not of overloadable type, so try to create a
       // built-in unary operation.
-      UnaryOperator::Opcode Opc
+      UnaryOperatorKind Opc
         = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
 
-      return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
+      return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
     }
   } else {
-    if (!FirstExpr->getType()->isOverloadableType() &&
-        !SecondExpr->getType()->isOverloadableType()) {
+    if (!First->getType()->isOverloadableType() &&
+        !Second->getType()->isOverloadableType()) {
       // Neither of the arguments is an overloadable type, so try to
       // create a built-in binary operation.
-      BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
-      OwningExprResult Result
-        = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
+      BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+      ExprResult Result
+        = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
       if (Result.isInvalid())
-        return SemaRef.ExprError();
+        return ExprError();
 
-      First.release();
-      Second.release();
       return move(Result);
     }
   }
@@ -6644,49 +6641,46 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
   // used during overload resolution.
   UnresolvedSet<16> Functions;
 
-  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
+  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
     assert(ULE->requiresADL());
 
     // FIXME: Do we have to check
     // IsAcceptableNonMemberOperatorCandidate for each of these?
     Functions.append(ULE->decls_begin(), ULE->decls_end());
   } else {
-    Functions.addDecl(cast<DeclRefExpr>(CalleeExpr)->getDecl());
+    Functions.addDecl(cast<DeclRefExpr>(Callee)->getDecl());
   }
 
   // Add any functions found via argument-dependent lookup.
-  Expr *Args[2] = { FirstExpr, SecondExpr };
-  unsigned NumArgs = 1 + (SecondExpr != 0);
+  Expr *Args[2] = { First, Second };
+  unsigned NumArgs = 1 + (Second != 0);
 
   // Create the overloaded operator invocation for unary operators.
   if (NumArgs == 1 || isPostIncDec) {
-    UnaryOperator::Opcode Opc
+    UnaryOperatorKind Opc
       = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
-    return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
+    return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First);
   }
 
   if (Op == OO_Subscript)
-    return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
+    return SemaRef.CreateOverloadedArraySubscriptExpr(Callee->getLocStart(),
                                                       OpLoc,
-                                                      move(First),
-                                                      move(Second));
+                                                      First,
+                                                      Second);
 
   // Create the overloaded operator invocation for binary operators.
-  BinaryOperator::Opcode Opc =
-    BinaryOperator::getOverloadedOpcode(Op);
-  OwningExprResult Result
+  BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
+  ExprResult Result
     = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
   if (Result.isInvalid())
-    return SemaRef.ExprError();
+    return ExprError();
 
-  First.release();
-  Second.release();
   return move(Result);
 }
 
 template<typename Derived>
-Sema::OwningExprResult 
-TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
+ExprResult 
+TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
                                                      SourceLocation OperatorLoc,
                                                        bool isArrow,
                                                  NestedNameSpecifier *Qualifier,
@@ -6701,32 +6695,32 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(ExprArg Base,
     SS.setScopeRep(Qualifier);
   }
 
-  Expr *BaseE = (Expr *)Base.get();
-  QualType BaseType = BaseE->getType();
-  if (BaseE->isTypeDependent() || Destroyed.getIdentifier() ||
+  QualType BaseType = Base->getType();
+  if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
       (!isArrow && !BaseType->getAs<RecordType>()) ||
       (isArrow && BaseType->getAs<PointerType>() && 
        !BaseType->getAs<PointerType>()->getPointeeType()
                                               ->template getAs<RecordType>())){
     // This pseudo-destructor expression is still a pseudo-destructor.
-    return SemaRef.BuildPseudoDestructorExpr(move(Base), OperatorLoc,
+    return SemaRef.BuildPseudoDestructorExpr(Base, OperatorLoc,
                                              isArrow? tok::arrow : tok::period,
                                              SS, ScopeType, CCLoc, TildeLoc,
                                              Destroyed,
                                              /*FIXME?*/true);
   }
-  
+
   TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
-  DeclarationName Name
-    = SemaRef.Context.DeclarationNames.getCXXDestructorName(
-                SemaRef.Context.getCanonicalType(DestroyedType->getType()));
-  
+  DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
+                 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
+  DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
+  NameInfo.setNamedTypeInfo(DestroyedType);
+
   // FIXME: the ScopeType should be tacked onto SS.
-  
-  return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
+
+  return getSema().BuildMemberReferenceExpr(Base, BaseType,
                                             OperatorLoc, isArrow,
                                             SS, /*FIXME: FirstQualifier*/ 0,
-                                            Name, Destroyed.getLocation(),
+                                            NameInfo,
                                             /*TemplateArgs*/ 0);
 }
 
-- 
cgit v1.1