Reimplement reference initialization (C++ [dcl.init.ref]) using the
new notion of an "initialization sequence", which encapsulates the
computation of the initialization sequence along with diagnostic
information and the capability to turn the computed sequence into an
expression. At present, I've only switched one CheckReferenceInit
callers over to this new mechanism; more will follow.

Aside from (hopefully) being much more true to the standard, the
diagnostics provided by this reference-initialization code are a bit
better than before. Some examples:

p5-var.cpp:54:12: error: non-const lvalue reference to type 'struct
Derived'
      cannot bind to a value of unrelated type 'struct Base'
  Derived &dr2 = b; // expected-error{{non-const lvalue reference to
  ...
           ^     ~
p5-var.cpp:55:9: error: binding of reference to type 'struct Base' to
a value of
      type 'struct Base const' drops qualifiers
  Base &br3 = bc; // expected-error{{drops qualifiers}}
        ^     ~~

p5-var.cpp:57:15: error: ambiguous conversion from derived class
      'struct Diamond' to base class 'struct Base':
    struct Diamond -> struct Derived -> struct Base
    struct Diamond -> struct Derived2 -> struct Base
  Base &br5 = diamond; // expected-error{{ambiguous conversion from
      ...
              ^~~~~~~
p5-var.cpp:59:9: error: non-const lvalue reference to type 'long'
      cannot bind to
      a value of unrelated type 'int'
  long &lr = i; // expected-error{{non-const lvalue reference to type
      ...
        ^    ~

p5-var.cpp:74:9: error: non-const lvalue reference to type 'struct
Base' cannot
      bind to a temporary of type 'struct Base'
  Base &br1 = Base(); // expected-error{{non-const lvalue reference to
  ...
        ^     ~~~~~~

p5-var.cpp:102:9: error: non-const reference cannot bind to bit-field
'i'
  int & ir1 = (ib.i); // expected-error{{non-const reference cannot
  ...
        ^     ~~~~~~
p5-var.cpp:98:7: note: bit-field is declared here
  int i : 17; // expected-note{{bit-field is declared here}}
      ^






git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90992 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 6f47cd0..ad903a0 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -95,7 +95,10 @@
   class CXXBasePaths;
   class CXXTemporary;
   class LookupResult;
-
+  class InitializedEntity;
+  class InitializationKind;
+  class InitializationSequence;
+  
 /// BlockSemaInfo - When a block is being parsed, this contains information
 /// about the block.  It is pointed to from Sema::CurBlock.
 struct BlockSemaInfo {
@@ -812,16 +815,6 @@
     return NULL;
   }
 
-  /// 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              ///< Overload resoltuion refers to a deleted function.
-  };
-
-
   /// Subroutines of ActOnDeclarator().
   TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
                                 TypeSourceInfo *TInfo);
@@ -1011,6 +1004,8 @@
   FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
                                                    bool Complain);
   Expr *FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn);
+  OwningExprResult FixOverloadedFunctionReference(OwningExprResult, 
+                                                  FunctionDecl *Fn);
 
   void AddOverloadedCallCandidates(llvm::SmallVectorImpl<NamedDecl*>& Callees,
                                    DeclarationName &UnqualifiedName,
@@ -1854,14 +1849,6 @@
   /// it simply returns the passed in expression.
   OwningExprResult MaybeBindToTemporary(Expr *E);
 
-  /// InitializationKind - Represents which kind of C++ initialization
-  /// [dcl.init] a routine is to perform.
-  enum InitializationKind {
-    IK_Direct, ///< Direct initialization
-    IK_Copy,   ///< Copy initialization
-    IK_Default ///< Default initialization
-  };
-
   CXXConstructorDecl *
   TryInitializationByConstructor(QualType ClassType,
                                  Expr **Args, unsigned NumArgs,
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index f913890..857241d 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "SemaInit.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -864,7 +865,9 @@
     if (CXXConstructorDecl *Constructor
           = Self.TryInitializationByConstructor(DestType, &SrcExpr, 1,
                                                 OpRange.getBegin(),
-                                                Sema::IK_Direct)) {
+              InitializationKind::CreateDirect(OpRange.getBegin(),
+                                               OpRange.getBegin(), 
+                                               OpRange.getEnd()))) {
       ConversionDecl = Constructor;
       Kind = CastExpr::CK_ConstructorConversion;
       return TC_Success;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 96b6c16..bf6863b 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "SemaInit.h"
 #include "Lookup.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTConsumer.h"
@@ -3486,8 +3487,35 @@
       Diag(VDecl->getLocation(), diag::err_block_extern_cant_init);
       VDecl->setInvalidDecl();
     } else if (!VDecl->isInvalidDecl()) {
-      if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(),
-                                VDecl->getDeclName(), DirectInit))
+      if (VDecl->getType()->isReferenceType()) {
+        InitializedEntity Entity
+          = InitializedEntity::InitializeVariable(VDecl);
+
+        // FIXME: Poor source location information.
+        InitializationKind Kind
+          = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(),
+                                                         SourceLocation(),
+                                                         SourceLocation())
+                      : InitializationKind::CreateCopy(VDecl->getLocation(),
+                                                       SourceLocation());
+        InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1);
+        if (InitSeq) {
+          OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+                                      MultiExprArg(*this, (void**)&Init, 1));
+          if (Result.isInvalid()) {
+            VDecl->setInvalidDecl();
+            return;
+          }
+
+          Init = Result.takeAs<Expr>();
+        } else {
+          InitSeq.Diagnose(*this, Entity, Kind, &Init, 1);
+          VDecl->setInvalidDecl();
+          return;
+        }
+        
+      } else if (CheckInitializerTypes(Init, DclT, VDecl->getLocation(),
+                                       VDecl->getDeclName(), DirectInit))
         VDecl->setInvalidDecl();
 
       // C++ 3.6.2p2, allow dynamic initialization of static initializers.
@@ -3677,7 +3705,7 @@
                                                SourceRange(Var->getLocation(),
                                                            Var->getLocation()),
                                                  Var->getDeclName(),
-                                                 IK_Default,
+                         InitializationKind::CreateDefault(Var->getLocation()),
                                                  ConstructorArgs);
           
           // FIXME: Location info for the variable initialization?
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 6f8a4f1..d977ad6 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "SemaInit.h"
 #include "Lookup.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
@@ -1108,7 +1109,8 @@
                                                           NumArgs), 
                                              IdLoc,
                                              SourceRange(IdLoc, RParenLoc), 
-                                             Member->getDeclName(), IK_Direct,
+                                             Member->getDeclName(), 
+                  InitializationKind::CreateDirect(IdLoc, LParenLoc, RParenLoc),
                                              ConstructorArgs);
       
       if (C) {
@@ -1232,7 +1234,8 @@
                                                         (void**)Args, NumArgs),
                                            BaseLoc, 
                                            SourceRange(BaseLoc, RParenLoc),
