diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 70387c7..687beae 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -434,6 +434,18 @@
   return false;
 }
 
+/// \brief Determine whether this type is any of the built-in character
+/// types.
+bool Type::isAnyCharacterType() const {
+  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+    return (BT->getKind() >= BuiltinType::Char_U &&
+            BT->getKind() <= BuiltinType::Char32) ||
+           (BT->getKind() >= BuiltinType::Char_S &&
+            BT->getKind() <= BuiltinType::WChar);
+  
+  return false;
+}
+
 /// isSignedIntegerType - Return true if this is an integer type that is
 /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
 /// an enum decl which has a signed representation, or a vector of signed
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
 