-                                           Name, IK_Direct,
+                                           Name, 
+                InitializationKind::CreateDirect(BaseLoc, LParenLoc, RParenLoc),
                                            ConstructorArgs);
     if (C) {
       // Take over the constructor arguments as our own.
@@ -3656,7 +3659,9 @@
                                            SourceRange(VDecl->getLocation(),
                                                        RParenLoc),
                                            VDecl->getDeclName(),
-                                           IK_Direct,
+                      InitializationKind::CreateDirect(VDecl->getLocation(), 
+                                                       LParenLoc, 
+                                                       RParenLoc),
                                            ConstructorArgs);
     if (!Constructor)
       RealDecl->setInvalidDecl();
@@ -3692,7 +3697,7 @@
                                                    QualType ClassType,
                                                    Expr **Args,
                                                    unsigned NumArgs,
-                                                  Sema::InitializationKind Kind,
+                                                   InitializationKind Kind,
                                            OverloadCandidateSet &CandidateSet) {
   // C++ [dcl.init]p14:
   //   If the initialization is direct-initialization, or if it is
@@ -3727,10 +3732,12 @@
     else
       Constructor = cast<CXXConstructorDecl>(*Con);
     
-    if ((Kind == Sema::IK_Direct) ||
-        (Kind == Sema::IK_Copy &&
+    if ((Kind.getKind() == InitializationKind::IK_Direct) ||
+        (Kind.getKind() == InitializationKind::IK_Value) ||
+        (Kind.getKind() == InitializationKind::IK_Copy &&
          Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) ||
-        (Kind == Sema::IK_Default && Constructor->isDefaultConstructor())) {
+        ((Kind.getKind() == InitializationKind::IK_Default) && 
+         Constructor->isDefaultConstructor())) {
       if (ConstructorTmpl)
         SemaRef.AddTemplateOverloadCandidate(ConstructorTmpl,
                                              /*ExplicitArgs*/ 0,
@@ -4002,7 +4009,7 @@
       // real, update the initializer with the resulting function.
       if (!ICS) {
         if (DiagnoseUseOfDecl(Fn, DeclLoc))
-          return true;
+          return true; 
 
         Init = FixOverloadedFunctionReference(Init, Fn);
       }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 16c5275..5e0ce66 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "SemaInit.h"
 #include "Lookup.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CXXInheritance.h"
@@ -225,7 +226,9 @@
                                              SourceRange(TypeRange.getBegin(),
                                                          RParenLoc),
                                              DeclarationName(),
-                                             IK_Direct,
+                         InitializationKind::CreateDirect(TypeRange.getBegin(), 
+                                                          LParenLoc, 
+                                                          RParenLoc),
                                              ConstructorArgs);
 
       if (!Constructor)
@@ -449,12 +452,17 @@
     // Skip all the checks.
   } else if ((RT = AllocType->getAs<RecordType>()) &&
              !AllocType->isAggregateType()) {
+    InitializationKind InitKind = InitializationKind::CreateDefault(TypeLoc);
+    if (NumConsArgs > 0)
+      InitKind = InitializationKind::CreateDirect(TypeLoc,
+                                                  PlacementLParen, 
+                                                  PlacementRParen);
     Constructor = PerformInitializationByConstructor(
                       AllocType, move(ConstructorArgs),
                       TypeLoc,
                       SourceRange(TypeLoc, ConstructorRParen),
                       RT->getDecl()->getDeclName(),
-                      NumConsArgs != 0 ? IK_Direct : IK_Default,
+                      InitKind,
                       ConvertedConstructorArgs);
     if (!Constructor)
       return ExprError();
@@ -1584,7 +1592,7 @@
 
   OverloadCandidateSet::iterator Best;
   switch (Self.BestViableFunction(CandidateSet, Loc, Best)) {
-    case Sema::OR_Success:
+    case OR_Success:
       // We found a match. Perform the conversions on the arguments and move on.
       if (Self.PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
                                          Best->Conversions[0], "converting") ||
@@ -1593,13 +1601,13 @@
         break;
       return false;
 
-    case Sema::OR_No_Viable_Function:
+    case OR_No_Viable_Function:
       Self.Diag(Loc, diag::err_typecheck_cond_incompatible_operands)
         << LHS->getType() << RHS->getType()
         << LHS->getSourceRange() << RHS->getSourceRange();
       return true;
 
-    case Sema::OR_Ambiguous:
+    case OR_Ambiguous:
       Self.Diag(Loc, diag::err_conditional_ambiguous_ovl)
         << LHS->getType() << RHS->getType()
         << LHS->getSourceRange() << RHS->getSourceRange();
@@ -1607,7 +1615,7 @@
       // the viable candidates.
       break;
 
-    case Sema::OR_Deleted:
+    case OR_Deleted:
       assert(false && "Conditional operator has only built-in overloads");
       break;
   }
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 4b0fc84..d2ae906 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -15,11 +15,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "SemaInit.h"
 #include "Sema.h"
 #include "clang/Parse/Designator.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
+#include "llvm/Support/ErrorHandling.h"
 #include <map>
 using namespace clang;
 
@@ -76,7 +78,7 @@
       OverloadCandidateSet CandidateSet;
       if (S.IsUserDefinedConversion(Init, DeclType, ICS.UserDefined,
                               CandidateSet,
-                              true, false, false) != S.OR_Ambiguous)
+                              true, false, false) != OR_Ambiguous)
         return S.Diag(Init->getSourceRange().getBegin(),
                       diag::err_typecheck_convert_incompatible)
                       << DeclType << Init->getType() << "initializing"
@@ -230,13 +232,20 @@
 
         ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
 
+        // FIXME: Poor location information
+        InitializationKind InitKind
+          = InitializationKind::CreateCopy(Init->getLocStart(), 
+                                           SourceLocation());
+        if (DirectInit)
+          InitKind = InitializationKind::CreateDirect(Init->getLocStart(),
+                                                      SourceLocation(), 
+                                                      SourceLocation());
         CXXConstructorDecl *Constructor
           = PerformInitializationByConstructor(DeclType, 
                                                MultiExprArg(*this, 
                                                             (void **)&Init, 1),
                                                InitLoc, Init->getSourceRange(),
-                                               InitEntity,
-                                               DirectInit? IK_Direct : IK_Copy,
+                                               InitEntity, InitKind,
                                                ConstructorArgs);
         if (!Constructor)
           return true;
@@ -1875,12 +1884,13 @@
       if (ClassDecl->hasUserDeclaredConstructor()) {
         ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
 
+        // FIXME: Poor location information
         CXXConstructorDecl *Constructor
           = PerformInitializationByConstructor(Type, 
                                                MultiExprArg(*this, 0, 0),
                                                Loc, SourceRange(Loc),
                                                DeclarationName(),
-                                               IK_Direct,
+                                 InitializationKind::CreateValue(Loc, Loc, Loc),
                                                ConstructorArgs);
         if (!Constructor)
           return true;
@@ -1908,3 +1918,955 @@
 
   return false;
 }
+
+//===----------------------------------------------------------------------===//
+// Initialization entity
+//===----------------------------------------------------------------------===//
+
+void InitializedEntity::InitDeclLoc() {
+  assert((Kind == EK_Variable || Kind == EK_Parameter || Kind == EK_Member) &&
+         "InitDeclLoc cannot be used with non-declaration entities.");
+  
+  if (TypeSourceInfo *DI = VariableOrMember->getTypeSourceInfo()) {
+    TL = DI->getTypeLoc();
+    return;
+  }
+  
+  // FIXME: Once we've gone through the effort to create the fake 
+  // TypeSourceInfo, should we cache it in the declaration?
+  // (If not, we "leak" it).
+  TypeSourceInfo *DI = VariableOrMember->getASTContext()
+                             .CreateTypeSourceInfo(VariableOrMember->getType());
+  DI->getTypeLoc().initialize(VariableOrMember->getLocation());
+  TL = DI->getTypeLoc();
+}
+
+InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, 
+                                                    CXXBaseSpecifier *Base)
+{
+  InitializedEntity Result;
+  Result.Kind = EK_Base;
+  Result.Base = Base;
+  // FIXME: CXXBaseSpecifier should store a TypeLoc.
+  TypeSourceInfo *DI = Context.CreateTypeSourceInfo(Base->getType());
+  DI->getTypeLoc().initialize(Base->getSourceRange().getBegin());
+  Result.TL = DI->getTypeLoc();
+  return Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Initialization sequence
+//===----------------------------------------------------------------------===//
+
+void InitializationSequence::Step::Destroy() {
+  switch (Kind) {
+  case SK_ResolveAddressOfOverloadedFunction:
+  case SK_CastDerivedToBaseRValue:
+  case SK_CastDerivedToBaseLValue:
+  case SK_BindReference:
+  case SK_BindReferenceToTemporary:
+  case SK_UserConversion:
+  case SK_QualificationConversionRValue:
+  case SK_QualificationConversionLValue:
+    break;
+    
+  case SK_ConversionSequence:
+    delete ICS;
+  }
+}
+
+void InitializationSequence::AddAddressOverloadResolutionStep(
+                                                      FunctionDecl *Function) {
+  Step S;
+  S.Kind = SK_ResolveAddressOfOverloadedFunction;
+  S.Type = Function->getType();
+  S.Function = Function;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, 
+                                                      bool IsLValue) {
+  Step S;
+  S.Kind = IsLValue? SK_CastDerivedToBaseLValue : SK_CastDerivedToBaseRValue;
+  S.Type = BaseType;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddReferenceBindingStep(QualType T, 
+                                                     bool BindingTemporary) {
+  Step S;
+  S.Kind = BindingTemporary? SK_BindReferenceToTemporary : SK_BindReference;
+  S.Type = T;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddUserConversionStep(FunctionDecl *Function) {
+  Step S;
+  S.Kind = SK_UserConversion;
+  S.Type = Function->getResultType().getNonReferenceType();
+  S.Function = Function;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddQualificationConversionStep(QualType Ty,
+                                                            bool IsLValue) {
+  Step S;
+  S.Kind = IsLValue? SK_QualificationConversionLValue 
+                   : SK_QualificationConversionRValue;
+  S.Type = Ty;
+  Steps.push_back(S);
+}
+
+void InitializationSequence::AddConversionSequenceStep(
+                                       const ImplicitConversionSequence &ICS,
+                                                       QualType T) {
+  Step S;
+  S.Kind = SK_ConversionSequence;
+  S.Type = T;
+  S.ICS = new ImplicitConversionSequence(ICS);
+  Steps.push_back(S);
+}
+
+void InitializationSequence::SetOverloadFailure(FailureKind Failure, 
+                                                OverloadingResult Result) {
+  SequenceKind = FailedSequence;
+  this->Failure = Failure;
+  this->FailedOverloadResult = Result;
+}
+
+//===----------------------------------------------------------------------===//
+// Attempt initialization
+//===----------------------------------------------------------------------===//
+
+/// \brief Attempt list initialization (C++0x [dcl.init.list]) 
+static bool TryListInitialization(Sema &S, 
+                                  const InitializedEntity &Entity,
+                                  const InitializationKind &Kind,
+                                  InitListExpr *InitList,
+                                  InitializationSequence &Sequence) {
+  // FIXME: For now, it is safe to assume that list initialization always
+  // works. When we actually perform list initialization, we'll do all of the
+  // necessary checking.
+  // C++0x initializer lists will force us to perform more checking here.
+  return true;
+}
+
+/// \brief Try a reference initialization that involves calling a conversion
+/// function.
+///
+/// FIXME: look intos DRs 656, 896
+static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
+                                             const InitializedEntity &Entity,
+                                             const InitializationKind &Kind,
+                                                          Expr *Initializer,
+                                                          bool AllowRValues,
+                                             InitializationSequence &Sequence) {
+  QualType DestType = Entity.getType().getType();
+  QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
+  QualType T1 = cv1T1.getUnqualifiedType();
+  QualType cv2T2 = Initializer->getType();
+  QualType T2 = cv2T2.getUnqualifiedType();
+
+  bool DerivedToBase;
+  assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), 
+                                         T1, T2, DerivedToBase) &&
+         "Must have incompatible references when binding via conversion");
+
+  // Build the candidate set directly in the initialization sequence
+  // structure, so that it will persist if we fail.
+  OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet();
+  CandidateSet.clear();
+
+  // Determine whether we are allowed to call explicit constructors or
+  // explicit conversion operators.
+  bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct;
+  
+  const RecordType *T1RecordType = 0;
+  if (AllowRValues && (T1RecordType = T1->getAs<RecordType>())) {
+    // The type we're converting to is a class type. Enumerate its constructors
+    // to see if there is a suitable conversion.
+    CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
+    
+    DeclarationName ConstructorName
+      = S.Context.DeclarationNames.getCXXConstructorName(
+                           S.Context.getCanonicalType(T1).getUnqualifiedType());
+    DeclContext::lookup_iterator Con, ConEnd;
+    for (llvm::tie(Con, ConEnd) = T1RecordDecl->lookup(ConstructorName);
+         Con != ConEnd; ++Con) {
+      // Find the constructor (which may be a template).
+      CXXConstructorDecl *Constructor = 0;
+      FunctionTemplateDecl *ConstructorTmpl
+        = dyn_cast<FunctionTemplateDecl>(*Con);
+      if (ConstructorTmpl)
+        Constructor = cast<CXXConstructorDecl>(
+                                         ConstructorTmpl->getTemplatedDecl());
+      else
+        Constructor = cast<CXXConstructorDecl>(*Con);
+      
+      if (!Constructor->isInvalidDecl() &&
+          Constructor->isConvertingConstructor(AllowExplicit)) {
+        if (ConstructorTmpl)
+          S.AddTemplateOverloadCandidate(ConstructorTmpl, /*ExplicitArgs*/ 0,
+                                         &Initializer, 1, CandidateSet);
+        else
+          S.AddOverloadCandidate(Constructor, &Initializer, 1, CandidateSet);
+      }
+    }    
+  }
+  
+  if (const RecordType *T2RecordType = T2->getAs<RecordType>()) {
+    // The type we're converting from is a class type, enumerate its conversion
+    // functions.
+    CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl());
+
+    // Determine the type we are converting to. If we are allowed to
+    // convert to an rvalue, take the type that the destination type
+    // refers to.
+    QualType ToType = AllowRValues? cv1T1 : DestType;
+
+    const UnresolvedSet *Conversions
+      = T2RecordDecl->getVisibleConversionFunctions();
+    for (UnresolvedSet::iterator I = Conversions->begin(),
+         E = Conversions->end(); 
+         I != E; ++I) {
+      NamedDecl *D = *I;
+      CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext());
+      if (isa<UsingShadowDecl>(D))
+        D = cast<UsingShadowDecl>(D)->getTargetDecl();
+      
+      FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D);
+      CXXConversionDecl *Conv;
+      if (ConvTemplate)
+        Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+      else
+        Conv = cast<CXXConversionDecl>(*I);
+      
+      // If the conversion function doesn't return a reference type,
+      // it can't be considered for this conversion unless we're allowed to
+      // consider rvalues.
+      // FIXME: Do we need to make sure that we only consider conversion 
+      // candidates with reference-compatible results? That might be needed to 
+      // break recursion.
+      if ((AllowExplicit || !Conv->isExplicit()) &&
+          (AllowRValues || Conv->getConversionType()->isLValueReferenceType())){
+        if (ConvTemplate)
+          S.AddTemplateConversionCandidate(ConvTemplate, ActingDC, Initializer,
+                                           ToType, CandidateSet);
+        else
+          S.AddConversionCandidate(Conv, ActingDC, Initializer, cv1T1,
+                                   CandidateSet);
+      }
+    }
+  }
+  
+  SourceLocation DeclLoc = Initializer->getLocStart();
+
+  // Perform overload resolution. If it fails, return the failed result.  
+  OverloadCandidateSet::iterator Best;
+  if (OverloadingResult Result 
+        = S.BestViableFunction(CandidateSet, DeclLoc, Best))
+    return Result;
+  
+  // Add the user-defined conversion step.
+  FunctionDecl *Function = Best->Function;
+  Sequence.AddUserConversionStep(Function);
+  
+  // Determine whether we need to perform derived-to-base or 
+  // cv-qualification adjustments.
+  if (isa<CXXConversionDecl>(Function))
+    T2 = Function->getResultType();
+  else
+    T2 = cv1T1;
+    
+  bool NewDerivedToBase = false;
+  Sema::ReferenceCompareResult NewRefRelationship
+    = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonReferenceType(),
+                                     NewDerivedToBase);
+  assert(NewRefRelationship != Sema::Ref_Incompatible &&
+         "Overload resolution picked a bad conversion function");
+  (void)NewRefRelationship;
+  if (NewDerivedToBase)
+    Sequence.AddDerivedToBaseCastStep(
+                                S.Context.getQualifiedType(T1,
+                                  T2.getNonReferenceType().getQualifiers()), 
+                                  /*isLValue=*/true);
+  
+  if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers())
+    Sequence.AddQualificationConversionStep(cv1T1, T2->isReferenceType());
+  
+  Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType());
+  return OR_Success;
+}
+  
+/// \brief Attempt reference initialization (C++0x [dcl.init.list]) 
+static void TryReferenceInitialization(Sema &S, 
+                                       const InitializedEntity &Entity,
+                                       const InitializationKind &Kind,
+                                       Expr *Initializer,
+                                       InitializationSequence &Sequence) {
+  Sequence.setSequenceKind(InitializationSequence::ReferenceBinding);
+  
+  QualType DestType = Entity.getType().getType();
+  QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType();
+  QualType T1 = cv1T1.getUnqualifiedType();
+  QualType cv2T2 = Initializer->getType();
+  QualType T2 = cv2T2.getUnqualifiedType();
+  SourceLocation DeclLoc = Initializer->getLocStart();
+  
+  // If the initializer is the address of an overloaded function, try
+  // to resolve the overloaded function. If all goes well, T2 is the
+  // type of the resulting function.
+  if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) {
+    FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer, 
+                                                            T1,
+                                                            false);
+    if (!Fn) {
+      Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed);
+      return;
+    }
+    
+    Sequence.AddAddressOverloadResolutionStep(Fn);
+    cv2T2 = Fn->getType();
+    T2 = cv2T2.getUnqualifiedType();
+  }
+  
+  // FIXME: Rvalue references
+  bool ForceRValue = false;
+  
+  // Compute some basic properties of the types and the initializer.
+  bool isLValueRef = DestType->isLValueReferenceType();
+  bool isRValueRef = !isLValueRef;
+  bool DerivedToBase = false;
+  Expr::isLvalueResult InitLvalue = ForceRValue ? Expr::LV_InvalidExpression :
+                                    Initializer->isLvalue(S.Context);
+  Sema::ReferenceCompareResult RefRelationship
+    = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase);
+  
+  // C++0x [dcl.init.ref]p5:
+  //   A reference to type "cv1 T1" is initialized by an expression of type 
+  //   "cv2 T2" as follows:
+  //
+  //     - If the reference is an lvalue reference and the initializer 
+  //       expression
+  OverloadingResult ConvOvlResult = OR_Success;
+  if (isLValueRef) {
+    if (InitLvalue == Expr::LV_Valid && 
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+      //   - is an lvalue (but is not a bit-field), and "cv1 T1" is 
+      //     reference-compatible with "cv2 T2," or
+      //
+      // Per C++ [over.best.ics]p2, we ignore whether the lvalue is a 
+      // bit-field when we're determining whether the reference initialization
+      // can occur. This property will be checked by PerformInitialization.
+      if (DerivedToBase)
+        Sequence.AddDerivedToBaseCastStep(
+                         S.Context.getQualifiedType(T1, cv2T2.getQualifiers()), 
+                         /*isLValue=*/true);
+      if (cv1T1.getQualifiers() != cv2T2.getQualifiers())
+        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/true);
+      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/false);
+      return;
+    }
+    
+    //     - has a class type (i.e., T2 is a class type), where T1 is not 
+    //       reference-related to T2, and can be implicitly converted to an 
+    //       lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible 
+    //       with "cv3 T3" (this conversion is selected by enumerating the 
+    //       applicable conversion functions (13.3.1.6) and choosing the best
+    //       one through overload resolution (13.3)),
+    if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType()) {
+      ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, 
+                                                       Initializer,
+                                                       /*AllowRValues=*/false,
+                                                       Sequence);
+      if (ConvOvlResult == OR_Success)
+        return;
+    }
+  }
+  
+  //     - Otherwise, the reference shall be an lvalue reference to a 
+  //       non-volatile const type (i.e., cv1 shall be const), or the reference
+  //       shall be an rvalue reference and the initializer expression shall 
+  //       be an rvalue.
+  if (!((isLValueRef && cv1T1.getCVRQualifiers() == Qualifiers::Const) ||
+        (isRValueRef && InitLvalue != Expr::LV_Valid))) {
+    if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty())
+      Sequence.SetOverloadFailure(
+                        InitializationSequence::FK_ReferenceInitOverloadFailed,
+                                  ConvOvlResult);
+    else if (isLValueRef)
+      Sequence.SetFailed(InitLvalue == Expr::LV_Valid
+        ? (RefRelationship == Sema::Ref_Related
+             ? InitializationSequence::FK_ReferenceInitDropsQualifiers
+             : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated)
+        : InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary);
+    else
+      Sequence.SetFailed(
+                    InitializationSequence::FK_RValueReferenceBindingToLValue);
+    
+    return;
+  }
+  
+  //       - If T1 and T2 are class types and
+  if (T1->isRecordType() && T2->isRecordType()) {
+    //       - the initializer expression is an rvalue and "cv1 T1" is 
+    //         reference-compatible with "cv2 T2", or
+    if (InitLvalue != Expr::LV_Valid && 
+        RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+      if (DerivedToBase)
+        Sequence.AddDerivedToBaseCastStep(
+                         S.Context.getQualifiedType(T1, cv2T2.getQualifiers()), 
+                         /*isLValue=*/false);
+      if (cv1T1.getQualifiers() != cv2T2.getQualifiers())
+        Sequence.AddQualificationConversionStep(cv1T1, /*IsLValue=*/false);
+      Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+      return;
+    }
+    
+    //       - T1 is not reference-related to T2 and the initializer expression
+    //         can be implicitly converted to an rvalue of type "cv3 T3" (this
+    //         conversion is selected by enumerating the applicable conversion
+    //         functions (13.3.1.6) and choosing the best one through overload 
+    //         resolution (13.3)),
+    if (RefRelationship == Sema::Ref_Incompatible) {
+      ConvOvlResult = TryRefInitWithConversionFunction(S, Entity,
+                                                       Kind, Initializer,
+                                                       /*AllowRValues=*/true,
+                                                       Sequence);
+      if (ConvOvlResult)
+        Sequence.SetOverloadFailure(
+                      InitializationSequence::FK_ReferenceInitOverloadFailed,
+                                    ConvOvlResult);
+        
+      return;
+    }
+    
+    Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
+    return;
+  }
+  
+  //      - If the initializer expression is an rvalue, with T2 an array type,
+  //        and "cv1 T1" is reference-compatible with "cv2 T2," the reference
+  //        is bound to the object represented by the rvalue (see 3.10).
+  // FIXME: How can an array type be reference-compatible with anything?
+  // Don't we mean the element types of T1 and T2?
+  
+  //      - Otherwise, a temporary of type “cv1 T1” is created and initialized
+  //        from the initializer expression using the rules for a non-reference
+  //        copy initialization (8.5). The reference is then bound to the 
+  //        temporary. [...]
+  // Determine whether we are allowed to call explicit constructors or
+  // explicit conversion operators.
+  bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct);
+  ImplicitConversionSequence ICS
+    = S.TryImplicitConversion(Initializer, cv1T1,
+                              /*SuppressUserConversions=*/false, AllowExplicit, 
+                              /*ForceRValue=*/false, 
+                              /*FIXME:InOverloadResolution=*/false,
+                              /*UserCast=*/Kind.isExplicitCast());
+            
+  if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
+    // FIXME: Use the conversion function set stored in ICS to turn
+    // this into an overloading ambiguity diagnostic. However, we need
+    // to keep that set as an OverloadCandidateSet rather than as some
+    // other kind of set.
+    Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed);
+    return;
+  }
+
+  //        [...] If T1 is reference-related to T2, cv1 must be the
+  //        same cv-qualification as, or greater cv-qualification
+  //        than, cv2; otherwise, the program is ill-formed.
+  if (RefRelationship == Sema::Ref_Related && 
+      !cv1T1.isAtLeastAsQualifiedAs(cv2T2)) {
+    Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
+    return;
+  }
+
+  // Perform the actual conversion.
+  Sequence.AddConversionSequenceStep(ICS, cv1T1);
+  Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true);
+  return;
+}
+
+/// \brief Attempt character array initialization from a string literal
+/// (C++ [dcl.init.string], C99 6.7.8). 
+static void TryStringLiteralInitialization(Sema &S, 
+                                           const InitializedEntity &Entity,
+                                           const InitializationKind &Kind,
+                                           Expr *Initializer,
+                                       InitializationSequence &Sequence) {
+  // FIXME: Implement!
+}
+
+/// \brief Attempt value initialization (C++ [dcl.init]p7).
+static void TryValueInitialization(Sema &S, 
+                                   const InitializedEntity &Entity,
+                                   const InitializationKind &Kind,
+                                   InitializationSequence &Sequence) {
+  // FIXME: Implement!
+}
+
+/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
+/// enumerates the constructors of the initialized entity and performs overload
+/// resolution to select the best.
+static void TryConstructorInitialization(Sema &S, 
+                                         const InitializedEntity &Entity,
+                                         const InitializationKind &Kind,
+                                         Expr **Args, unsigned NumArgs,
+                                         InitializationSequence &Sequence) {
+  // FIXME: Implement!
+}
+
+/// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]),
+/// which enumerates all conversion functions and performs overload resolution
+/// to select the best.
+static void TryUserDefinedConversion(Sema &S, 
+                                     const InitializedEntity &Entity,
+                                     const InitializationKind &Kind,
+                                     Expr *Initializer,
+                                     InitializationSequence &Sequence) {
+  // FIXME: Implement!
+}
+
+/// \brief Attempt an implicit conversion (C++ [conv]) converting from one
+/// non-class type to another.
+static void TryImplicitConversion(Sema &S, 
+                                  const InitializedEntity &Entity,
+                                  const InitializationKind &Kind,
+                                  Expr *Initializer,
+                                  InitializationSequence &Sequence) {
+  ImplicitConversionSequence ICS
+    = S.TryImplicitConversion(Initializer, Entity.getType().getType(),
+                              /*SuppressUserConversions=*/true, 
+                              /*AllowExplicit=*/false,
+                              /*ForceRValue=*/false, 
+                              /*FIXME:InOverloadResolution=*/false,
+                              /*UserCast=*/Kind.isExplicitCast());
+  
+  if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
+    Sequence.SetFailed(InitializationSequence::FK_ConversionFailed);
+    return;
+  }
+  
+  Sequence.AddConversionSequenceStep(ICS, Entity.getType().getType());
+}
+
+InitializationSequence::InitializationSequence(Sema &S,
+                                               const InitializedEntity &Entity,
+                                               const InitializationKind &Kind,
+                                               Expr **Args,
+                                               unsigned NumArgs) {
+  ASTContext &Context = S.Context;
+  
+  // C++0x [dcl.init]p16:
+  //   The semantics of initializers are as follows. The destination type is 
+  //   the type of the object or reference being initialized and the source 
+  //   type is the type of the initializer expression. The source type is not
+  //   defined when the initializer is a braced-init-list or when it is a 
+  //   parenthesized list of expressions.
+  QualType DestType = Entity.getType().getType();
+
+  if (DestType->isDependentType() ||
+      Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
+    SequenceKind = DependentSequence;
+    return;
+  }
+
+  QualType SourceType;
+  Expr *Initializer = 0;
+  if (Kind.getKind() == InitializationKind::IK_Copy) {
+    Initializer = Args[0];
+    if (!isa<InitListExpr>(Initializer))
+      SourceType = Initializer->getType();
+  }
+  
+  //     - If the initializer is a braced-init-list, the object is 
+  //       list-initialized (8.5.4).
+  if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) {
+    TryListInitialization(S, Entity, Kind, InitList, *this);
+  }
+  
+  //     - If the destination type is a reference type, see 8.5.3.
+  if (DestType->isReferenceType()) {
+    // C++0x [dcl.init.ref]p1:
+    //   A variable declared to be a T& or T&&, that is, "reference to type T"
+    //   (8.3.2), shall be initialized by an object, or function, of type T or
+    //   by an object that can be converted into a T.
+    // (Therefore, multiple arguments are not permitted.)
+    if (NumArgs != 1)
+      SetFailed(FK_TooManyInitsForReference);
+    else
+      TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
+    return;
+  }
+  
+  //     - If the destination type is an array of characters, an array of 
+  //       char16_t, an array of char32_t, or an array of wchar_t, and the 
+  //       initializer is a string literal, see 8.5.2.
+  if (Initializer && IsStringInit(Initializer, DestType, Context)) {
+    TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this);
+    return;
+  }
+  
+  //     - If the initializer is (), the object is value-initialized.
+  if (Kind.getKind() == InitializationKind::IK_Value) {
+    TryValueInitialization(S, Entity, Kind, *this);
+    return;
+  }
+  
+  //     - Otherwise, if the destination type is an array, the program is 
+  //       ill-formed.
+  if (const ArrayType *AT = Context.getAsArrayType(DestType)) {
+    if (AT->getElementType()->isAnyCharacterType())
+      SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
+    else
+      SetFailed(FK_ArrayNeedsInitList);
+    
+    return;
+  }
+  
+  //     - If the destination type is a (possibly cv-qualified) class type:
+  if (DestType->isRecordType()) {
+    //     - If the initialization is direct-initialization, or if it is 
+    //       copy-initialization where the cv-unqualified version of the 
+    //       source type is the same class as, or a derived class of, the 
+    //       class of the destination, constructors are considered. [...]
+    if (Kind.getKind() == InitializationKind::IK_Direct ||
+        (Kind.getKind() == InitializationKind::IK_Copy &&
+         (Context.hasSameUnqualifiedType(SourceType, DestType) ||
+          S.IsDerivedFrom(SourceType, DestType))))
+      TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, *this);
+    //     - Otherwise (i.e., for the remaining copy-initialization cases), 
+    //       user-defined conversion sequences that can convert from the source
+    //       type to the destination type or (when a conversion function is 
+    //       used) to a derived class thereof are enumerated as described in
+    //       13.3.1.4, and the best one is chosen through overload resolution
+    //       (13.3).
+    else
+      TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
+    return;
+  }
+  
+  //    - Otherwise, if the source type is a (possibly cv-qualified) class 
+  //      type, conversion functions are considered.
+  if (SourceType->isRecordType()) {
+    TryUserDefinedConversion(S, Entity, Kind, Initializer, *this);
+    return;
+  }
+  
+  //    - Otherwise, the initial value of the object being initialized is the
+  //      (possibly converted) value of the ini- tializer expression. Standard
+  //      conversions (Clause 4) will be used, if necessary, to convert the
+  //      initializer expression to the cv-unqualified version of the 
+  //      destination type; no user-defined conversions are considered.
+  TryImplicitConversion(S, Entity, Kind, Initializer, *this);
+}
+
+InitializationSequence::~InitializationSequence() {
+  for (llvm::SmallVectorImpl<Step>::iterator Step = Steps.begin(),
+                                          StepEnd = Steps.end();
+       Step != StepEnd; ++Step)
+    Step->Destroy();
+}
+
+//===----------------------------------------------------------------------===//
+// Perform initialization
+//===----------------------------------------------------------------------===//
+
+Action::OwningExprResult 
+InitializationSequence::Perform(Sema &S,
+                                const InitializedEntity &Entity,
+                                const InitializationKind &Kind,
+                                Action::MultiExprArg Args) {
+  if (SequenceKind == FailedSequence) {
+    unsigned NumArgs = Args.size();
+    Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs);
+    return S.ExprError();
+  }
+  
+  if (SequenceKind == DependentSequence) {
+    if (Kind.getKind() == InitializationKind::IK_Copy)
+      return Sema::OwningExprResult(S, Args.release()[0]);
+
+    unsigned NumArgs = Args.size();
+    return S.Owned(new (S.Context) ParenListExpr(S.Context,
+                                                 SourceLocation(),
+                                                 (Expr **)Args.release(), 
+                                                 NumArgs,
+                                                 SourceLocation()));
+  }
+
+  QualType DestType = Entity.getType().getType().getNonReferenceType();
+
+  Sema::OwningExprResult CurInit(S);
+  // For copy initialization and any other initialization forms that
+  // only have a single initializer, we start with the (only)
+  // initializer we have.
+  // FIXME: DPG is not happy about this. There's confusion regarding whether
+  // we're supposed to start the conversion from the solitary initializer or
+  // from the set of arguments.
+  if (Kind.getKind() == InitializationKind::IK_Copy ||
+      SequenceKind == ReferenceBinding) {
+    assert(Args.size() == 1);
+    CurInit = Sema::OwningExprResult(S, Args.release()[0]);
+    if (CurInit.isInvalid())
+      return S.ExprError();
+  }
+    
+  // Walk through the computed steps for the initialization sequence, 
+  // performing the specified conversions along the way.
+  for (step_iterator Step = step_begin(), StepEnd = step_end();
+       Step != StepEnd; ++Step) {
+    if (CurInit.isInvalid())
+      return S.ExprError();
+    
+    Expr *CurInitExpr = (Expr *)CurInit.get();
+    QualType SourceType = CurInitExpr->getType();
+    
+    switch (Step->Kind) {
+    case SK_ResolveAddressOfOverloadedFunction:
+      // Overload resolution determined which function invoke; update the 
+      // initializer to reflect that choice.
+      CurInit = S.FixOverloadedFunctionReference(move(CurInit), Step->Function);
+      break;
+        
+    case SK_CastDerivedToBaseRValue:
+    case SK_CastDerivedToBaseLValue: {
+      // We have a derived-to-base cast that produces either an rvalue or an
+      // lvalue. Perform that cast.
+      
+      // Casts to inaccessible base classes are allowed with C-style casts.
+      bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast();
+      if (S.CheckDerivedToBaseConversion(SourceType, Step->Type,
+                                         CurInitExpr->getLocStart(),
+                                         CurInitExpr->getSourceRange(),
+                                         IgnoreBaseAccess))
+        return S.ExprError();
+        
+      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(Step->Type,
+                                                    CastExpr::CK_DerivedToBase,
+                                                      (Expr*)CurInit.release(),
+                                     Step->Kind == SK_CastDerivedToBaseLValue));
+      break;
+    }
+        
+    case SK_BindReference:
+      if (FieldDecl *BitField = CurInitExpr->getBitField()) {
+        // References cannot bind to bit fields (C++ [dcl.init.ref]p5).
+        S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield)
+          << Entity.getType().getType().isVolatileQualified()
+          << BitField->getDeclName()
+          << CurInitExpr->getSourceRange();
+        S.Diag(BitField->getLocation(), diag::note_bitfield_decl);
+        return S.ExprError();
+      }
+        
+      // Reference binding does not have any corresponding ASTs.
+
+      // Check exception specifications
+      if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
+        return S.ExprError();
+      break;
+        
+    case SK_BindReferenceToTemporary:
+      // Check exception specifications
+      if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType))
+        return S.ExprError();
+
+      // FIXME: At present, we have no AST to describe when we need to make a
+      // temporary to bind a reference to. We should.
+      break;
+        
+    case SK_UserConversion: {
+      // We have a user-defined conversion that invokes either a constructor
+      // or a conversion function.
+      CastExpr::CastKind CastKind = CastExpr::CK_Unknown;
+      if (CXXConstructorDecl *Constructor
+                              = dyn_cast<CXXConstructorDecl>(Step->Function)) {
+        // Build a call to the selected constructor.
+        ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
+        SourceLocation Loc = CurInitExpr->getLocStart();
+        CurInit.release(); // Ownership transferred into MultiExprArg, below.
+        
+        // Determine the arguments required to actually perform the constructor
+        // call.
+        if (S.CompleteConstructorCall(Constructor,
+                                      Sema::MultiExprArg(S, 
+                                                         (void **)&CurInitExpr,
+                                                         1),
+                                      Loc, ConstructorArgs))
+          return S.ExprError();
+        
+        // Build the an expression that constructs a temporary.
+        CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor, 
+                                          move_arg(ConstructorArgs));
+        if (CurInit.isInvalid())
+          return S.ExprError();
+        
+        CastKind = CastExpr::CK_ConstructorConversion;
+      } else {
+        // Build a call to the conversion function.
+        CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Step->Function);
+        
+        // FIXME: Should we move this initialization into a separate 
+        // derived-to-base conversion? I believe the answer is "no", because
+        // we don't want to turn off access control here for c-style casts.
+        if (S.PerformObjectArgumentInitialization(CurInitExpr, Conversion))
+          return S.ExprError();
+
+        // Do a little dance to make sure that CurInit has the proper
+        // pointer.
+        CurInit.release();
+        
+        // Build the actual call to the conversion function.
+        CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, Conversion));
+        if (CurInit.isInvalid() || !CurInit.get())
+          return S.ExprError();
+        
+        CastKind = CastExpr::CK_UserDefinedConversion;
+      }
+      
+      CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>());
+      CurInitExpr = CurInit.takeAs<Expr>();
+      CurInit = S.Owned(new (S.Context) ImplicitCastExpr(CurInitExpr->getType(),
+                                                         CastKind, 
+                                                         CurInitExpr,
+                                                         false));                                                        
+      break;
+    }
+        
+    case SK_QualificationConversionLValue:
+    case SK_QualificationConversionRValue:
+      // Perform a qualification conversion; these can never go wrong.
+      S.ImpCastExprToType(CurInitExpr, Step->Type,
+                          CastExpr::CK_NoOp, 
+                          Step->Kind == SK_QualificationConversionLValue);
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);
+      break;
+        
+    case SK_ConversionSequence:
+      if (S.PerformImplicitConversion(CurInitExpr, Step->Type, "converting", 
+                                      false, false, *Step->ICS))
+        return S.ExprError();
+        
+      CurInit.release();
+      CurInit = S.Owned(CurInitExpr);        
+      break;
+    }
+  }
+  
+  return move(CurInit);
+}
+
+//===----------------------------------------------------------------------===//
+// Diagnose initialization failures
+//===----------------------------------------------------------------------===//
+bool InitializationSequence::Diagnose(Sema &S, 
+                                      const InitializedEntity &Entity,
+                                      const InitializationKind &Kind,
+                                      Expr **Args, unsigned NumArgs) {
+  if (SequenceKind != FailedSequence)
+    return false;
+  
+  QualType DestType = Entity.getType().getType();
+  switch (Failure) {
+  case FK_TooManyInitsForReference:
+    S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits)
+      << SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd());
+    break;
+    
+  case FK_ArrayNeedsInitList:
+  case FK_ArrayNeedsInitListOrStringLiteral:
+    S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list)
+      << (Failure == FK_ArrayNeedsInitListOrStringLiteral);
+    break;
+      
+  case FK_AddressOfOverloadFailed:
+    S.ResolveAddressOfOverloadedFunction(Args[0], 
+                                         DestType.getNonReferenceType(),
+                                         true);
+    break;
+      
+  case FK_ReferenceInitOverloadFailed:
+    switch (FailedOverloadResult) {
+    case OR_Ambiguous:
+      S.Diag(Kind.getLocation(), diag::err_typecheck_ambiguous_condition)
+        << Args[0]->getType() << DestType.getNonReferenceType()
+        << Args[0]->getSourceRange();
+      S.PrintOverloadCandidates(FailedCandidateSet, true);
+      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, false);
+      break;
+        
+    case OR_Deleted: {
+      S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function)
+        << Args[0]->getType() << DestType.getNonReferenceType()
+        << Args[0]->getSourceRange();
+      OverloadCandidateSet::iterator Best;
+      OverloadingResult Ovl = S.BestViableFunction(FailedCandidateSet,
+                                                   Kind.getLocation(),
+                                                   Best);
+      if (Ovl == OR_Deleted) {
+        S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
+          << Best->Function->isDeleted();
+      } else {
+        llvm::llvm_unreachable("Inconsistent overload resolution?");
+      }
+      break;
+    }
+        
+    case OR_Success:
+      llvm::llvm_unreachable("Conversion did not fail!");
+      break;
+    }
+    break;
+      
+  case FK_NonConstLValueReferenceBindingToTemporary:
+  case FK_NonConstLValueReferenceBindingToUnrelated:
+    S.Diag(Kind.getLocation(), 
+           Failure == FK_NonConstLValueReferenceBindingToTemporary
+             ? diag::err_lvalue_reference_bind_to_temporary
+             : diag::err_lvalue_reference_bind_to_unrelated)
+      << DestType.getNonReferenceType()
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_RValueReferenceBindingToLValue:
+    S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref)
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ReferenceInitDropsQualifiers:
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals)
+      << DestType.getNonReferenceType()
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ReferenceInitFailed:
+    S.Diag(Kind.getLocation(), diag::err_reference_bind_failed)
+      << DestType.getNonReferenceType()
+      << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+    break;
+      
+  case FK_ConversionFailed:
+    S.Diag(Kind.getLocation(), diag::err_cannot_initialize_decl_noname)
+      << DestType
+      << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid)
+      << Args[0]->getType()
+      << Args[0]->getSourceRange();
+      break;
+  }
+  
+  return true;
+}
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
index e69de29..85aa421 100644
--- a/lib/Sema/SemaInit.h
+++ b/lib/Sema/SemaInit.h
@@ -0,0 +1,530 @@
+//===--- SemaInit.h - Semantic Analysis for Initializers ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file 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/TypeLoc.h"
+#include "clang/Parse/Action.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cassert>
+
+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 temporary object.
+    EK_Temporary,
+    /// \brief The entity being initialized is a base member subobject.
+    EK_Base,
+    /// \brief The entity being initialized is a non-static data member 
+    /// subobject.
+    EK_Member
+  };
+  
+private:
+  /// \brief The kind of entity being initialized.
+  EntityKind Kind;
+
+  /// \brief The type of the object or reference being initialized along with 
+  /// its location information.
+  TypeLoc TL;
+  
+  union {
+    /// \brief When Kind == EK_Variable, EK_Parameter, or EK_Member, 
+    /// the VarDecl, ParmVarDecl, or FieldDecl, respectively.
+    DeclaratorDecl *VariableOrMember;
+    
+    /// \brief When Kind == EK_Result or EK_Exception, the location of the 
+    /// 'return' or 'throw' keyword, respectively. When Kind == EK_Temporary,
+    /// the location where the temporary is being created.
+    unsigned Location;
+    
+    /// \brief When Kind == EK_Base, the base specifier that provides the 
+    /// base class.
+    CXXBaseSpecifier *Base;
+  };
+
+  InitializedEntity() { }
+
+  /// \brief Create the initialization entity for a variable.
+  InitializedEntity(VarDecl *Var)
+    : Kind(EK_Variable), 
+      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Var)) 
+  {
+    InitDeclLoc();
+  }
+  
+  /// \brief Create the initialization entity for a parameter.
+  InitializedEntity(ParmVarDecl *Parm)
+    : Kind(EK_Parameter), 
+      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Parm)) 
+  { 
+    InitDeclLoc();
+  }
+  
+  /// \brief Create the initialization entity for the result of a function,
+  /// throwing an object, or performing an explicit cast.
+  InitializedEntity(EntityKind Kind, SourceLocation Loc, TypeLoc TL)
+    : Kind(Kind), TL(TL), Location(Loc.getRawEncoding()) { }
+  
+  /// \brief Create the initialization entity for a member subobject.
+  InitializedEntity(FieldDecl *Member) 
+    : Kind(EK_Member), 
+      VariableOrMember(reinterpret_cast<DeclaratorDecl*>(Member))
+  { 
+    InitDeclLoc();
+  }
+  
+  /// \brief Initialize type-location information from a declaration.
+  void InitDeclLoc();
+  
+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 the result of a function.
+  static InitializedEntity InitializeResult(SourceLocation ReturnLoc,
+                                            TypeLoc TL) {
+    return InitializedEntity(EK_Result, ReturnLoc, TL);
+  }
+
+  /// \brief Create the initialization entity for an exception object.
+  static InitializedEntity InitializeException(SourceLocation ThrowLoc,
+                                               TypeLoc TL) {
+    return InitializedEntity(EK_Exception, ThrowLoc, TL);
+  }
+  
+  /// \brief Create the initialization entity for a temporary.
+  static InitializedEntity InitializeTemporary(EntityKind Kind, TypeLoc TL) {
+    return InitializedEntity(Kind, SourceLocation(), TL);
+  }
+  
+  /// \brief Create the initialization entity for a base class subobject.
+  static InitializedEntity InitializeBase(ASTContext &Context,
+                                          CXXBaseSpecifier *Base);
+  
+  /// \brief Create the initialize entity for a member subobject.
+  static InitializedEntity InitializeMember(FieldDecl *Member) {
+    return InitializedEntity(Member);
+  }
+  
+  /// \brief Determine the kind of initialization.
+  EntityKind getKind() const { return Kind; }
+  
+  /// \brief Retrieve type being initialized.
+  TypeLoc getType() const { return TL; }
+  
+  /// \brief Determine the location of the 'return' keyword when initializing
+  /// the result of a function call.
+  SourceLocation getReturnLoc() const {
+    assert(getKind() == EK_Result && "No 'return' location!");
+    return SourceLocation::getFromRawEncoding(Location);
+  }
+  
+  /// \brief Determine the location of the 'throw' keyword when initializing
+  /// an exception object.
+  SourceLocation getThrowLoc() const {
+    assert(getKind() == EK_Exception && "No 'throw' location!");
+    return SourceLocation::getFromRawEncoding(Location);
+  }
+};
+  
+/// \brief 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_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) {
+    return InitializationKind(SIK_Value, InitLoc, LParenLoc, RParenLoc);
+  }
+  
+  /// \brief Determine the initialization kind.
+  InitKind getKind() const {
+    if (Kind > SIK_Value)
+      return IK_Direct;
+    
+    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 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[1]);
+  }
+  
+  /// \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.
+  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 reference binding.
+    ReferenceBinding
+  };
+  
+  /// \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 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 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.
+      FunctionDecl *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
+  };
+  
+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;
+  
+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.
+  ///
+  /// \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);
+  
+  /// \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 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);
+  
+  /// \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.
+  void AddReferenceBindingStep(QualType T, bool BindingTemporary);
+  
+  /// \brief Add a new step invoking a conversion function, which is either
+  /// a constructor or a conversion function.
+  void AddUserConversionStep(FunctionDecl *Function);
+  
+  /// \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 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;
+  }
+};
+  
+} // end namespace clang
+
+#endif // LLVM_CLANG_SEMA_INIT_H
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 4443de0..9ca8d76 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1399,13 +1399,13 @@
 /// for overload resolution.
 /// \param UserCast true if looking for user defined conversion for a static
 /// cast.
-Sema::OverloadingResult Sema::IsUserDefinedConversion(
-                                   Expr *From, QualType ToType,
-                                   UserDefinedConversionSequence& User,
-                                   OverloadCandidateSet& CandidateSet,
-                                   bool AllowConversionFunctions,
-                                   bool AllowExplicit, bool ForceRValue,
-                                   bool UserCast) {
+OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
+                                          UserDefinedConversionSequence& User,
+                                            OverloadCandidateSet& CandidateSet,
+                                                bool AllowConversionFunctions,
+                                                bool AllowExplicit, 
+                                                bool ForceRValue,
+                                                bool UserCast) {
   if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
     if (RequireCompleteType(From->getLocStart(), ToType, PDiag())) {
       // We're not going to find any constructors.
@@ -4167,10 +4167,9 @@
 /// function, Best points to the candidate function found.
 ///
 /// \returns The result of overload resolution.
-Sema::OverloadingResult
-Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
-                         SourceLocation Loc,
-                         OverloadCandidateSet::iterator& Best) {
+OverloadingResult Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
+                                           SourceLocation Loc,
+                                        OverloadCandidateSet::iterator& Best) {
   // Find the best viable function.
   Best = CandidateSet.end();
   for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
@@ -5769,4 +5768,9 @@
   return E->Retain();
 }
 
+Sema::OwningExprResult Sema::FixOverloadedFunctionReference(OwningExprResult E, 
+                                                            FunctionDecl *Fn) {
+  return Owned(FixOverloadedFunctionReference((Expr *)E.get(), Fn));
+}
+
 } // end namespace clang
diff --git a/lib/Sema/SemaOverload.h b/lib/Sema/SemaOverload.h
index 5eef3ce..3613d60 100644
--- a/lib/Sema/SemaOverload.h
+++ b/lib/Sema/SemaOverload.h
@@ -15,12 +15,26 @@
 #ifndef LLVM_CLANG_SEMA_OVERLOAD_H
 #define LLVM_CLANG_SEMA_OVERLOAD_H
 
+#include "clang/AST/Decl.h"
+#include "clang/AST/Type.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              ///< Overload resoltuion 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
@@ -271,6 +285,7 @@
   /// 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;
     
   public:
@@ -279,6 +294,12 @@
     bool isNewCandidate(Decl *F) { 
       return Functions.insert(F->getCanonicalDecl()); 
     }
+
+    /// \brief Clear out all of the candidates.
+    void clear() {
+      inherited::clear();
+      Functions.clear();
+    }
   };
 } // end namespace clang