diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 884d60d..200214b 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -71,32 +71,43 @@
 
 namespace clang {
 
-  unsigned ASTImporter::getFieldIndex(Decl *F) {
-    assert(F && (isa<FieldDecl>(*F) || isa<IndirectFieldDecl>(*F)) &&
-        "Try to get field index for non-field.");
+  using llvm::make_error;
+  using llvm::Error;
+  using llvm::Expected;
+  using ExpectedType = llvm::Expected<QualType>;
+  using ExpectedStmt = llvm::Expected<Stmt *>;
+  using ExpectedExpr = llvm::Expected<Expr *>;
+  using ExpectedDecl = llvm::Expected<Decl *>;
+  using ExpectedSLoc = llvm::Expected<SourceLocation>;
 
-    auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
-    if (!Owner)
-      return 0;
-
-    unsigned Index = 1;
-    for (const auto *D : Owner->decls()) {
-      if (D == F)
-        return Index;
-
-      if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
-        ++Index;
+  std::string ImportError::toString() const {
+    // FIXME: Improve error texts.
+    switch (Error) {
+    case NameConflict:
+      return "NameConflict";
+    case UnsupportedConstruct:
+      return "UnsupportedConstruct";
+    case Unknown:
+      return "Unknown error";
+    default:
+      llvm_unreachable("Invalid error code.");
     }
-
-    llvm_unreachable("Field was not found in its parent context.");
-
-    return 0;
   }
 
+  void ImportError::log(raw_ostream &OS) const {
+    OS << toString();
+  }
+
+  std::error_code ImportError::convertToErrorCode() const {
+    llvm_unreachable("Function not implemented.");
+  }
+
+  char ImportError::ID;
+
   template <class T>
-  SmallVector<Decl*, 2>
+  SmallVector<Decl *, 2>
   getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
-    SmallVector<Decl*, 2> Redecls;
+    SmallVector<Decl *, 2> Redecls;
     for (auto *R : D->getFirstDecl()->redecls()) {
       if (R != D->getFirstDecl())
         Redecls.push_back(R);
@@ -121,12 +132,132 @@
       To->setIsUsed();
   }
 
-  class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
-                          public DeclVisitor<ASTNodeImporter, Decl *>,
-                          public StmtVisitor<ASTNodeImporter, Stmt *> {
+  Optional<unsigned> ASTImporter::getFieldIndex(Decl *F) {
+    assert(F && (isa<FieldDecl>(*F) || isa<IndirectFieldDecl>(*F)) &&
+        "Try to get field index for non-field.");
+
+    auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
+    if (!Owner)
+      return None;
+
+    unsigned Index = 0;
+    for (const auto *D : Owner->decls()) {
+      if (D == F)
+        return Index;
+
+      if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
+        ++Index;
+    }
+
+    llvm_unreachable("Field was not found in its parent context.");
+
+    return None;
+  }
+
+  // FIXME: Temporary until every import returns Expected.
+  template <>
+  LLVM_NODISCARD Error
+  ASTImporter::importInto(SourceLocation &To, const SourceLocation &From) {
+    To = Import(From);
+    if (From.isValid() && To.isInvalid())
+        return llvm::make_error<ImportError>();
+    return Error::success();
+  }
+  // FIXME: Temporary until every import returns Expected.
+  template <>
+  LLVM_NODISCARD Error
+  ASTImporter::importInto(QualType &To, const QualType &From) {
+    To = Import(From);
+    if (!From.isNull() && To.isNull())
+        return llvm::make_error<ImportError>();
+    return Error::success();
+  }
+
+  class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, ExpectedType>,
+                          public DeclVisitor<ASTNodeImporter, ExpectedDecl>,
+                          public StmtVisitor<ASTNodeImporter, ExpectedStmt> {
     ASTImporter &Importer;
 
-    // Wrapper for an overload set.
+    // Use this instead of Importer.importInto .
+    template <typename ImportT>
+    LLVM_NODISCARD Error importInto(ImportT &To, const ImportT &From) {
+      return Importer.importInto(To, From);
+    }
+
+    // Use this to import pointers of specific type.
+    template <typename ImportT>
+    LLVM_NODISCARD Error importInto(ImportT *&To, ImportT *From) {
+      auto ToI = Importer.Import(From);
+      if (!ToI && From)
+        return make_error<ImportError>();
+      To = cast_or_null<ImportT>(ToI);
+      return Error::success();
+      // FIXME: This should be the final code.
+      //auto ToOrErr = Importer.Import(From);
+      //if (ToOrErr) {
+      //  To = cast_or_null<ImportT>(*ToOrErr);
+      //}
+      //return ToOrErr.takeError();
+    }
+
+    // Call the import function of ASTImporter for a baseclass of type `T` and
+    // cast the return value to `T`.
+    template <typename T>
+    Expected<T *> import(T *From) {
+      auto *To = Importer.Import(From);
+      if (!To && From)
+        return make_error<ImportError>();
+      return cast_or_null<T>(To);
+      // FIXME: This should be the final code.
+      //auto ToOrErr = Importer.Import(From);
+      //if (!ToOrErr)
+      //  return ToOrErr.takeError();
+      //return cast_or_null<T>(*ToOrErr);
+    }
+
+    template <typename T>
+    Expected<T *> import(const T *From) {
+      return import(const_cast<T *>(From));
+    }
+
+    // Call the import function of ASTImporter for type `T`.
+    template <typename T>
+    Expected<T> import(const T &From) {
+      T To = Importer.Import(From);
+      T DefaultT;
+      if (To == DefaultT && !(From == DefaultT))
+        return make_error<ImportError>();
+      return To;
+      // FIXME: This should be the final code.
+      //return Importer.Import(From);
+    }
+
+    template <class T>
+    Expected<std::tuple<T>>
+    importSeq(const T &From) {
+      Expected<T> ToOrErr = import(From);
+      if (!ToOrErr)
+        return ToOrErr.takeError();
+      return std::make_tuple<T>(std::move(*ToOrErr));
+    }
+
+    // Import multiple objects with a single function call.
+    // This should work for every type for which a variant of `import` exists.
+    // The arguments are processed from left to right and import is stopped on
+    // first error.
+    template <class THead, class... TTail>
+    Expected<std::tuple<THead, TTail...>>
+    importSeq(const THead &FromHead, const TTail &...FromTail) {
+      Expected<std::tuple<THead>> ToHeadOrErr = importSeq(FromHead);
+      if (!ToHeadOrErr)
+        return ToHeadOrErr.takeError();
+      Expected<std::tuple<TTail...>> ToTailOrErr = importSeq(FromTail...);
+      if (!ToTailOrErr)
+        return ToTailOrErr.takeError();
+      return std::tuple_cat(*ToHeadOrErr, *ToTailOrErr);
+    }
+
+// Wrapper for an overload set.
     template <typename ToDeclT> struct CallOverloadedCreateFun {
       template <typename... Args>
       auto operator()(Args &&... args)
@@ -171,6 +302,11 @@
     LLVM_NODISCARD bool
     GetImportedOrCreateSpecialDecl(ToDeclT *&ToD, CreateFunT CreateFun,
                                    FromDeclT *FromD, Args &&... args) {
+      // FIXME: This code is needed later.
+      //if (Importer.getImportDeclErrorIfAny(FromD)) {
+      //  ToD = nullptr;
+      //  return true; // Already imported but with error.
+      //}
       ToD = cast_or_null<ToDeclT>(Importer.GetAlreadyImportedOrNull(FromD));
       if (ToD)
         return true; // Already imported.
@@ -194,84 +330,82 @@
   public:
     explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
 
-    using TypeVisitor<ASTNodeImporter, QualType>::Visit;
-    using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
-    using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
+    using TypeVisitor<ASTNodeImporter, ExpectedType>::Visit;
+    using DeclVisitor<ASTNodeImporter, ExpectedDecl>::Visit;
+    using StmtVisitor<ASTNodeImporter, ExpectedStmt>::Visit;
 
     // Importing types
-    QualType VisitType(const Type *T);
-    QualType VisitAtomicType(const AtomicType *T);
-    QualType VisitBuiltinType(const BuiltinType *T);
-    QualType VisitDecayedType(const DecayedType *T);
-    QualType VisitComplexType(const ComplexType *T);
-    QualType VisitPointerType(const PointerType *T);
-    QualType VisitBlockPointerType(const BlockPointerType *T);
-    QualType VisitLValueReferenceType(const LValueReferenceType *T);
-    QualType VisitRValueReferenceType(const RValueReferenceType *T);
-    QualType VisitMemberPointerType(const MemberPointerType *T);
-    QualType VisitConstantArrayType(const ConstantArrayType *T);
-    QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
-    QualType VisitVariableArrayType(const VariableArrayType *T);
-    QualType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
+    ExpectedType VisitType(const Type *T);
+    ExpectedType VisitAtomicType(const AtomicType *T);
+    ExpectedType VisitBuiltinType(const BuiltinType *T);
+    ExpectedType VisitDecayedType(const DecayedType *T);
+    ExpectedType VisitComplexType(const ComplexType *T);
+    ExpectedType VisitPointerType(const PointerType *T);
+    ExpectedType VisitBlockPointerType(const BlockPointerType *T);
+    ExpectedType VisitLValueReferenceType(const LValueReferenceType *T);
+    ExpectedType VisitRValueReferenceType(const RValueReferenceType *T);
+    ExpectedType VisitMemberPointerType(const MemberPointerType *T);
+    ExpectedType VisitConstantArrayType(const ConstantArrayType *T);
+    ExpectedType VisitIncompleteArrayType(const IncompleteArrayType *T);
+    ExpectedType VisitVariableArrayType(const VariableArrayType *T);
+    ExpectedType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
     // FIXME: DependentSizedExtVectorType
-    QualType VisitVectorType(const VectorType *T);
-    QualType VisitExtVectorType(const ExtVectorType *T);
-    QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
-    QualType VisitFunctionProtoType(const FunctionProtoType *T);
-    QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T);
-    QualType VisitParenType(const ParenType *T);
-    QualType VisitTypedefType(const TypedefType *T);
-    QualType VisitTypeOfExprType(const TypeOfExprType *T);
+    ExpectedType VisitVectorType(const VectorType *T);
+    ExpectedType VisitExtVectorType(const ExtVectorType *T);
+    ExpectedType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
+    ExpectedType VisitFunctionProtoType(const FunctionProtoType *T);
+    ExpectedType VisitUnresolvedUsingType(const UnresolvedUsingType *T);
+    ExpectedType VisitParenType(const ParenType *T);
+    ExpectedType VisitTypedefType(const TypedefType *T);
+    ExpectedType VisitTypeOfExprType(const TypeOfExprType *T);
     // FIXME: DependentTypeOfExprType
-    QualType VisitTypeOfType(const TypeOfType *T);
-    QualType VisitDecltypeType(const DecltypeType *T);
-    QualType VisitUnaryTransformType(const UnaryTransformType *T);
-    QualType VisitAutoType(const AutoType *T);
-    QualType VisitInjectedClassNameType(const InjectedClassNameType *T);
+    ExpectedType VisitTypeOfType(const TypeOfType *T);
+    ExpectedType VisitDecltypeType(const DecltypeType *T);
+    ExpectedType VisitUnaryTransformType(const UnaryTransformType *T);
+    ExpectedType VisitAutoType(const AutoType *T);
+    ExpectedType VisitInjectedClassNameType(const InjectedClassNameType *T);
     // FIXME: DependentDecltypeType
-    QualType VisitRecordType(const RecordType *T);
-    QualType VisitEnumType(const EnumType *T);
-    QualType VisitAttributedType(const AttributedType *T);
-    QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T);
-    QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
-    QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
-    QualType VisitElaboratedType(const ElaboratedType *T);
-    QualType VisitDependentNameType(const DependentNameType *T);
-    QualType VisitPackExpansionType(const PackExpansionType *T);
-    QualType VisitDependentTemplateSpecializationType(
+    ExpectedType VisitRecordType(const RecordType *T);
+    ExpectedType VisitEnumType(const EnumType *T);
+    ExpectedType VisitAttributedType(const AttributedType *T);
+    ExpectedType VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+    ExpectedType VisitSubstTemplateTypeParmType(
+        const SubstTemplateTypeParmType *T);
+    ExpectedType VisitTemplateSpecializationType(
+        const TemplateSpecializationType *T);
+    ExpectedType VisitElaboratedType(const ElaboratedType *T);
+    ExpectedType VisitDependentNameType(const DependentNameType *T);
+    ExpectedType VisitPackExpansionType(const PackExpansionType *T);
+    ExpectedType VisitDependentTemplateSpecializationType(
         const DependentTemplateSpecializationType *T);
-    QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
-    QualType VisitObjCObjectType(const ObjCObjectType *T);
-    QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
+    ExpectedType VisitObjCInterfaceType(const ObjCInterfaceType *T);
+    ExpectedType VisitObjCObjectType(const ObjCObjectType *T);
+    ExpectedType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
 
     // Importing declarations
-    bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
-                         DeclContext *&LexicalDC, DeclarationName &Name,
-                         NamedDecl *&ToD, SourceLocation &Loc);
-    void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
-    void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
-                                  DeclarationNameInfo& To);
-    void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
-    void ImportImplicitMethods(const CXXRecordDecl *From, CXXRecordDecl *To);
+    Error ImportDeclParts(
+        NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC,
+        DeclarationName &Name, NamedDecl *&ToD, SourceLocation &Loc);
+    Error ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
+    Error ImportDeclarationNameLoc(
+        const DeclarationNameInfo &From, DeclarationNameInfo &To);
+    Error ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
+    Error ImportDeclContext(
+        Decl *From, DeclContext *&ToDC, DeclContext *&ToLexicalDC);
+    Error ImportImplicitMethods(const CXXRecordDecl *From, CXXRecordDecl *To);
 
-    bool ImportCastPath(CastExpr *E, CXXCastPath &Path);
+    Expected<CXXCastPath> ImportCastPath(CastExpr *E);
 
     using Designator = DesignatedInitExpr::Designator;
 
-    Designator ImportDesignator(const Designator &D);
-
-    Optional<LambdaCapture> ImportLambdaCapture(const LambdaCapture &From);
-
     /// What we should import from the definition.
     enum ImportDefinitionKind {
       /// Import the default subset of the definition, which might be
       /// nothing (if minimal import is set) or might be everything (if minimal
       /// import is not set).
       IDK_Default,
-
       /// Import everything.
       IDK_Everything,
-
       /// Import only the bare bones needed to establish a valid
       /// DeclContext.
       IDK_Basic
@@ -282,41 +416,44 @@
              (IDK == IDK_Default && !Importer.isMinimalImport());
     }
 
-    bool ImportInitializer(VarDecl *From, VarDecl *To);
-    bool ImportDefinition(RecordDecl *From, RecordDecl *To,
-                          ImportDefinitionKind Kind = IDK_Default);
-    bool ImportDefinition(EnumDecl *From, EnumDecl *To,
-                          ImportDefinitionKind Kind = IDK_Default);
-    bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
-                          ImportDefinitionKind Kind = IDK_Default);
-    bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To,
-                          ImportDefinitionKind Kind = IDK_Default);
-    TemplateParameterList *ImportTemplateParameterList(
+    Error ImportInitializer(VarDecl *From, VarDecl *To);
+    Error ImportDefinition(
+        RecordDecl *From, RecordDecl *To,
+        ImportDefinitionKind Kind = IDK_Default);
+    Error ImportDefinition(
+        EnumDecl *From, EnumDecl *To,
+        ImportDefinitionKind Kind = IDK_Default);
+    Error ImportDefinition(
+        ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
+        ImportDefinitionKind Kind = IDK_Default);
+    Error ImportDefinition(
+        ObjCProtocolDecl *From, ObjCProtocolDecl *To,
+        ImportDefinitionKind Kind = IDK_Default);
+    Expected<TemplateParameterList *> ImportTemplateParameterList(
         TemplateParameterList *Params);
-    TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
-    Optional<TemplateArgumentLoc> ImportTemplateArgumentLoc(
-        const TemplateArgumentLoc &TALoc);
-    bool ImportTemplateArguments(const TemplateArgument *FromArgs,
-                                 unsigned NumFromArgs,
-                                 SmallVectorImpl<TemplateArgument> &ToArgs);
+    Error ImportTemplateArguments(
+        const TemplateArgument *FromArgs, unsigned NumFromArgs,
+        SmallVectorImpl<TemplateArgument> &ToArgs);
+    Expected<TemplateArgument>
+    ImportTemplateArgument(const TemplateArgument &From);
 
     template <typename InContainerTy>
-    bool ImportTemplateArgumentListInfo(const InContainerTy &Container,
-                                        TemplateArgumentListInfo &ToTAInfo);
+    Error ImportTemplateArgumentListInfo(
+        const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo);
 
     template<typename InContainerTy>
-    bool ImportTemplateArgumentListInfo(SourceLocation FromLAngleLoc,
-                                        SourceLocation FromRAngleLoc,
-                                        const InContainerTy &Container,
-                                        TemplateArgumentListInfo &Result);
+    Error ImportTemplateArgumentListInfo(
+      SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
+      const InContainerTy &Container, TemplateArgumentListInfo &Result);
 
     using TemplateArgsTy = SmallVector<TemplateArgument, 8>;
-    using OptionalTemplateArgsTy = Optional<TemplateArgsTy>;
-    std::tuple<FunctionTemplateDecl *, OptionalTemplateArgsTy>
+    using FunctionTemplateAndArgsTy =
+        std::tuple<FunctionTemplateDecl *, TemplateArgsTy>;
+    Expected<FunctionTemplateAndArgsTy>
     ImportFunctionTemplateWithTemplateArgsFromSpecialization(
         FunctionDecl *FromFD);
 
-    bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
+    Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
 
     bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
     bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
@@ -330,258 +467,497 @@
     bool IsStructuralMatch(FunctionDecl *From, FunctionDecl *To);
     bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
     bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
-    Decl *VisitDecl(Decl *D);
-    Decl *VisitEmptyDecl(EmptyDecl *D);
-    Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
-    Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
-    Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
-    Decl *VisitNamespaceDecl(NamespaceDecl *D);
-    Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
-    Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
-    Decl *VisitTypedefDecl(TypedefDecl *D);
-    Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
-    Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
-    Decl *VisitLabelDecl(LabelDecl *D);
-    Decl *VisitEnumDecl(EnumDecl *D);
-    Decl *VisitRecordDecl(RecordDecl *D);
-    Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
-    Decl *VisitFunctionDecl(FunctionDecl *D);
-    Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
-    Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
-    Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
-    Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
-    Decl *VisitFieldDecl(FieldDecl *D);
-    Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
-    Decl *VisitFriendDecl(FriendDecl *D);
-    Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
-    Decl *VisitVarDecl(VarDecl *D);
-    Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
-    Decl *VisitParmVarDecl(ParmVarDecl *D);
-    Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
-    Decl *VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
-    Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
-    Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
-    Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D);
-    Decl *VisitUsingDecl(UsingDecl *D);
-    Decl *VisitUsingShadowDecl(UsingShadowDecl *D);
-    Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
-    Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
-    Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+    ExpectedDecl VisitDecl(Decl *D);
+    ExpectedDecl VisitImportDecl(ImportDecl *D);
+    ExpectedDecl VisitEmptyDecl(EmptyDecl *D);
+    ExpectedDecl VisitAccessSpecDecl(AccessSpecDecl *D);
+    ExpectedDecl VisitStaticAssertDecl(StaticAssertDecl *D);
+    ExpectedDecl VisitTranslationUnitDecl(TranslationUnitDecl *D);
+    ExpectedDecl VisitNamespaceDecl(NamespaceDecl *D);
+    ExpectedDecl VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+    ExpectedDecl VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
+    ExpectedDecl VisitTypedefDecl(TypedefDecl *D);
+    ExpectedDecl VisitTypeAliasDecl(TypeAliasDecl *D);
+    ExpectedDecl VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
+    ExpectedDecl VisitLabelDecl(LabelDecl *D);
+    ExpectedDecl VisitEnumDecl(EnumDecl *D);
+    ExpectedDecl VisitRecordDecl(RecordDecl *D);
+    ExpectedDecl VisitEnumConstantDecl(EnumConstantDecl *D);
+    ExpectedDecl VisitFunctionDecl(FunctionDecl *D);
+    ExpectedDecl VisitCXXMethodDecl(CXXMethodDecl *D);
+    ExpectedDecl VisitCXXConstructorDecl(CXXConstructorDecl *D);
+    ExpectedDecl VisitCXXDestructorDecl(CXXDestructorDecl *D);
+    ExpectedDecl VisitCXXConversionDecl(CXXConversionDecl *D);
+    ExpectedDecl VisitFieldDecl(FieldDecl *D);
+    ExpectedDecl VisitIndirectFieldDecl(IndirectFieldDecl *D);
+    ExpectedDecl VisitFriendDecl(FriendDecl *D);
+    ExpectedDecl VisitObjCIvarDecl(ObjCIvarDecl *D);
+    ExpectedDecl VisitVarDecl(VarDecl *D);
+    ExpectedDecl VisitImplicitParamDecl(ImplicitParamDecl *D);
+    ExpectedDecl VisitParmVarDecl(ParmVarDecl *D);
+    ExpectedDecl VisitObjCMethodDecl(ObjCMethodDecl *D);
+    ExpectedDecl VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
+    ExpectedDecl VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+    ExpectedDecl VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+    ExpectedDecl VisitLinkageSpecDecl(LinkageSpecDecl *D);
+    ExpectedDecl VisitUsingDecl(UsingDecl *D);
+    ExpectedDecl VisitUsingShadowDecl(UsingShadowDecl *D);
+    ExpectedDecl VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+    ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+    ExpectedDecl VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
 
-    ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list);
-    Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
-    Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
-    Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
-    Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
-    Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
-    Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
-    Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
-    Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
-    Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
-    Decl *VisitClassTemplateSpecializationDecl(
+    Expected<ObjCTypeParamList *>
+    ImportObjCTypeParamList(ObjCTypeParamList *list);
+
+    ExpectedDecl VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+    ExpectedDecl VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+    ExpectedDecl VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+    ExpectedDecl VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+    ExpectedDecl VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+    ExpectedDecl VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+    ExpectedDecl VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+    ExpectedDecl VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+    ExpectedDecl VisitClassTemplateDecl(ClassTemplateDecl *D);
+    ExpectedDecl VisitClassTemplateSpecializationDecl(
                                             ClassTemplateSpecializationDecl *D);
-    Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
-    Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
-    Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+    ExpectedDecl VisitVarTemplateDecl(VarTemplateDecl *D);
+    ExpectedDecl VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
+    ExpectedDecl VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
 
     // Importing statements
-    DeclGroupRef ImportDeclGroup(DeclGroupRef DG);
-
-    Stmt *VisitStmt(Stmt *S);
-    Stmt *VisitGCCAsmStmt(GCCAsmStmt *S);
-    Stmt *VisitDeclStmt(DeclStmt *S);
-    Stmt *VisitNullStmt(NullStmt *S);
-    Stmt *VisitCompoundStmt(CompoundStmt *S);
-    Stmt *VisitCaseStmt(CaseStmt *S);
-    Stmt *VisitDefaultStmt(DefaultStmt *S);
-    Stmt *VisitLabelStmt(LabelStmt *S);
-    Stmt *VisitAttributedStmt(AttributedStmt *S);
-    Stmt *VisitIfStmt(IfStmt *S);
-    Stmt *VisitSwitchStmt(SwitchStmt *S);
-    Stmt *VisitWhileStmt(WhileStmt *S);
-    Stmt *VisitDoStmt(DoStmt *S);
-    Stmt *VisitForStmt(ForStmt *S);
-    Stmt *VisitGotoStmt(GotoStmt *S);
-    Stmt *VisitIndirectGotoStmt(IndirectGotoStmt *S);
-    Stmt *VisitContinueStmt(ContinueStmt *S);
-    Stmt *VisitBreakStmt(BreakStmt *S);
-    Stmt *VisitReturnStmt(ReturnStmt *S);
+    ExpectedStmt VisitStmt(Stmt *S);
+    ExpectedStmt VisitGCCAsmStmt(GCCAsmStmt *S);
+    ExpectedStmt VisitDeclStmt(DeclStmt *S);
+    ExpectedStmt VisitNullStmt(NullStmt *S);
+    ExpectedStmt VisitCompoundStmt(CompoundStmt *S);
+    ExpectedStmt VisitCaseStmt(CaseStmt *S);
+    ExpectedStmt VisitDefaultStmt(DefaultStmt *S);
+    ExpectedStmt VisitLabelStmt(LabelStmt *S);
+    ExpectedStmt VisitAttributedStmt(AttributedStmt *S);
+    ExpectedStmt VisitIfStmt(IfStmt *S);
+    ExpectedStmt VisitSwitchStmt(SwitchStmt *S);
+    ExpectedStmt VisitWhileStmt(WhileStmt *S);
+    ExpectedStmt VisitDoStmt(DoStmt *S);
+    ExpectedStmt VisitForStmt(ForStmt *S);
+    ExpectedStmt VisitGotoStmt(GotoStmt *S);
+    ExpectedStmt VisitIndirectGotoStmt(IndirectGotoStmt *S);
+    ExpectedStmt VisitContinueStmt(ContinueStmt *S);
+    ExpectedStmt VisitBreakStmt(BreakStmt *S);
+    ExpectedStmt VisitReturnStmt(ReturnStmt *S);
     // FIXME: MSAsmStmt
     // FIXME: SEHExceptStmt
     // FIXME: SEHFinallyStmt
     // FIXME: SEHTryStmt
     // FIXME: SEHLeaveStmt
     // FIXME: CapturedStmt
-    Stmt *VisitCXXCatchStmt(CXXCatchStmt *S);
-    Stmt *VisitCXXTryStmt(CXXTryStmt *S);
-    Stmt *VisitCXXForRangeStmt(CXXForRangeStmt *S);
+    ExpectedStmt VisitCXXCatchStmt(CXXCatchStmt *S);
+    ExpectedStmt VisitCXXTryStmt(CXXTryStmt *S);
+    ExpectedStmt VisitCXXForRangeStmt(CXXForRangeStmt *S);
     // FIXME: MSDependentExistsStmt
-    Stmt *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
-    Stmt *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
-    Stmt *VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S);
-    Stmt *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
-    Stmt *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
-    Stmt *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
-    Stmt *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
+    ExpectedStmt VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
+    ExpectedStmt VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
+    ExpectedStmt VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S);
+    ExpectedStmt VisitObjCAtTryStmt(ObjCAtTryStmt *S);
+    ExpectedStmt VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    ExpectedStmt VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
+    ExpectedStmt VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
 
     // Importing expressions
-    Expr *VisitExpr(Expr *E);
-    Expr *VisitVAArgExpr(VAArgExpr *E);
-    Expr *VisitGNUNullExpr(GNUNullExpr *E);
-    Expr *VisitPredefinedExpr(PredefinedExpr *E);
-    Expr *VisitDeclRefExpr(DeclRefExpr *E);
-    Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *ILE);
-    Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E);
-    Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
-    Expr *VisitIntegerLiteral(IntegerLiteral *E);
-    Expr *VisitFloatingLiteral(FloatingLiteral *E);
-    Expr *VisitImaginaryLiteral(ImaginaryLiteral *E);
-    Expr *VisitCharacterLiteral(CharacterLiteral *E);
-    Expr *VisitStringLiteral(StringLiteral *E);
-    Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
-    Expr *VisitAtomicExpr(AtomicExpr *E);
-    Expr *VisitAddrLabelExpr(AddrLabelExpr *E);
-    Expr *VisitParenExpr(ParenExpr *E);
-    Expr *VisitParenListExpr(ParenListExpr *E);
-    Expr *VisitStmtExpr(StmtExpr *E);
-    Expr *VisitUnaryOperator(UnaryOperator *E);
-    Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
-    Expr *VisitBinaryOperator(BinaryOperator *E);
-    Expr *VisitConditionalOperator(ConditionalOperator *E);
-    Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E);
-    Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E);
-    Expr *VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
-    Expr *VisitExpressionTraitExpr(ExpressionTraitExpr *E);
-    Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
-    Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
-    Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
-    Expr *VisitExplicitCastExpr(ExplicitCastExpr *E);
-    Expr *VisitOffsetOfExpr(OffsetOfExpr *OE);
-    Expr *VisitCXXThrowExpr(CXXThrowExpr *E);
-    Expr *VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
-    Expr *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
-    Expr *VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
-    Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
-    Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
-    Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
-    Expr *VisitPackExpansionExpr(PackExpansionExpr *E);
-    Expr *VisitSizeOfPackExpr(SizeOfPackExpr *E);
-    Expr *VisitCXXNewExpr(CXXNewExpr *CE);
-    Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
-    Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
-    Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
-    Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
-    Expr *VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
-    Expr *VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *CE);
-    Expr *VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
-    Expr *VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
-    Expr *VisitExprWithCleanups(ExprWithCleanups *EWC);
-    Expr *VisitCXXThisExpr(CXXThisExpr *E);
-    Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
-    Expr *VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
-    Expr *VisitMemberExpr(MemberExpr *E);
-    Expr *VisitCallExpr(CallExpr *E);
-    Expr *VisitLambdaExpr(LambdaExpr *LE);
-    Expr *VisitInitListExpr(InitListExpr *E);
-    Expr *VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
-    Expr *VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E);
-    Expr *VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
-    Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
-    Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
-    Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
-    Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
-    Expr *VisitTypeTraitExpr(TypeTraitExpr *E);
-    Expr *VisitCXXTypeidExpr(CXXTypeidExpr *E);
+    ExpectedStmt VisitExpr(Expr *E);
+    ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
+    ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
+    ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E);
+    ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E);
+    ExpectedStmt VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
+    ExpectedStmt VisitDesignatedInitExpr(DesignatedInitExpr *E);
+    ExpectedStmt VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
+    ExpectedStmt VisitIntegerLiteral(IntegerLiteral *E);
+    ExpectedStmt VisitFloatingLiteral(FloatingLiteral *E);
+    ExpectedStmt VisitImaginaryLiteral(ImaginaryLiteral *E);
+    ExpectedStmt VisitCharacterLiteral(CharacterLiteral *E);
+    ExpectedStmt VisitStringLiteral(StringLiteral *E);
+    ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+    ExpectedStmt VisitAtomicExpr(AtomicExpr *E);
+    ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E);
+    ExpectedStmt VisitParenExpr(ParenExpr *E);
+    ExpectedStmt VisitParenListExpr(ParenListExpr *E);
+    ExpectedStmt VisitStmtExpr(StmtExpr *E);
+    ExpectedStmt VisitUnaryOperator(UnaryOperator *E);
+    ExpectedStmt VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
+    ExpectedStmt VisitBinaryOperator(BinaryOperator *E);
+    ExpectedStmt VisitConditionalOperator(ConditionalOperator *E);
+    ExpectedStmt VisitBinaryConditionalOperator(BinaryConditionalOperator *E);
+    ExpectedStmt VisitOpaqueValueExpr(OpaqueValueExpr *E);
+    ExpectedStmt VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
+    ExpectedStmt VisitExpressionTraitExpr(ExpressionTraitExpr *E);
+    ExpectedStmt VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+    ExpectedStmt VisitCompoundAssignOperator(CompoundAssignOperator *E);
+    ExpectedStmt VisitImplicitCastExpr(ImplicitCastExpr *E);
+    ExpectedStmt VisitExplicitCastExpr(ExplicitCastExpr *E);
+    ExpectedStmt VisitOffsetOfExpr(OffsetOfExpr *OE);
+    ExpectedStmt VisitCXXThrowExpr(CXXThrowExpr *E);
+    ExpectedStmt VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
+    ExpectedStmt VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+    ExpectedStmt VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
+    ExpectedStmt VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+    ExpectedStmt VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
+    ExpectedStmt VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
+    ExpectedStmt VisitPackExpansionExpr(PackExpansionExpr *E);
+    ExpectedStmt VisitSizeOfPackExpr(SizeOfPackExpr *E);
+    ExpectedStmt VisitCXXNewExpr(CXXNewExpr *E);
+    ExpectedStmt VisitCXXDeleteExpr(CXXDeleteExpr *E);
+    ExpectedStmt VisitCXXConstructExpr(CXXConstructExpr *E);
+    ExpectedStmt VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+    ExpectedStmt VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+    ExpectedStmt VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
+    ExpectedStmt VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
+    ExpectedStmt VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
+    ExpectedStmt VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
+    ExpectedStmt VisitExprWithCleanups(ExprWithCleanups *E);
+    ExpectedStmt VisitCXXThisExpr(CXXThisExpr *E);
+    ExpectedStmt VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+    ExpectedStmt VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
+    ExpectedStmt VisitMemberExpr(MemberExpr *E);
+    ExpectedStmt VisitCallExpr(CallExpr *E);
+    ExpectedStmt VisitLambdaExpr(LambdaExpr *LE);
+    ExpectedStmt VisitInitListExpr(InitListExpr *E);
+    ExpectedStmt VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
+    ExpectedStmt VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E);
+    ExpectedStmt VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
+    ExpectedStmt VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
+    ExpectedStmt VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
+    ExpectedStmt VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+    ExpectedStmt VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
+    ExpectedStmt VisitTypeTraitExpr(TypeTraitExpr *E);
+    ExpectedStmt VisitCXXTypeidExpr(CXXTypeidExpr *E);
 
     template<typename IIter, typename OIter>
-    void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) {
+    Error ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
       using ItemT = typename std::remove_reference<decltype(*Obegin)>::type;
-
-      ASTImporter &ImporterRef = Importer;
-      std::transform(Ibegin, Iend, Obegin,
-                     [&ImporterRef](ItemT From) -> ItemT {
-                       return ImporterRef.Import(From);
-                     });
+      for (; Ibegin != Iend; ++Ibegin, ++Obegin) {
+        Expected<ItemT> ToOrErr = import(*Ibegin);
+        if (!ToOrErr)
+          return ToOrErr.takeError();
+        *Obegin = *ToOrErr;
+      }
+      return Error::success();
     }
 
-    template<typename IIter, typename OIter>
-    bool ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
-      using ItemT = typename std::remove_reference<decltype(**Obegin)>::type;
-
-      ASTImporter &ImporterRef = Importer;
-      bool Failed = false;
-      std::transform(Ibegin, Iend, Obegin,
-                     [&ImporterRef, &Failed](ItemT *From) -> ItemT * {
-                       auto *To = cast_or_null<ItemT>(ImporterRef.Import(From));
-                       if (!To && From)
-                         Failed = true;
-                       return To;
-                     });
-      return Failed;
-    }
-
+    // Import every item from a container structure into an output container.
+    // If error occurs, stops at first error and returns the error.
+    // The output container should have space for all needed elements (it is not
+    // expanded, new items are put into from the beginning).
     template<typename InContainerTy, typename OutContainerTy>
-    bool ImportContainerChecked(const InContainerTy &InContainer,
-                                OutContainerTy &OutContainer) {
-      return ImportArrayChecked(InContainer.begin(), InContainer.end(),
-                                OutContainer.begin());
+    Error ImportContainerChecked(
+        const InContainerTy &InContainer, OutContainerTy &OutContainer) {
+      return ImportArrayChecked(
+          InContainer.begin(), InContainer.end(), OutContainer.begin());
     }
 
     template<typename InContainerTy, typename OIter>
-    bool ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
+    Error ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
       return ImportArrayChecked(InContainer.begin(), InContainer.end(), Obegin);
     }
 
-    // Importing overrides.
     void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
 
-    FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl *FromFD);
+    Expected<FunctionDecl *> FindFunctionTemplateSpecialization(
+        FunctionDecl *FromFD);
   };
 
+// FIXME: Temporary until every import returns Expected.
+template <>
+Expected<TemplateName> ASTNodeImporter::import(const TemplateName &From) {
+  TemplateName To = Importer.Import(From);
+  if (To.isNull() && !From.isNull())
+    return make_error<ImportError>();
+  return To;
+}
+
 template <typename InContainerTy>
-bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+Error ASTNodeImporter::ImportTemplateArgumentListInfo(
     SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
     const InContainerTy &Container, TemplateArgumentListInfo &Result) {
-  TemplateArgumentListInfo ToTAInfo(Importer.Import(FromLAngleLoc),
-                                    Importer.Import(FromRAngleLoc));
-  if (ImportTemplateArgumentListInfo(Container, ToTAInfo))
-    return true;
+  auto ToLAngleLocOrErr = import(FromLAngleLoc);
+  if (!ToLAngleLocOrErr)
+    return ToLAngleLocOrErr.takeError();
+  auto ToRAngleLocOrErr = import(FromRAngleLoc);
+  if (!ToRAngleLocOrErr)
+    return ToRAngleLocOrErr.takeError();
+
+  TemplateArgumentListInfo ToTAInfo(*ToLAngleLocOrErr, *ToRAngleLocOrErr);
+  if (auto Err = ImportTemplateArgumentListInfo(Container, ToTAInfo))
+    return Err;
   Result = ToTAInfo;
-  return false;
+  return Error::success();
 }
 
 template <>
-bool ASTNodeImporter::ImportTemplateArgumentListInfo<TemplateArgumentListInfo>(
+Error ASTNodeImporter::ImportTemplateArgumentListInfo<TemplateArgumentListInfo>(
     const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) {
   return ImportTemplateArgumentListInfo(
       From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result);
 }
 
 template <>
-bool ASTNodeImporter::ImportTemplateArgumentListInfo<
-    ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo &From,
-                                 TemplateArgumentListInfo &Result) {
-  return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc,
-                                        From.arguments(), Result);
+Error ASTNodeImporter::ImportTemplateArgumentListInfo<
+    ASTTemplateArgumentListInfo>(
+        const ASTTemplateArgumentListInfo &From,
+        TemplateArgumentListInfo &Result) {
+  return ImportTemplateArgumentListInfo(
+      From.LAngleLoc, From.RAngleLoc, From.arguments(), Result);
 }
 
-std::tuple<FunctionTemplateDecl *, ASTNodeImporter::OptionalTemplateArgsTy>
+Expected<ASTNodeImporter::FunctionTemplateAndArgsTy>
 ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
     FunctionDecl *FromFD) {
   assert(FromFD->getTemplatedKind() ==
-         FunctionDecl::TK_FunctionTemplateSpecialization);
+      FunctionDecl::TK_FunctionTemplateSpecialization);
+
+  FunctionTemplateAndArgsTy Result;
+
   auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
-  auto *Template = cast_or_null<FunctionTemplateDecl>(
-      Importer.Import(FTSInfo->getTemplate()));
+  if (Error Err = importInto(std::get<0>(Result), FTSInfo->getTemplate()))
+    return std::move(Err);
 
   // Import template arguments.
   auto TemplArgs = FTSInfo->TemplateArguments->asArray();
-  TemplateArgsTy ToTemplArgs;
-  if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
-                              ToTemplArgs)) // Error during import.
-    return std::make_tuple(Template, OptionalTemplateArgsTy());
+  if (Error Err = ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
+      std::get<1>(Result)))
+    return std::move(Err);
 
-  return std::make_tuple(Template, ToTemplArgs);
+  return Result;
+}
+
+template <>
+Expected<TemplateParameterList *>
+ASTNodeImporter::import(TemplateParameterList *From) {
+  SmallVector<NamedDecl *, 4> To(From->size());
+  if (Error Err = ImportContainerChecked(*From, To))
+    return std::move(Err);
+
+  ExpectedExpr ToRequiresClause = import(From->getRequiresClause());
+  if (!ToRequiresClause)
+    return ToRequiresClause.takeError();
+
+  auto ToTemplateLocOrErr = import(From->getTemplateLoc());
+  if (!ToTemplateLocOrErr)
+    return ToTemplateLocOrErr.takeError();
+  auto ToLAngleLocOrErr = import(From->getLAngleLoc());
+  if (!ToLAngleLocOrErr)
+    return ToLAngleLocOrErr.takeError();
+  auto ToRAngleLocOrErr = import(From->getRAngleLoc());
+  if (!ToRAngleLocOrErr)
+    return ToRAngleLocOrErr.takeError();
+
+  return TemplateParameterList::Create(
+      Importer.getToContext(),
+      *ToTemplateLocOrErr,
+      *ToLAngleLocOrErr,
+      To,
+      *ToRAngleLocOrErr,
+      *ToRequiresClause);
+}
+
+template <>
+Expected<TemplateArgument>
+ASTNodeImporter::import(const TemplateArgument &From) {
+  switch (From.getKind()) {
+  case TemplateArgument::Null:
+    return TemplateArgument();
+
+  case TemplateArgument::Type: {
+    ExpectedType ToTypeOrErr = import(From.getAsType());
+    if (!ToTypeOrErr)
+      return ToTypeOrErr.takeError();
+    return TemplateArgument(*ToTypeOrErr);
+  }
+
+  case TemplateArgument::Integral: {
+    ExpectedType ToTypeOrErr = import(From.getIntegralType());
+    if (!ToTypeOrErr)
+      return ToTypeOrErr.takeError();
+    return TemplateArgument(From, *ToTypeOrErr);
+  }
+
+  case TemplateArgument::Declaration: {
+    Expected<ValueDecl *> ToOrErr = import(From.getAsDecl());
+    if (!ToOrErr)
+      return ToOrErr.takeError();
+    ExpectedType ToTypeOrErr = import(From.getParamTypeForDecl());
+    if (!ToTypeOrErr)
+      return ToTypeOrErr.takeError();
+    return TemplateArgument(*ToOrErr, *ToTypeOrErr);
+  }
+
+  case TemplateArgument::NullPtr: {
+    ExpectedType ToTypeOrErr = import(From.getNullPtrType());
+    if (!ToTypeOrErr)
+      return ToTypeOrErr.takeError();
+    return TemplateArgument(*ToTypeOrErr, /*isNullPtr*/true);
+  }
+
+  case TemplateArgument::Template: {
+    Expected<TemplateName> ToTemplateOrErr = import(From.getAsTemplate());
+    if (!ToTemplateOrErr)
+      return ToTemplateOrErr.takeError();
+
+    return TemplateArgument(*ToTemplateOrErr);
+  }
+
+  case TemplateArgument::TemplateExpansion: {
+    Expected<TemplateName> ToTemplateOrErr =
+        import(From.getAsTemplateOrTemplatePattern());
+    if (!ToTemplateOrErr)
+      return ToTemplateOrErr.takeError();
+
+    return TemplateArgument(
+        *ToTemplateOrErr, From.getNumTemplateExpansions());
+  }
+
+  case TemplateArgument::Expression:
+    if (ExpectedExpr ToExpr = import(From.getAsExpr()))
+      return TemplateArgument(*ToExpr);
+    else
+      return ToExpr.takeError();
+
+  case TemplateArgument::Pack: {
+    SmallVector<TemplateArgument, 2> ToPack;
+    ToPack.reserve(From.pack_size());
+    if (Error Err = ImportTemplateArguments(
+        From.pack_begin(), From.pack_size(), ToPack))
+      return std::move(Err);
+
+    return TemplateArgument(
+        llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
+  }
+  }
+
+  llvm_unreachable("Invalid template argument kind");
+}
+
+template <>
+Expected<TemplateArgumentLoc>
+ASTNodeImporter::import(const TemplateArgumentLoc &TALoc) {
+  Expected<TemplateArgument> ArgOrErr = import(TALoc.getArgument());
+  if (!ArgOrErr)
+    return ArgOrErr.takeError();
+  TemplateArgument Arg = *ArgOrErr;
+
+  TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
+
+  TemplateArgumentLocInfo ToInfo;
+  if (Arg.getKind() == TemplateArgument::Expression) {
+    ExpectedExpr E = import(FromInfo.getAsExpr());
+    if (!E)
+      return E.takeError();
+    ToInfo = TemplateArgumentLocInfo(*E);
+  } else if (Arg.getKind() == TemplateArgument::Type) {
+    if (auto TSIOrErr = import(FromInfo.getAsTypeSourceInfo()))
+      ToInfo = TemplateArgumentLocInfo(*TSIOrErr);
+    else
+      return TSIOrErr.takeError();
+  } else {
+    auto ToTemplateQualifierLocOrErr =
+        import(FromInfo.getTemplateQualifierLoc());
+    if (!ToTemplateQualifierLocOrErr)
+      return ToTemplateQualifierLocOrErr.takeError();
+    auto ToTemplateNameLocOrErr = import(FromInfo.getTemplateNameLoc());
+    if (!ToTemplateNameLocOrErr)
+      return ToTemplateNameLocOrErr.takeError();
+    auto ToTemplateEllipsisLocOrErr =
+        import(FromInfo.getTemplateEllipsisLoc());
+    if (!ToTemplateEllipsisLocOrErr)
+      return ToTemplateEllipsisLocOrErr.takeError();
+
+    ToInfo = TemplateArgumentLocInfo(
+          *ToTemplateQualifierLocOrErr,
+          *ToTemplateNameLocOrErr,
+          *ToTemplateEllipsisLocOrErr);
+  }
+
+  return TemplateArgumentLoc(Arg, ToInfo);
+}
+
+template <>
+Expected<DeclGroupRef> ASTNodeImporter::import(const DeclGroupRef &DG) {
+  if (DG.isNull())
+    return DeclGroupRef::Create(Importer.getToContext(), nullptr, 0);
+  size_t NumDecls = DG.end() - DG.begin();
+  SmallVector<Decl *, 1> ToDecls;
+  ToDecls.reserve(NumDecls);
+  for (Decl *FromD : DG) {
+    if (auto ToDOrErr = import(FromD))
+      ToDecls.push_back(*ToDOrErr);
+    else
+      return ToDOrErr.takeError();
+  }
+  return DeclGroupRef::Create(Importer.getToContext(),
+                              ToDecls.begin(),
+                              NumDecls);
+}
+
+template <>
+Expected<ASTNodeImporter::Designator>
+ASTNodeImporter::import(const Designator &D) {
+  if (D.isFieldDesignator()) {
+    IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName());
+
+    ExpectedSLoc ToDotLocOrErr = import(D.getDotLoc());
+    if (!ToDotLocOrErr)
+      return ToDotLocOrErr.takeError();
+
+    ExpectedSLoc ToFieldLocOrErr = import(D.getFieldLoc());
+    if (!ToFieldLocOrErr)
+      return ToFieldLocOrErr.takeError();
+
+    return Designator(ToFieldName, *ToDotLocOrErr, *ToFieldLocOrErr);
+  }
+
+  ExpectedSLoc ToLBracketLocOrErr = import(D.getLBracketLoc());
+  if (!ToLBracketLocOrErr)
+    return ToLBracketLocOrErr.takeError();
+
+  ExpectedSLoc ToRBracketLocOrErr = import(D.getRBracketLoc());
+  if (!ToRBracketLocOrErr)
+    return ToRBracketLocOrErr.takeError();
+
+  if (D.isArrayDesignator())
+    return Designator(D.getFirstExprIndex(),
+                      *ToLBracketLocOrErr, *ToRBracketLocOrErr);
+
+  ExpectedSLoc ToEllipsisLocOrErr = import(D.getEllipsisLoc());
+  if (!ToEllipsisLocOrErr)
+    return ToEllipsisLocOrErr.takeError();
+
+  assert(D.isArrayRangeDesignator());
+  return Designator(
+      D.getFirstExprIndex(), *ToLBracketLocOrErr, *ToEllipsisLocOrErr,
+      *ToRBracketLocOrErr);
+}
+
+template <>
+Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
+  VarDecl *Var = nullptr;
+  if (From.capturesVariable()) {
+    if (auto VarOrErr = import(From.getCapturedVar()))
+      Var = *VarOrErr;
+    else
+      return VarOrErr.takeError();
+  }
+
+  auto LocationOrErr = import(From.getLocation());
+  if (!LocationOrErr)
+    return LocationOrErr.takeError();
+
+  SourceLocation EllipsisLoc;
+  if (From.isPackExpansion())
+    if (Error Err = importInto(EllipsisLoc, From.getEllipsisLoc()))
+      return std::move(Err);
+
+  return LambdaCapture(
+      *LocationOrErr, From.isImplicit(), From.getCaptureKind(), Var,
+      EllipsisLoc);
 }
 
 } // namespace clang
@@ -592,21 +968,21 @@
 
 using namespace clang;
 
-QualType ASTNodeImporter::VisitType(const Type *T) {
+ExpectedType ASTNodeImporter::VisitType(const Type *T) {
   Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
     << T->getTypeClassName();
-  return {};
+  return make_error<ImportError>(ImportError::UnsupportedConstruct);
 }
 
-QualType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
-  QualType UnderlyingType = Importer.Import(T->getValueType());
-  if(UnderlyingType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
+  ExpectedType UnderlyingTypeOrErr = import(T->getValueType());
+  if (!UnderlyingTypeOrErr)
+    return UnderlyingTypeOrErr.takeError();
 
-  return Importer.getToContext().getAtomicType(UnderlyingType);
+  return Importer.getToContext().getAtomicType(*UnderlyingTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
+ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
   switch (T->getKind()) {
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
   case BuiltinType::Id: \
@@ -651,183 +1027,196 @@
   llvm_unreachable("Invalid BuiltinType Kind!");
 }
 
-QualType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
-  QualType OrigT = Importer.Import(T->getOriginalType());
-  if (OrigT.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
+  ExpectedType ToOriginalTypeOrErr = import(T->getOriginalType());
+  if (!ToOriginalTypeOrErr)
+    return ToOriginalTypeOrErr.takeError();
 
-  return Importer.getToContext().getDecayedType(OrigT);
+  return Importer.getToContext().getDecayedType(*ToOriginalTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
+  ExpectedType ToElementTypeOrErr = import(T->getElementType());
+  if (!ToElementTypeOrErr)
+    return ToElementTypeOrErr.takeError();
 
-  return Importer.getToContext().getComplexType(ToElementType);
+  return Importer.getToContext().getComplexType(*ToElementTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitPointerType(const PointerType *T) {
-  QualType ToPointeeType = Importer.Import(T->getPointeeType());
-  if (ToPointeeType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitPointerType(const PointerType *T) {
+  ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+  if (!ToPointeeTypeOrErr)
+    return ToPointeeTypeOrErr.takeError();
 
-  return Importer.getToContext().getPointerType(ToPointeeType);
+  return Importer.getToContext().getPointerType(*ToPointeeTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
+ExpectedType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
   // FIXME: Check for blocks support in "to" context.
-  QualType ToPointeeType = Importer.Import(T->getPointeeType());
-  if (ToPointeeType.isNull())
-    return {};
+  ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+  if (!ToPointeeTypeOrErr)
+    return ToPointeeTypeOrErr.takeError();
 
-  return Importer.getToContext().getBlockPointerType(ToPointeeType);
+  return Importer.getToContext().getBlockPointerType(*ToPointeeTypeOrErr);
 }
 
-QualType
+ExpectedType
 ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
   // FIXME: Check for C++ support in "to" context.
-  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
-  if (ToPointeeType.isNull())
-    return {};
+  ExpectedType ToPointeeTypeOrErr = import(T->getPointeeTypeAsWritten());
+  if (!ToPointeeTypeOrErr)
+    return ToPointeeTypeOrErr.takeError();
 
-  return Importer.getToContext().getLValueReferenceType(ToPointeeType);
+  return Importer.getToContext().getLValueReferenceType(*ToPointeeTypeOrErr);
 }
 
-QualType
+ExpectedType
 ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
   // FIXME: Check for C++0x support in "to" context.
-  QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
-  if (ToPointeeType.isNull())
-    return {};
+  ExpectedType ToPointeeTypeOrErr = import(T->getPointeeTypeAsWritten());
+  if (!ToPointeeTypeOrErr)
+    return ToPointeeTypeOrErr.takeError();
 
-  return Importer.getToContext().getRValueReferenceType(ToPointeeType);
+  return Importer.getToContext().getRValueReferenceType(*ToPointeeTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
+ExpectedType
+ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
   // FIXME: Check for C++ support in "to" context.
-  QualType ToPointeeType = Importer.Import(T->getPointeeType());
-  if (ToPointeeType.isNull())
-    return {};
+  ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+  if (!ToPointeeTypeOrErr)
+    return ToPointeeTypeOrErr.takeError();
 
-  QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
-  return Importer.getToContext().getMemberPointerType(ToPointeeType,
-                                                      ClassType.getTypePtr());
+  ExpectedType ClassTypeOrErr = import(QualType(T->getClass(), 0));
+  if (!ClassTypeOrErr)
+    return ClassTypeOrErr.takeError();
+
+  return Importer.getToContext().getMemberPointerType(
+      *ToPointeeTypeOrErr, (*ClassTypeOrErr).getTypePtr());
 }
 
-QualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
+ExpectedType
+ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
+  ExpectedType ToElementTypeOrErr = import(T->getElementType());
+  if (!ToElementTypeOrErr)
+    return ToElementTypeOrErr.takeError();
 
-  return Importer.getToContext().getConstantArrayType(ToElementType,
+  return Importer.getToContext().getConstantArrayType(*ToElementTypeOrErr,
                                                       T->getSize(),
                                                       T->getSizeModifier(),
                                                T->getIndexTypeCVRQualifiers());
 }
 
-QualType
+ExpectedType
 ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
+  ExpectedType ToElementTypeOrErr = import(T->getElementType());
+  if (!ToElementTypeOrErr)
+    return ToElementTypeOrErr.takeError();
 
-  return Importer.getToContext().getIncompleteArrayType(ToElementType,
+  return Importer.getToContext().getIncompleteArrayType(*ToElementTypeOrErr,
                                                         T->getSizeModifier(),
                                                 T->getIndexTypeCVRQualifiers());
 }
 
-QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
+ExpectedType
+ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
+  QualType ToElementType;
+  Expr *ToSizeExpr;
+  SourceRange ToBracketsRange;
+  if (auto Imp = importSeq(
+      T->getElementType(), T->getSizeExpr(), T->getBracketsRange()))
+    std::tie(ToElementType, ToSizeExpr, ToBracketsRange) = *Imp;
+  else
+    return Imp.takeError();
 
-  Expr *Size = Importer.Import(T->getSizeExpr());
-  if (!Size)
-    return {};
-
-  SourceRange Brackets = Importer.Import(T->getBracketsRange());
-  return Importer.getToContext().getVariableArrayType(ToElementType, Size,
-                                                      T->getSizeModifier(),
-                                                T->getIndexTypeCVRQualifiers(),
-                                                      Brackets);
+  return Importer.getToContext().getVariableArrayType(
+      ToElementType, ToSizeExpr, T->getSizeModifier(),
+      T->getIndexTypeCVRQualifiers(), ToBracketsRange);
 }
 
-QualType ASTNodeImporter::VisitDependentSizedArrayType(
+ExpectedType ASTNodeImporter::VisitDependentSizedArrayType(
     const DependentSizedArrayType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
-
+  QualType ToElementType;
+  Expr *ToSizeExpr;
+  SourceRange ToBracketsRange;
+  if (auto Imp = importSeq(
+      T->getElementType(), T->getSizeExpr(), T->getBracketsRange()))
+    std::tie(ToElementType, ToSizeExpr, ToBracketsRange) = *Imp;
+  else
+    return Imp.takeError();
   // SizeExpr may be null if size is not specified directly.
   // For example, 'int a[]'.
-  Expr *Size = Importer.Import(T->getSizeExpr());
-  if (!Size && T->getSizeExpr())
-    return {};
 
-  SourceRange Brackets = Importer.Import(T->getBracketsRange());
   return Importer.getToContext().getDependentSizedArrayType(
-      ToElementType, Size, T->getSizeModifier(), T->getIndexTypeCVRQualifiers(),
-      Brackets);
+      ToElementType, ToSizeExpr, T->getSizeModifier(),
+      T->getIndexTypeCVRQualifiers(), ToBracketsRange);
 }
 
-QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitVectorType(const VectorType *T) {
+  ExpectedType ToElementTypeOrErr = import(T->getElementType());
+  if (!ToElementTypeOrErr)
+    return ToElementTypeOrErr.takeError();
 
-  return Importer.getToContext().getVectorType(ToElementType,
+  return Importer.getToContext().getVectorType(*ToElementTypeOrErr,
                                                T->getNumElements(),
                                                T->getVectorKind());
 }
 
-QualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
-  QualType ToElementType = Importer.Import(T->getElementType());
-  if (ToElementType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
+  ExpectedType ToElementTypeOrErr = import(T->getElementType());
+  if (!ToElementTypeOrErr)
+    return ToElementTypeOrErr.takeError();
 
-  return Importer.getToContext().getExtVectorType(ToElementType,
+  return Importer.getToContext().getExtVectorType(*ToElementTypeOrErr,
                                                   T->getNumElements());
 }
 
-QualType
+ExpectedType
 ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
   // FIXME: What happens if we're importing a function without a prototype
   // into C++? Should we make it variadic?
-  QualType ToResultType = Importer.Import(T->getReturnType());
-  if (ToResultType.isNull())
-    return {};
+  ExpectedType ToReturnTypeOrErr = import(T->getReturnType());
+  if (!ToReturnTypeOrErr)
+    return ToReturnTypeOrErr.takeError();
 
-  return Importer.getToContext().getFunctionNoProtoType(ToResultType,
+  return Importer.getToContext().getFunctionNoProtoType(*ToReturnTypeOrErr,
                                                         T->getExtInfo());
 }
 
-QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
-  QualType ToResultType = Importer.Import(T->getReturnType());
-  if (ToResultType.isNull())
-    return {};
+ExpectedType
+ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
+  ExpectedType ToReturnTypeOrErr = import(T->getReturnType());
+  if (!ToReturnTypeOrErr)
+    return ToReturnTypeOrErr.takeError();
 
   // Import argument types
   SmallVector<QualType, 4> ArgTypes;
   for (const auto &A : T->param_types()) {
-    QualType ArgType = Importer.Import(A);
-    if (ArgType.isNull())
-      return {};
-    ArgTypes.push_back(ArgType);
+    ExpectedType TyOrErr = import(A);
+    if (!TyOrErr)
+      return TyOrErr.takeError();
+    ArgTypes.push_back(*TyOrErr);
   }
 
   // Import exception types
   SmallVector<QualType, 4> ExceptionTypes;
   for (const auto &E : T->exceptions()) {
-    QualType ExceptionType = Importer.Import(E);
-    if (ExceptionType.isNull())
-      return {};
-    ExceptionTypes.push_back(ExceptionType);
+    ExpectedType TyOrErr = import(E);
+    if (!TyOrErr)
+      return TyOrErr.takeError();
+    ExceptionTypes.push_back(*TyOrErr);
   }
 
   FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo();
   FunctionProtoType::ExtProtoInfo ToEPI;
 
+  auto Imp = importSeq(
+      FromEPI.ExceptionSpec.NoexceptExpr,
+      FromEPI.ExceptionSpec.SourceDecl,
+      FromEPI.ExceptionSpec.SourceTemplate);
+  if (!Imp)
+    return Imp.takeError();
+
   ToEPI.ExtInfo = FromEPI.ExtInfo;
   ToEPI.Variadic = FromEPI.Variadic;
   ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn;
@@ -835,112 +1224,108 @@
   ToEPI.RefQualifier = FromEPI.RefQualifier;
   ToEPI.ExceptionSpec.Type = FromEPI.ExceptionSpec.Type;
   ToEPI.ExceptionSpec.Exceptions = ExceptionTypes;
-  ToEPI.ExceptionSpec.NoexceptExpr =
-      Importer.Import(FromEPI.ExceptionSpec.NoexceptExpr);
-  ToEPI.ExceptionSpec.SourceDecl = cast_or_null<FunctionDecl>(
-      Importer.Import(FromEPI.ExceptionSpec.SourceDecl));
-  ToEPI.ExceptionSpec.SourceTemplate = cast_or_null<FunctionDecl>(
-      Importer.Import(FromEPI.ExceptionSpec.SourceTemplate));
+  std::tie(
+      ToEPI.ExceptionSpec.NoexceptExpr,
+      ToEPI.ExceptionSpec.SourceDecl,
+      ToEPI.ExceptionSpec.SourceTemplate) = *Imp;
 
-  return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
+  return Importer.getToContext().getFunctionType(
+      *ToReturnTypeOrErr, ArgTypes, ToEPI);
 }
 
-QualType ASTNodeImporter::VisitUnresolvedUsingType(
+ExpectedType ASTNodeImporter::VisitUnresolvedUsingType(
     const UnresolvedUsingType *T) {
-  const auto *ToD =
-      cast_or_null<UnresolvedUsingTypenameDecl>(Importer.Import(T->getDecl()));
-  if (!ToD)
-    return {};
+  UnresolvedUsingTypenameDecl *ToD;
+  Decl *ToPrevD;
+  if (auto Imp = importSeq(T->getDecl(), T->getDecl()->getPreviousDecl()))
+    std::tie(ToD, ToPrevD) = *Imp;
+  else
+    return Imp.takeError();
 
-  auto *ToPrevD =
-      cast_or_null<UnresolvedUsingTypenameDecl>(
-        Importer.Import(T->getDecl()->getPreviousDecl()));
-  if (!ToPrevD && T->getDecl()->getPreviousDecl())
-    return {};
-
-  return Importer.getToContext().getTypeDeclType(ToD, ToPrevD);
+  return Importer.getToContext().getTypeDeclType(
+      ToD, cast_or_null<TypeDecl>(ToPrevD));
 }
 
-QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
-  QualType ToInnerType = Importer.Import(T->getInnerType());
-  if (ToInnerType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitParenType(const ParenType *T) {
+  ExpectedType ToInnerTypeOrErr = import(T->getInnerType());
+  if (!ToInnerTypeOrErr)
+    return ToInnerTypeOrErr.takeError();
 
-  return Importer.getToContext().getParenType(ToInnerType);
+  return Importer.getToContext().getParenType(*ToInnerTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
-  auto *ToDecl =
-      dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
-  if (!ToDecl)
-    return {};
+ExpectedType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
+  Expected<TypedefNameDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
 
-  return Importer.getToContext().getTypeDeclType(ToDecl);
+  return Importer.getToContext().getTypeDeclType(*ToDeclOrErr);
 }
 
-QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
-  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
-  if (!ToExpr)
-    return {};
+ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
+  ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
+  if (!ToExprOrErr)
+    return ToExprOrErr.takeError();
 
-  return Importer.getToContext().getTypeOfExprType(ToExpr);
+  return Importer.getToContext().getTypeOfExprType(*ToExprOrErr);
 }
 
-QualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
-  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
-  if (ToUnderlyingType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
+  ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
+  if (!ToUnderlyingTypeOrErr)
+    return ToUnderlyingTypeOrErr.takeError();
 
-  return Importer.getToContext().getTypeOfType(ToUnderlyingType);
+  return Importer.getToContext().getTypeOfType(*ToUnderlyingTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
+ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
   // FIXME: Make sure that the "to" context supports C++0x!
-  Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
-  if (!ToExpr)
-    return {};
+  ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
+  if (!ToExprOrErr)
+    return ToExprOrErr.takeError();
 
-  QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
-  if (UnderlyingType.isNull())
-    return {};
+  ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
+  if (!ToUnderlyingTypeOrErr)
+    return ToUnderlyingTypeOrErr.takeError();
 
-  return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
+  return Importer.getToContext().getDecltypeType(
+      *ToExprOrErr, *ToUnderlyingTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
-  QualType ToBaseType = Importer.Import(T->getBaseType());
-  QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
-  if (ToBaseType.isNull() || ToUnderlyingType.isNull())
-    return {};
+ExpectedType
+ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
+  ExpectedType ToBaseTypeOrErr = import(T->getBaseType());
+  if (!ToBaseTypeOrErr)
+    return ToBaseTypeOrErr.takeError();
 
-  return Importer.getToContext().getUnaryTransformType(ToBaseType,
-                                                       ToUnderlyingType,
-                                                       T->getUTTKind());
+  ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
+  if (!ToUnderlyingTypeOrErr)
+    return ToUnderlyingTypeOrErr.takeError();
+
+  return Importer.getToContext().getUnaryTransformType(
+      *ToBaseTypeOrErr, *ToUnderlyingTypeOrErr, T->getUTTKind());
 }
 
-QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
+ExpectedType ASTNodeImporter::VisitAutoType(const AutoType *T) {
   // FIXME: Make sure that the "to" context supports C++11!
-  QualType FromDeduced = T->getDeducedType();
-  QualType ToDeduced;
-  if (!FromDeduced.isNull()) {
-    ToDeduced = Importer.Import(FromDeduced);
-    if (ToDeduced.isNull())
-      return {};
-  }
+  ExpectedType ToDeducedTypeOrErr = import(T->getDeducedType());
+  if (!ToDeducedTypeOrErr)
+    return ToDeducedTypeOrErr.takeError();
 
-  return Importer.getToContext().getAutoType(ToDeduced, T->getKeyword(),
+  return Importer.getToContext().getAutoType(*ToDeducedTypeOrErr,
+                                             T->getKeyword(),
                                              /*IsDependent*/false);
 }
 
-QualType ASTNodeImporter::VisitInjectedClassNameType(
+ExpectedType ASTNodeImporter::VisitInjectedClassNameType(
     const InjectedClassNameType *T) {
-  auto *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl()));
-  if (!D)
-    return {};
+  Expected<CXXRecordDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
 
-  QualType InjType = Importer.Import(T->getInjectedSpecializationType());
-  if (InjType.isNull())
-    return {};
+  ExpectedType ToInjTypeOrErr = import(T->getInjectedSpecializationType());
+  if (!ToInjTypeOrErr)
+    return ToInjTypeOrErr.takeError();
 
   // FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading
   // See comments in InjectedClassNameType definition for details
@@ -951,220 +1336,208 @@
   };
 
   return QualType(new (Importer.getToContext(), TypeAlignment)
-                  InjectedClassNameType(D, InjType), 0);
+                  InjectedClassNameType(*ToDeclOrErr, *ToInjTypeOrErr), 0);
 }
 
-QualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
-  auto *ToDecl = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
-  if (!ToDecl)
-    return {};
+ExpectedType ASTNodeImporter::VisitRecordType(const RecordType *T) {
+  Expected<RecordDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
 
-  return Importer.getToContext().getTagDeclType(ToDecl);
+  return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
 }
 
-QualType ASTNodeImporter::VisitEnumType(const EnumType *T) {
-  auto *ToDecl = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
-  if (!ToDecl)
-    return {};
+ExpectedType ASTNodeImporter::VisitEnumType(const EnumType *T) {
+  Expected<EnumDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
 
-  return Importer.getToContext().getTagDeclType(ToDecl);
+  return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
 }
 
-QualType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
-  QualType FromModifiedType = T->getModifiedType();
-  QualType FromEquivalentType = T->getEquivalentType();
-  QualType ToModifiedType;
-  QualType ToEquivalentType;
-
-  if (!FromModifiedType.isNull()) {
-    ToModifiedType = Importer.Import(FromModifiedType);
-    if (ToModifiedType.isNull())
-      return {};
-  }
-  if (!FromEquivalentType.isNull()) {
-    ToEquivalentType = Importer.Import(FromEquivalentType);
-    if (ToEquivalentType.isNull())
-      return {};
-  }
+ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
+  ExpectedType ToModifiedTypeOrErr = import(T->getModifiedType());
+  if (!ToModifiedTypeOrErr)
+    return ToModifiedTypeOrErr.takeError();
+  ExpectedType ToEquivalentTypeOrErr = import(T->getEquivalentType());
+  if (!ToEquivalentTypeOrErr)
+    return ToEquivalentTypeOrErr.takeError();
 
   return Importer.getToContext().getAttributedType(T->getAttrKind(),
-    ToModifiedType, ToEquivalentType);
+      *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr);
 }
 
-QualType ASTNodeImporter::VisitTemplateTypeParmType(
+ExpectedType ASTNodeImporter::VisitTemplateTypeParmType(
     const TemplateTypeParmType *T) {
-  auto *ParmDecl =
-      cast_or_null<TemplateTypeParmDecl>(Importer.Import(T->getDecl()));
-  if (!ParmDecl && T->getDecl())
-    return {};
+  Expected<TemplateTypeParmDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
 
   return Importer.getToContext().getTemplateTypeParmType(
-        T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl);
+      T->getDepth(), T->getIndex(), T->isParameterPack(), *ToDeclOrErr);
 }
 
-QualType ASTNodeImporter::VisitSubstTemplateTypeParmType(
+ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType(
     const SubstTemplateTypeParmType *T) {
-  const auto *Replaced =
-      cast_or_null<TemplateTypeParmType>(Importer.Import(
-        QualType(T->getReplacedParameter(), 0)).getTypePtr());
-  if (!Replaced)
-    return {};
+  ExpectedType ReplacedOrErr = import(QualType(T->getReplacedParameter(), 0));
+  if (!ReplacedOrErr)
+    return ReplacedOrErr.takeError();
+  const TemplateTypeParmType *Replaced =
+      cast<TemplateTypeParmType>((*ReplacedOrErr).getTypePtr());
 
-  QualType Replacement = Importer.Import(T->getReplacementType());
-  if (Replacement.isNull())
-    return {};
-  Replacement = Replacement.getCanonicalType();
+  ExpectedType ToReplacementTypeOrErr = import(T->getReplacementType());
+  if (!ToReplacementTypeOrErr)
+    return ToReplacementTypeOrErr.takeError();
 
   return Importer.getToContext().getSubstTemplateTypeParmType(
-        Replaced, Replacement);
+        Replaced, (*ToReplacementTypeOrErr).getCanonicalType());
 }
 
-QualType ASTNodeImporter::VisitTemplateSpecializationType(
+ExpectedType ASTNodeImporter::VisitTemplateSpecializationType(
                                        const TemplateSpecializationType *T) {
-  TemplateName ToTemplate = Importer.Import(T->getTemplateName());
-  if (ToTemplate.isNull())
-    return {};
+  auto ToTemplateOrErr = import(T->getTemplateName());
+  if (!ToTemplateOrErr)
+    return ToTemplateOrErr.takeError();
 
   SmallVector<TemplateArgument, 2> ToTemplateArgs;
-  if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs))
-    return {};
+  if (Error Err = ImportTemplateArguments(
+      T->getArgs(), T->getNumArgs(), ToTemplateArgs))
+    return std::move(Err);
 
   QualType ToCanonType;
   if (!QualType(T, 0).isCanonical()) {
     QualType FromCanonType
       = Importer.getFromContext().getCanonicalType(QualType(T, 0));
-    ToCanonType =Importer.Import(FromCanonType);
-    if (ToCanonType.isNull())
-      return {};
+    if (ExpectedType TyOrErr = import(FromCanonType))
+      ToCanonType = *TyOrErr;
+    else
+      return TyOrErr.takeError();
   }
-  return Importer.getToContext().getTemplateSpecializationType(ToTemplate,
+  return Importer.getToContext().getTemplateSpecializationType(*ToTemplateOrErr,
                                                                ToTemplateArgs,
                                                                ToCanonType);
 }
 
-QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
-  NestedNameSpecifier *ToQualifier = nullptr;
+ExpectedType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
   // Note: the qualifier in an ElaboratedType is optional.
-  if (T->getQualifier()) {
-    ToQualifier = Importer.Import(T->getQualifier());
-    if (!ToQualifier)
-      return {};
-  }
+  auto ToQualifierOrErr = import(T->getQualifier());
+  if (!ToQualifierOrErr)
+    return ToQualifierOrErr.takeError();
 
-  QualType ToNamedType = Importer.Import(T->getNamedType());
-  if (ToNamedType.isNull())
-    return {};
+  ExpectedType ToNamedTypeOrErr = import(T->getNamedType());
+  if (!ToNamedTypeOrErr)
+    return ToNamedTypeOrErr.takeError();
 
-  TagDecl *OwnedTagDecl =
-      cast_or_null<TagDecl>(Importer.Import(T->getOwnedTagDecl()));
-  if (!OwnedTagDecl && T->getOwnedTagDecl())
-    return {};
+  Expected<TagDecl *> ToOwnedTagDeclOrErr = import(T->getOwnedTagDecl());
+  if (!ToOwnedTagDeclOrErr)
+    return ToOwnedTagDeclOrErr.takeError();
 
   return Importer.getToContext().getElaboratedType(T->getKeyword(),
-                                                   ToQualifier, ToNamedType,
-                                                   OwnedTagDecl);
+                                                   *ToQualifierOrErr,
+                                                   *ToNamedTypeOrErr,
+                                                   *ToOwnedTagDeclOrErr);
 }
 
-QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
-  QualType Pattern = Importer.Import(T->getPattern());
-  if (Pattern.isNull())
-    return {};
+ExpectedType
+ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
+  ExpectedType ToPatternOrErr = import(T->getPattern());
+  if (!ToPatternOrErr)
+    return ToPatternOrErr.takeError();
 
-  return Importer.getToContext().getPackExpansionType(Pattern,
+  return Importer.getToContext().getPackExpansionType(*ToPatternOrErr,
                                                       T->getNumExpansions());
 }
 
-QualType ASTNodeImporter::VisitDependentTemplateSpecializationType(
+ExpectedType ASTNodeImporter::VisitDependentTemplateSpecializationType(
     const DependentTemplateSpecializationType *T) {
-  NestedNameSpecifier *Qualifier = Importer.Import(T->getQualifier());
-  if (!Qualifier && T->getQualifier())
-    return {};
+  auto ToQualifierOrErr = import(T->getQualifier());
+  if (!ToQualifierOrErr)
+    return ToQualifierOrErr.takeError();
 
-  IdentifierInfo *Name = Importer.Import(T->getIdentifier());
-  if (!Name && T->getIdentifier())
-    return {};
+  IdentifierInfo *ToName = Importer.Import(T->getIdentifier());
 
   SmallVector<TemplateArgument, 2> ToPack;
   ToPack.reserve(T->getNumArgs());
-  if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToPack))
-    return {};
+  if (Error Err = ImportTemplateArguments(
+      T->getArgs(), T->getNumArgs(), ToPack))
+    return std::move(Err);
 
   return Importer.getToContext().getDependentTemplateSpecializationType(
-        T->getKeyword(), Qualifier, Name, ToPack);
+      T->getKeyword(), *ToQualifierOrErr, ToName, ToPack);
 }
 
-QualType ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) {
-  NestedNameSpecifier *NNS = Importer.Import(T->getQualifier());
-  if (!NNS && T->getQualifier())
-    return QualType();
+ExpectedType
+ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) {
+  auto ToQualifierOrErr = import(T->getQualifier());
+  if (!ToQualifierOrErr)
+    return ToQualifierOrErr.takeError();
 
   IdentifierInfo *Name = Importer.Import(T->getIdentifier());
-  if (!Name && T->getIdentifier())
-    return QualType();
 
-  QualType Canon = (T == T->getCanonicalTypeInternal().getTypePtr())
-                       ? QualType()
-                       : Importer.Import(T->getCanonicalTypeInternal());
-  if (!Canon.isNull())
-    Canon = Canon.getCanonicalType();
+  QualType Canon;
+  if (T != T->getCanonicalTypeInternal().getTypePtr()) {
+    if (ExpectedType TyOrErr = import(T->getCanonicalTypeInternal()))
+      Canon = (*TyOrErr).getCanonicalType();
+    else
+      return TyOrErr.takeError();
+  }
 
-  return Importer.getToContext().getDependentNameType(T->getKeyword(), NNS,
+  return Importer.getToContext().getDependentNameType(T->getKeyword(),
+                                                      *ToQualifierOrErr,
                                                       Name, Canon);
 }
 
-QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
-  auto *Class =
-      dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
-  if (!Class)
-    return {};
+ExpectedType
+ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
+  Expected<ObjCInterfaceDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
 
-  return Importer.getToContext().getObjCInterfaceType(Class);
+  return Importer.getToContext().getObjCInterfaceType(*ToDeclOrErr);
 }
 
-QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
-  QualType ToBaseType = Importer.Import(T->getBaseType());
-  if (ToBaseType.isNull())
-    return {};
+ExpectedType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
+  ExpectedType ToBaseTypeOrErr = import(T->getBaseType());
+  if (!ToBaseTypeOrErr)
+    return ToBaseTypeOrErr.takeError();
 
   SmallVector<QualType, 4> TypeArgs;
   for (auto TypeArg : T->getTypeArgsAsWritten()) {
-    QualType ImportedTypeArg = Importer.Import(TypeArg);
-    if (ImportedTypeArg.isNull())
-      return {};
-
-    TypeArgs.push_back(ImportedTypeArg);
+    if (ExpectedType TyOrErr = import(TypeArg))
+      TypeArgs.push_back(*TyOrErr);
+    else
+      return TyOrErr.takeError();
   }
 
   SmallVector<ObjCProtocolDecl *, 4> Protocols;
   for (auto *P : T->quals()) {
-    auto *Protocol = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
-    if (!Protocol)
-      return {};
-    Protocols.push_back(Protocol);
+    if (Expected<ObjCProtocolDecl *> ProtocolOrErr = import(P))
+      Protocols.push_back(*ProtocolOrErr);
+    else
+      return ProtocolOrErr.takeError();
+
   }
 
-  return Importer.getToContext().getObjCObjectType(ToBaseType, TypeArgs,
+  return Importer.getToContext().getObjCObjectType(*ToBaseTypeOrErr, TypeArgs,
                                                    Protocols,
                                                    T->isKindOfTypeAsWritten());
 }
 
-QualType
+ExpectedType
 ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
-  QualType ToPointeeType = Importer.Import(T->getPointeeType());
-  if (ToPointeeType.isNull())
-    return {};
+  ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+  if (!ToPointeeTypeOrErr)
+    return ToPointeeTypeOrErr.takeError();
 
-  return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
+  return Importer.getToContext().getObjCObjectPointerType(*ToPointeeTypeOrErr);
 }
 
 //----------------------------------------------------------------------------
 // Import Declarations
 //----------------------------------------------------------------------------
-bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
-                                      DeclContext *&LexicalDC,
-                                      DeclarationName &Name,
-                                      NamedDecl *&ToD,
-                                      SourceLocation &Loc) {
+Error ASTNodeImporter::ImportDeclParts(
+    NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC,
+    DeclarationName &Name, NamedDecl *&ToD, SourceLocation &Loc) {
   // Check if RecordDecl is in FunctionDecl parameters to avoid infinite loop.
   // example: int struct_in_proto(struct data_t{int a;int b;} *d);
   DeclContext *OrigDC = D->getDeclContext();
@@ -1184,66 +1557,63 @@
       if (RT && RT->getDecl() == D) {
         Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
             << D->getDeclKindName();
-        return true;
+        return make_error<ImportError>(ImportError::UnsupportedConstruct);
       }
     }
   }
 
   // Import the context of this declaration.
-  DC = Importer.ImportContext(OrigDC);
-  if (!DC)
-    return true;
-
-  LexicalDC = DC;
-  if (D->getDeclContext() != D->getLexicalDeclContext()) {
-    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
-    if (!LexicalDC)
-      return true;
-  }
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return Err;
 
   // Import the name of this declaration.
-  Name = Importer.Import(D->getDeclName());
-  if (D->getDeclName() && !Name)
-    return true;
+  if (Error Err = importInto(Name, D->getDeclName()))
+    return Err;
 
   // Import the location of this declaration.
-  Loc = Importer.Import(D->getLocation());
+  if (Error Err = importInto(Loc, D->getLocation()))
+    return Err;
+
   ToD = cast_or_null<NamedDecl>(Importer.GetAlreadyImportedOrNull(D));
-  return false;
+
+  return Error::success();
 }
 
-void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
+Error ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
   if (!FromD)
-    return;
+    return Error::success();
 
-  if (!ToD) {
-    ToD = Importer.Import(FromD);
-    if (!ToD)
-      return;
-  }
+  if (!ToD)
+    if (Error Err = importInto(ToD, FromD))
+      return Err;
 
-  if (auto *FromRecord = dyn_cast<RecordDecl>(FromD)) {
-    if (auto *ToRecord = cast_or_null<RecordDecl>(ToD)) {
-      if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) {
-        ImportDefinition(FromRecord, ToRecord);
+  if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
+    if (RecordDecl *ToRecord = cast<RecordDecl>(ToD)) {
+      if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() &&
+          !ToRecord->getDefinition()) {
+        if (Error Err = ImportDefinition(FromRecord, ToRecord))
+          return Err;
       }
     }
-    return;
+    return Error::success();
   }
 
-  if (auto *FromEnum = dyn_cast<EnumDecl>(FromD)) {
-    if (auto *ToEnum = cast_or_null<EnumDecl>(ToD)) {
+  if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
+    if (EnumDecl *ToEnum = cast<EnumDecl>(ToD)) {
       if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
-        ImportDefinition(FromEnum, ToEnum);
+        if (Error Err = ImportDefinition(FromEnum, ToEnum))
+          return Err;
       }
     }
-    return;
+    return Error::success();
   }
+
+  return Error::success();
 }
 
-void
-ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
-                                          DeclarationNameInfo& To) {
+Error
+ASTNodeImporter::ImportDeclarationNameLoc(
+    const DeclarationNameInfo &From, DeclarationNameInfo& To) {
   // NOTE: To.Name and To.Loc are already imported.
   // We only have to import To.LocInfo.
   switch (To.getName().getNameKind()) {
@@ -1253,72 +1623,116 @@
   case DeclarationName::ObjCMultiArgSelector:
   case DeclarationName::CXXUsingDirective:
   case DeclarationName::CXXDeductionGuideName:
-    return;
+    return Error::success();
 
   case DeclarationName::CXXOperatorName: {
-    SourceRange Range = From.getCXXOperatorNameRange();
-    To.setCXXOperatorNameRange(Importer.Import(Range));
-    return;
+    if (auto ToRangeOrErr = import(From.getCXXOperatorNameRange()))
+      To.setCXXOperatorNameRange(*ToRangeOrErr);
+    else
+      return ToRangeOrErr.takeError();
+    return Error::success();
   }
   case DeclarationName::CXXLiteralOperatorName: {
-    SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
-    To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
-    return;
+    if (ExpectedSLoc LocOrErr = import(From.getCXXLiteralOperatorNameLoc()))
+      To.setCXXLiteralOperatorNameLoc(*LocOrErr);
+    else
+      return LocOrErr.takeError();
+    return Error::success();
   }
   case DeclarationName::CXXConstructorName:
   case DeclarationName::CXXDestructorName:
   case DeclarationName::CXXConversionFunctionName: {
-    TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
-    To.setNamedTypeInfo(Importer.Import(FromTInfo));
-    return;
+    if (auto ToTInfoOrErr = import(From.getNamedTypeInfo()))
+      To.setNamedTypeInfo(*ToTInfoOrErr);
+    else
+      return ToTInfoOrErr.takeError();
+    return Error::success();
   }
   }
   llvm_unreachable("Unknown name kind.");
 }
 
-void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
+Error
+ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
   if (Importer.isMinimalImport() && !ForceImport) {
-    Importer.ImportContext(FromDC);
-    return;
+    auto ToDCOrErr = Importer.ImportContext(FromDC);
+    return ToDCOrErr.takeError();
+  }
+  llvm::SmallVector<Decl *, 8> ImportedDecls;
+  for (auto *From : FromDC->decls()) {
+    ExpectedDecl ImportedOrErr = import(From);
+    if (!ImportedOrErr)
+      // Ignore the error, continue with next Decl.
+      // FIXME: Handle this case somehow better.
+      consumeError(ImportedOrErr.takeError());
   }
 
-  for (auto *From : FromDC->decls())
-    Importer.Import(From);
+  return Error::success();
 }
 
-void ASTNodeImporter::ImportImplicitMethods(
+Error ASTNodeImporter::ImportDeclContext(
+    Decl *FromD, DeclContext *&ToDC, DeclContext *&ToLexicalDC) {
+  auto ToDCOrErr = Importer.ImportContext(FromD->getDeclContext());
+  if (!ToDCOrErr)
+    return ToDCOrErr.takeError();
+  ToDC = *ToDCOrErr;
+
+  if (FromD->getDeclContext() != FromD->getLexicalDeclContext()) {
+    auto ToLexicalDCOrErr = Importer.ImportContext(
+        FromD->getLexicalDeclContext());
+    if (!ToLexicalDCOrErr)
+      return ToLexicalDCOrErr.takeError();
+    ToLexicalDC = *ToLexicalDCOrErr;
+  } else
+    ToLexicalDC = ToDC;
+
+  return Error::success();
+}
+
+Error ASTNodeImporter::ImportImplicitMethods(
     const CXXRecordDecl *From, CXXRecordDecl *To) {
   assert(From->isCompleteDefinition() && To->getDefinition() == To &&
       "Import implicit methods to or from non-definition");
 
   for (CXXMethodDecl *FromM : From->methods())
-    if (FromM->isImplicit())
-      Importer.Import(FromM);
+    if (FromM->isImplicit()) {
+      Expected<CXXMethodDecl *> ToMOrErr = import(FromM);
+      if (!ToMOrErr)
+        return ToMOrErr.takeError();
+    }
+
+  return Error::success();
 }
 
-static void setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
-                               ASTImporter &Importer) {
+static Error setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
+                                       ASTImporter &Importer) {
   if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) {
-    auto *ToTypedef =
-      cast_or_null<TypedefNameDecl>(Importer.Import(FromTypedef));
-    assert (ToTypedef && "Failed to import typedef of an anonymous structure");
-
-    To->setTypedefNameForAnonDecl(ToTypedef);
+    Decl *ToTypedef = Importer.Import(FromTypedef);
+    if (!ToTypedef)
+      return make_error<ImportError>();
+    To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToTypedef));
+    // FIXME: This should be the final code.
+    //if (Expected<Decl *> ToTypedefOrErr = Importer.Import(FromTypedef))
+    //  To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
+    //else
+    //  return ToTypedefOrErr.takeError();
   }
+  return Error::success();
 }
 
-bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
-                                       ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportDefinition(
+    RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) {
   if (To->getDefinition() || To->isBeingDefined()) {
     if (Kind == IDK_Everything)
-      ImportDeclContext(From, /*ForceImport=*/true);
+      return ImportDeclContext(From, /*ForceImport=*/true);
 
-    return false;
+    return Error::success();
   }
 
   To->startDefinition();
 
-  setTypedefNameForAnonDecl(From, To, Importer);
+  if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
+    return Err;
 
   // Add base classes.
   if (auto *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
@@ -1394,50 +1808,65 @@
 
     SmallVector<CXXBaseSpecifier *, 4> Bases;
     for (const auto &Base1 : FromCXX->bases()) {
-      QualType T = Importer.Import(Base1.getType());
-      if (T.isNull())
-        return true;
+      ExpectedType TyOrErr = import(Base1.getType());
+      if (!TyOrErr)
+        return TyOrErr.takeError();
 
       SourceLocation EllipsisLoc;
-      if (Base1.isPackExpansion())
-        EllipsisLoc = Importer.Import(Base1.getEllipsisLoc());
+      if (Base1.isPackExpansion()) {
+        if (ExpectedSLoc LocOrErr = import(Base1.getEllipsisLoc()))
+          EllipsisLoc = *LocOrErr;
+        else
+          return LocOrErr.takeError();
+      }
 
       // Ensure that we have a definition for the base.
-      ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl());
+      if (Error Err =
+          ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl()))
+        return Err;
+
+      auto RangeOrErr = import(Base1.getSourceRange());
+      if (!RangeOrErr)
+        return RangeOrErr.takeError();
+
+      auto TSIOrErr = import(Base1.getTypeSourceInfo());
+      if (!TSIOrErr)
+        return TSIOrErr.takeError();
 
       Bases.push_back(
-                    new (Importer.getToContext())
-                      CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()),
-                                       Base1.isVirtual(),
-                                       Base1.isBaseOfClass(),
-                                       Base1.getAccessSpecifierAsWritten(),
-                                   Importer.Import(Base1.getTypeSourceInfo()),
-                                       EllipsisLoc));
+          new (Importer.getToContext()) CXXBaseSpecifier(
+              *RangeOrErr,
+              Base1.isVirtual(),
+              Base1.isBaseOfClass(),
+              Base1.getAccessSpecifierAsWritten(),
+              *TSIOrErr,
+              EllipsisLoc));
     }
     if (!Bases.empty())
       ToCXX->setBases(Bases.data(), Bases.size());
   }
 
   if (shouldForceImportDeclContext(Kind))
-    ImportDeclContext(From, /*ForceImport=*/true);
+    if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+      return Err;
 
   To->completeDefinition();
-  return false;
+  return Error::success();
 }
 
-bool ASTNodeImporter::ImportInitializer(VarDecl *From, VarDecl *To) {
+Error ASTNodeImporter::ImportInitializer(VarDecl *From, VarDecl *To) {
   if (To->getAnyInitializer())
-    return false;
+    return Error::success();
 
   Expr *FromInit = From->getInit();
   if (!FromInit)
-    return false;
+    return Error::success();
 
-  Expr *ToInit = Importer.Import(const_cast<Expr *>(FromInit));
-  if (!ToInit)
-    return true;
+  ExpectedExpr ToInitOrErr = import(FromInit);
+  if (!ToInitOrErr)
+    return ToInitOrErr.takeError();
 
-  To->setInit(ToInit);
+  To->setInit(*ToInitOrErr);
   if (From->isInitKnownICE()) {
     EvaluatedStmt *Eval = To->ensureEvaluatedStmt();
     Eval->CheckedICE = true;
@@ -1445,185 +1874,106 @@
   }
 
   // FIXME: Other bits to merge?
-  return false;
+  return Error::success();
 }
 
-bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
-                                       ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportDefinition(
+    EnumDecl *From, EnumDecl *To, ImportDefinitionKind Kind) {
   if (To->getDefinition() || To->isBeingDefined()) {
     if (Kind == IDK_Everything)
-      ImportDeclContext(From, /*ForceImport=*/true);
-    return false;
+      return ImportDeclContext(From, /*ForceImport=*/true);
+    return Error::success();
   }
 
   To->startDefinition();
 
-  setTypedefNameForAnonDecl(From, To, Importer);
+  if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
+    return Err;
 
-  QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
-  if (T.isNull())
-    return true;
+  ExpectedType ToTypeOrErr =
+      import(Importer.getFromContext().getTypeDeclType(From));
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  QualType ToPromotionType = Importer.Import(From->getPromotionType());
-  if (ToPromotionType.isNull())
-    return true;
+  ExpectedType ToPromotionTypeOrErr = import(From->getPromotionType());
+  if (!ToPromotionTypeOrErr)
+    return ToPromotionTypeOrErr.takeError();
 
   if (shouldForceImportDeclContext(Kind))
-    ImportDeclContext(From, /*ForceImport=*/true);
+    if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+      return Err;
 
   // FIXME: we might need to merge the number of positive or negative bits
   // if the enumerator lists don't match.
-  To->completeDefinition(T, ToPromotionType,
+  To->completeDefinition(*ToTypeOrErr, *ToPromotionTypeOrErr,
                          From->getNumPositiveBits(),
                          From->getNumNegativeBits());
-  return false;
+  return Error::success();
 }
 
-TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
-                                                TemplateParameterList *Params) {
+// FIXME: Remove this, use `import` instead.
+Expected<TemplateParameterList *> ASTNodeImporter::ImportTemplateParameterList(
+    TemplateParameterList *Params) {
   SmallVector<NamedDecl *, 4> ToParams(Params->size());
-  if (ImportContainerChecked(*Params, ToParams))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(*Params, ToParams))
+    return std::move(Err);
 
   Expr *ToRequiresClause;
   if (Expr *const R = Params->getRequiresClause()) {
-    ToRequiresClause = Importer.Import(R);
-    if (!ToRequiresClause)
-      return nullptr;
+    if (Error Err = importInto(ToRequiresClause, R))
+      return std::move(Err);
   } else {
     ToRequiresClause = nullptr;
   }
 
-  return TemplateParameterList::Create(Importer.getToContext(),
-                                       Importer.Import(Params->getTemplateLoc()),
-                                       Importer.Import(Params->getLAngleLoc()),
-                                       ToParams,
-                                       Importer.Import(Params->getRAngleLoc()),
-                                       ToRequiresClause);
+  auto ToTemplateLocOrErr = import(Params->getTemplateLoc());
+  if (!ToTemplateLocOrErr)
+    return ToTemplateLocOrErr.takeError();
+  auto ToLAngleLocOrErr = import(Params->getLAngleLoc());
+  if (!ToLAngleLocOrErr)
+    return ToLAngleLocOrErr.takeError();
+  auto ToRAngleLocOrErr = import(Params->getRAngleLoc());
+  if (!ToRAngleLocOrErr)
+    return ToRAngleLocOrErr.takeError();
+
+  return TemplateParameterList::Create(
+      Importer.getToContext(),
+      *ToTemplateLocOrErr,
+      *ToLAngleLocOrErr,
+      ToParams,
+      *ToRAngleLocOrErr,
+      ToRequiresClause);
 }
 
-TemplateArgument
-ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
-  switch (From.getKind()) {
-  case TemplateArgument::Null:
-    return TemplateArgument();
-
-  case TemplateArgument::Type: {
-    QualType ToType = Importer.Import(From.getAsType());
-    if (ToType.isNull())
-      return {};
-    return TemplateArgument(ToType);
-  }
-
-  case TemplateArgument::Integral: {
-    QualType ToType = Importer.Import(From.getIntegralType());
-    if (ToType.isNull())
-      return {};
-    return TemplateArgument(From, ToType);
-  }
-
-  case TemplateArgument::Declaration: {
-    auto *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl()));
-    QualType ToType = Importer.Import(From.getParamTypeForDecl());
-    if (!To || ToType.isNull())
-      return {};
-    return TemplateArgument(To, ToType);
-  }
-
-  case TemplateArgument::NullPtr: {
-    QualType ToType = Importer.Import(From.getNullPtrType());
-    if (ToType.isNull())
-      return {};
-    return TemplateArgument(ToType, /*isNullPtr*/true);
-  }
-
-  case TemplateArgument::Template: {
-    TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
-    if (ToTemplate.isNull())
-      return {};
-
-    return TemplateArgument(ToTemplate);
-  }
-
-  case TemplateArgument::TemplateExpansion: {
-    TemplateName ToTemplate
-      = Importer.Import(From.getAsTemplateOrTemplatePattern());
-    if (ToTemplate.isNull())
-      return {};
-
-    return TemplateArgument(ToTemplate, From.getNumTemplateExpansions());
-  }
-
-  case TemplateArgument::Expression:
-    if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
-      return TemplateArgument(ToExpr);
-    return TemplateArgument();
-
-  case TemplateArgument::Pack: {
-    SmallVector<TemplateArgument, 2> ToPack;
-    ToPack.reserve(From.pack_size());
-    if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
-      return {};
-
-    return TemplateArgument(
-        llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
-  }
-  }
-
-  llvm_unreachable("Invalid template argument kind");
-}
-
-Optional<TemplateArgumentLoc>
-ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) {
-  TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument());
-  TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
-  TemplateArgumentLocInfo ToInfo;
-  if (Arg.getKind() == TemplateArgument::Expression) {
-    Expr *E = Importer.Import(FromInfo.getAsExpr());
-    ToInfo = TemplateArgumentLocInfo(E);
-    if (!E)
-      return None;
-  } else if (Arg.getKind() == TemplateArgument::Type) {
-    if (TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo()))
-      ToInfo = TemplateArgumentLocInfo(TSI);
-    else
-      return None;
-  } else {
-    ToInfo = TemplateArgumentLocInfo(
-          Importer.Import(FromInfo.getTemplateQualifierLoc()),
-          Importer.Import(FromInfo.getTemplateNameLoc()),
-          Importer.Import(FromInfo.getTemplateEllipsisLoc()));
-  }
-  return TemplateArgumentLoc(Arg, ToInfo);
-}
-
-bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
-                                              unsigned NumFromArgs,
-                              SmallVectorImpl<TemplateArgument> &ToArgs) {
+Error ASTNodeImporter::ImportTemplateArguments(
+    const TemplateArgument *FromArgs, unsigned NumFromArgs,
+    SmallVectorImpl<TemplateArgument> &ToArgs) {
   for (unsigned I = 0; I != NumFromArgs; ++I) {
-    TemplateArgument To = ImportTemplateArgument(FromArgs[I]);
-    if (To.isNull() && !FromArgs[I].isNull())
-      return true;
-
-    ToArgs.push_back(To);
+    if (auto ToOrErr = import(FromArgs[I]))
+      ToArgs.push_back(*ToOrErr);
+    else
+      return ToOrErr.takeError();
   }
 
-  return false;
+  return Error::success();
 }
 
-// We cannot use Optional<> pattern here and below because
-// TemplateArgumentListInfo's operator new is declared as deleted so it cannot
-// be stored in Optional.
+// FIXME: Do not forget to remove this and use only 'import'.
+Expected<TemplateArgument>
+ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
+  return import(From);
+}
+
 template <typename InContainerTy>
-bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+Error ASTNodeImporter::ImportTemplateArgumentListInfo(
     const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
   for (const auto &FromLoc : Container) {
-    if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc))
-      ToTAInfo.addArgument(*ToLoc);
+    if (auto ToLocOrErr = import(FromLoc))
+      ToTAInfo.addArgument(*ToLocOrErr);
     else
-      return true;
+      return ToLocOrErr.takeError();
   }
-  return false;
+  return Error::success();
 }
 
 static StructuralEquivalenceKind
@@ -1720,30 +2070,31 @@
   return Ctx.IsEquivalent(From, To);
 }
 
-Decl *ASTNodeImporter::VisitDecl(Decl *D) {
+ExpectedDecl ASTNodeImporter::VisitDecl(Decl *D) {
   Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
     << D->getDeclKindName();
-  return nullptr;
+  return make_error<ImportError>(ImportError::UnsupportedConstruct);
 }
 
-Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
-  // Import the context of this declaration.
-  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-  if (!DC)
-    return nullptr;
+ExpectedDecl ASTNodeImporter::VisitImportDecl(ImportDecl *D) {
+  Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+      << D->getDeclKindName();
+  return make_error<ImportError>(ImportError::UnsupportedConstruct);
+}
 
-  DeclContext *LexicalDC = DC;
-  if (D->getDeclContext() != D->getLexicalDeclContext()) {
-    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
-    if (!LexicalDC)
-      return nullptr;
-  }
+ExpectedDecl ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
+  // Import the context of this declaration.
+  DeclContext *DC, *LexicalDC;
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return std::move(Err);
 
   // Import the location of this declaration.
-  SourceLocation Loc = Importer.Import(D->getLocation());
+  ExpectedSLoc LocOrErr = import(D->getLocation());
+  if (!LocOrErr)
+    return LocOrErr.takeError();
 
   EmptyDecl *ToD;
-  if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc))
+  if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, *LocOrErr))
     return ToD;
 
   ToD->setLexicalDeclContext(LexicalDC);
@@ -1751,7 +2102,7 @@
   return ToD;
 }
 
-Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
   TranslationUnitDecl *ToD =
     Importer.getToContext().getTranslationUnitDecl();
 
@@ -1760,18 +2111,23 @@
   return ToD;
 }
 
-Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
-  SourceLocation Loc = Importer.Import(D->getLocation());
-  SourceLocation ColonLoc = Importer.Import(D->getColonLoc());
+ExpectedDecl ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
+  ExpectedSLoc LocOrErr = import(D->getLocation());
+  if (!LocOrErr)
+    return LocOrErr.takeError();
+  auto ColonLocOrErr = import(D->getColonLoc());
+  if (!ColonLocOrErr)
+    return ColonLocOrErr.takeError();
 
   // Import the context of this declaration.
-  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-  if (!DC)
-    return nullptr;
+  auto DCOrErr = Importer.ImportContext(D->getDeclContext());
+  if (!DCOrErr)
+    return DCOrErr.takeError();
+  DeclContext *DC = *DCOrErr;
 
   AccessSpecDecl *ToD;
   if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), D->getAccess(),
-                              DC, Loc, ColonLoc))
+                              DC, *LocOrErr, *ColonLocOrErr))
     return ToD;
 
   // Lexical DeclContext and Semantic DeclContext
@@ -1782,29 +2138,26 @@
   return ToD;
 }
 
-Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
-  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-  if (!DC)
-    return nullptr;
-
+ExpectedDecl ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
+  auto DCOrErr = Importer.ImportContext(D->getDeclContext());
+  if (!DCOrErr)
+    return DCOrErr.takeError();
+  DeclContext *DC = *DCOrErr;
   DeclContext *LexicalDC = DC;
 
-  // Import the location of this declaration.
-  SourceLocation Loc = Importer.Import(D->getLocation());
-
-  Expr *AssertExpr = Importer.Import(D->getAssertExpr());
-  if (!AssertExpr)
-    return nullptr;
-
-  StringLiteral *FromMsg = D->getMessage();
-  auto *ToMsg = cast_or_null<StringLiteral>(Importer.Import(FromMsg));
-  if (!ToMsg && FromMsg)
-    return nullptr;
+  SourceLocation ToLocation, ToRParenLoc;
+  Expr *ToAssertExpr;
+  StringLiteral *ToMessage;
+  if (auto Imp = importSeq(
+      D->getLocation(), D->getAssertExpr(), D->getMessage(), D->getRParenLoc()))
+    std::tie(ToLocation, ToAssertExpr, ToMessage, ToRParenLoc) = *Imp;
+  else
+    return Imp.takeError();
 
   StaticAssertDecl *ToD;
   if (GetImportedOrCreateDecl(
-          ToD, D, Importer.getToContext(), DC, Loc, AssertExpr, ToMsg,
-          Importer.Import(D->getRParenLoc()), D->isFailed()))
+      ToD, D, Importer.getToContext(), DC, ToLocation, ToAssertExpr, ToMessage,
+      ToRParenLoc, D->isFailed()))
     return ToD;
 
   ToD->setLexicalDeclContext(LexicalDC);
@@ -1812,14 +2165,14 @@
   return ToD;
 }
 
-Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
   // Import the major distinguishing characteristics of this namespace.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -1853,15 +2206,21 @@
       Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
+      if (!Name)
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
+  ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+  if (!BeginLocOrErr)
+    return BeginLocOrErr.takeError();
+
   // Create the "to" namespace, if needed.
   NamespaceDecl *ToNamespace = MergeWithNamespace;
   if (!ToNamespace) {
     if (GetImportedOrCreateDecl(
             ToNamespace, D, Importer.getToContext(), DC, D->isInline(),
-            Importer.Import(D->getBeginLoc()), Loc, Name.getAsIdentifierInfo(),
+            *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
             /*PrevDecl=*/nullptr))
       return ToNamespace;
     ToNamespace->setLexicalDeclContext(LexicalDC);
@@ -1878,43 +2237,42 @@
   }
   Importer.MapImported(D, ToNamespace);
 
-  ImportDeclContext(D);
+  if (Error Err = ImportDeclContext(D))
+    return std::move(Err);
 
   return ToNamespace;
 }
 
-Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
   // Import the major distinguishing characteristics of this namespace.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *LookupD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc))
+    return std::move(Err);
   if (LookupD)
     return LookupD;
 
   // NOTE: No conflict resolution is done for namespace aliases now.
 
-  auto *TargetDecl = cast_or_null<NamespaceDecl>(
-      Importer.Import(D->getNamespace()));
-  if (!TargetDecl)
-    return nullptr;
-
-  IdentifierInfo *ToII = Importer.Import(D->getIdentifier());
-  if (!ToII)
-    return nullptr;
-
-  NestedNameSpecifierLoc ToQLoc = Importer.Import(D->getQualifierLoc());
-  if (D->getQualifierLoc() && !ToQLoc)
-    return nullptr;
+  SourceLocation ToNamespaceLoc, ToAliasLoc, ToTargetNameLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  NamespaceDecl *ToNamespace;
+  if (auto Imp = importSeq(
+      D->getNamespaceLoc(), D->getAliasLoc(), D->getQualifierLoc(),
+      D->getTargetNameLoc(), D->getNamespace()))
+    std::tie(
+        ToNamespaceLoc, ToAliasLoc, ToQualifierLoc, ToTargetNameLoc,
+        ToNamespace) = *Imp;
+  else
+    return Imp.takeError();
+  IdentifierInfo *ToIdentifier = Importer.Import(D->getIdentifier());
 
   NamespaceAliasDecl *ToD;
-  if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getNamespaceLoc()),
-                              Importer.Import(D->getAliasLoc()), ToII, ToQLoc,
-                              Importer.Import(D->getTargetNameLoc()),
-                              TargetDecl))
+  if (GetImportedOrCreateDecl(
+      ToD, D, Importer.getToContext(), DC, ToNamespaceLoc, ToAliasLoc,
+      ToIdentifier, ToQualifierLoc, ToTargetNameLoc, ToNamespace))
     return ToD;
 
   ToD->setLexicalDeclContext(LexicalDC);
@@ -1923,14 +2281,15 @@
   return ToD;
 }
 
-Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
+ExpectedDecl
+ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
   // Import the major distinguishing characteristics of this typedef.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -1946,9 +2305,9 @@
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
       if (auto *FoundTypedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
-        if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
-                                            FoundTypedef->getUnderlyingType()))
-          return Importer.MapImported(D, FoundTypedef);
+        if (Importer.IsStructurallyEquivalent(
+                D->getUnderlyingType(), FoundTypedef->getUnderlyingType()))
+            return Importer.MapImported(D, FoundTypedef);
       }
 
       ConflictingDecls.push_back(FoundDecl);
@@ -1959,28 +2318,30 @@
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
       if (!Name)
-        return nullptr;
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
-  // Import the underlying type of this typedef;
-  QualType T = Importer.Import(D->getUnderlyingType());
-  if (T.isNull())
-    return nullptr;
+  QualType ToUnderlyingType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceLocation ToBeginLoc;
+  if (auto Imp = importSeq(
+      D->getUnderlyingType(), D->getTypeSourceInfo(), D->getBeginLoc()))
+    std::tie(ToUnderlyingType, ToTypeSourceInfo, ToBeginLoc) = *Imp;
+  else
+    return Imp.takeError();
 
   // Create the new typedef node.
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-  SourceLocation StartL = Importer.Import(D->getBeginLoc());
-
+  // FIXME: ToUnderlyingType is not used.
   TypedefNameDecl *ToTypedef;
   if (IsAlias) {
     if (GetImportedOrCreateDecl<TypeAliasDecl>(
-            ToTypedef, D, Importer.getToContext(), DC, StartL, Loc,
-            Name.getAsIdentifierInfo(), TInfo))
+        ToTypedef, D, Importer.getToContext(), DC, ToBeginLoc, Loc,
+        Name.getAsIdentifierInfo(), ToTypeSourceInfo))
       return ToTypedef;
   } else if (GetImportedOrCreateDecl<TypedefDecl>(
-                 ToTypedef, D, Importer.getToContext(), DC, StartL, Loc,
-                 Name.getAsIdentifierInfo(), TInfo))
+      ToTypedef, D, Importer.getToContext(), DC, ToBeginLoc, Loc,
+      Name.getAsIdentifierInfo(), ToTypeSourceInfo))
     return ToTypedef;
 
   ToTypedef->setAccess(D->getAccess());
@@ -1994,22 +2355,23 @@
   return ToTypedef;
 }
 
-Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
   return VisitTypedefNameDecl(D, /*IsAlias=*/false);
 }
 
-Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
   return VisitTypedefNameDecl(D, /*IsAlias=*/true);
 }
 
-Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
   // Import the major distinguishing characteristics of this typedef.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *FoundD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc))
+    return std::move(Err);
   if (FoundD)
     return FoundD;
 
@@ -2034,26 +2396,23 @@
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
       if (!Name)
-        return nullptr;
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
-  TemplateParameterList *Params = ImportTemplateParameterList(
-        D->getTemplateParameters());
-  if (!Params)
-    return nullptr;
-
-  auto *TemplDecl = cast_or_null<TypeAliasDecl>(
-        Importer.Import(D->getTemplatedDecl()));
-  if (!TemplDecl)
-    return nullptr;
+  TemplateParameterList *ToTemplateParameters;
+  TypeAliasDecl *ToTemplatedDecl;
+  if (auto Imp = importSeq(D->getTemplateParameters(), D->getTemplatedDecl()))
+    std::tie(ToTemplateParameters, ToTemplatedDecl) = *Imp;
+  else
+    return Imp.takeError();
 
   TypeAliasTemplateDecl *ToAlias;
   if (GetImportedOrCreateDecl(ToAlias, D, Importer.getToContext(), DC, Loc,
-                              Name, Params, TemplDecl))
+                              Name, ToTemplateParameters, ToTemplatedDecl))
     return ToAlias;
 
-  TemplDecl->setDescribedAliasTemplate(ToAlias);
+  ToTemplatedDecl->setDescribedAliasTemplate(ToAlias);
 
   ToAlias->setAccess(D->getAccess());
   ToAlias->setLexicalDeclContext(LexicalDC);
@@ -2061,48 +2420,53 @@
   return ToAlias;
 }
 
-Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
   // Import the major distinguishing characteristics of this label.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
   assert(LexicalDC->isFunctionOrMethod());
 
   LabelDecl *ToLabel;
-  if (D->isGnuLocal()
-          ? GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC,
-                                    Importer.Import(D->getLocation()),
-                                    Name.getAsIdentifierInfo(),
-                                    Importer.Import(D->getBeginLoc()))
-          : GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC,
-                                    Importer.Import(D->getLocation()),
-                                    Name.getAsIdentifierInfo()))
-    return ToLabel;
+  if (D->isGnuLocal()) {
+    ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+    if (!BeginLocOrErr)
+      return BeginLocOrErr.takeError();
+    if (GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC, Loc,
+                                Name.getAsIdentifierInfo(), *BeginLocOrErr))
+      return ToLabel;
 
-  auto *Label = cast_or_null<LabelStmt>(Importer.Import(D->getStmt()));
-  if (!Label)
-    return nullptr;
+  } else {
+    if (GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC, Loc,
+                                Name.getAsIdentifierInfo()))
+      return ToLabel;
 
-  ToLabel->setStmt(Label);
+  }
+
+  Expected<LabelStmt *> ToStmtOrErr = import(D->getStmt());
+  if (!ToStmtOrErr)
+    return ToStmtOrErr.takeError();
+
+  ToLabel->setStmt(*ToStmtOrErr);
   ToLabel->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(ToLabel);
   return ToLabel;
 }
 
-Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
   // Import the major distinguishing characteristics of this enum.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -2110,7 +2474,9 @@
   unsigned IDNS = Decl::IDNS_Tag;
   DeclarationName SearchName = Name;
   if (!SearchName && D->getTypedefNameForAnonDecl()) {
-    SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
+    if (Error Err = importInto(
+        SearchName, D->getTypedefNameForAnonDecl()->getDeclName()))
+      return std::move(Err);
     IDNS = Decl::IDNS_Ordinary;
   } else if (Importer.getToContext().getLangOpts().CPlusPlus)
     IDNS |= Decl::IDNS_Ordinary;
@@ -2124,13 +2490,12 @@
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
 
-      Decl *Found = FoundDecl;
-      if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
+      if (auto *Typedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
         if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
-          Found = Tag->getDecl();
+          FoundDecl = Tag->getDecl();
       }
 
-      if (auto *FoundEnum = dyn_cast<EnumDecl>(Found)) {
+      if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
         if (IsStructuralMatch(D, FoundEnum))
           return Importer.MapImported(D, FoundEnum);
       }
@@ -2142,37 +2507,43 @@
       Name = Importer.HandleNameConflict(Name, DC, IDNS,
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
+      if (!Name)
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
+  SourceLocation ToBeginLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  QualType ToIntegerType;
+  if (auto Imp = importSeq(
+      D->getBeginLoc(), D->getQualifierLoc(), D->getIntegerType()))
+    std::tie(ToBeginLoc, ToQualifierLoc, ToIntegerType) = *Imp;
+  else
+    return Imp.takeError();
+
   // Create the enum declaration.
   EnumDecl *D2;
   if (GetImportedOrCreateDecl(
-          D2, D, Importer.getToContext(), DC, Importer.Import(D->getBeginLoc()),
+          D2, D, Importer.getToContext(), DC, ToBeginLoc,
           Loc, Name.getAsIdentifierInfo(), nullptr, D->isScoped(),
           D->isScopedUsingClassTag(), D->isFixed()))
     return D2;
 
-  // Import the qualifier, if any.
-  D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+  D2->setQualifierInfo(ToQualifierLoc);
+  D2->setIntegerType(ToIntegerType);
   D2->setAccess(D->getAccess());
   D2->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(D2);
 
-  // Import the integer type.
-  QualType ToIntegerType = Importer.Import(D->getIntegerType());
-  if (ToIntegerType.isNull())
-    return nullptr;
-  D2->setIntegerType(ToIntegerType);
-
   // Import the definition
-  if (D->isCompleteDefinition() && ImportDefinition(D, D2))
-    return nullptr;
+  if (D->isCompleteDefinition())
+    if (Error Err = ImportDefinition(D, D2))
+      return std::move(Err);
 
   return D2;
 }
 
-Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
   bool IsFriendTemplate = false;
   if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
     IsFriendTemplate =
@@ -2194,11 +2565,11 @@
       // ClassTemplateSpecializationDecl itself. Thus, we start with an extra
       // condition in order to be able to import the implict Decl.
       !D->isImplicit()) {
-    Decl *ImportedDef = Importer.Import(Definition);
-    if (!ImportedDef)
-      return nullptr;
+    ExpectedDecl ImportedDefOrErr = import(Definition);
+    if (!ImportedDefOrErr)
+      return ImportedDefOrErr.takeError();
 
-    return Importer.MapImported(D, ImportedDef);
+    return Importer.MapImported(D, *ImportedDefOrErr);
   }
 
   // Import the major distinguishing characteristics of this record.
@@ -2206,8 +2577,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -2215,7 +2586,9 @@
   unsigned IDNS = Decl::IDNS_Tag;
   DeclarationName SearchName = Name;
   if (!SearchName && D->getTypedefNameForAnonDecl()) {
-    SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
+    if (Error Err = importInto(
+        SearchName, D->getTypedefNameForAnonDecl()->getDeclName()))
+      return std::move(Err);
     IDNS = Decl::IDNS_Ordinary;
   } else if (Importer.getToContext().getLangOpts().CPlusPlus)
     IDNS |= Decl::IDNS_Ordinary;
@@ -2245,16 +2618,23 @@
       }
 
       if (D->getDescribedTemplate()) {
-        if (auto *Template = dyn_cast<ClassTemplateDecl>(Found))
+        if (auto *Template = dyn_cast<ClassTemplateDecl>(Found)) {
           Found = Template->getTemplatedDecl();
-        else
+        } else {
+          ConflictingDecls.push_back(FoundDecl);
           continue;
+        }
       }
 
       if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) {
         if (!SearchName) {
           if (!IsStructuralMatch(D, FoundRecord, false))
             continue;
+        } else {
+          if (!IsStructuralMatch(D, FoundRecord)) {
+            ConflictingDecls.push_back(FoundDecl);
+            continue;
+          }
         }
 
         PrevDecl = FoundRecord;
@@ -2263,8 +2643,7 @@
           if ((SearchName && !D->isCompleteDefinition() && !IsFriendTemplate)
               || (D->isCompleteDefinition() &&
                   D->isAnonymousStructOrUnion()
-                    == FoundDef->isAnonymousStructOrUnion() &&
-                  IsStructuralMatch(D, FoundDef))) {
+                    == FoundDef->isAnonymousStructOrUnion())) {
             // The record types structurally match, or the "from" translation
             // unit only had a forward declaration anyway; call it the same
             // function.
@@ -2278,10 +2657,13 @@
               if (D->isCompleteDefinition() && !Importer.isMinimalImport())
                 // FoundDef may not have every implicit method that D has
                 // because implicit methods are created only if they are used.
-                ImportImplicitMethods(DCXX, FoundCXX);
+                if (Error Err = ImportImplicitMethods(DCXX, FoundCXX))
+                  return std::move(Err);
             }
             return FoundDef;
           }
+          if (IsFriendTemplate)
+            continue;
         } else if (!D->isCompleteDefinition()) {
           // We have a forward declaration of this type, so adopt that forward
           // declaration rather than building a new one.
@@ -2297,18 +2679,18 @@
 
           if (FoundRecord->isCompleteDefinition() &&
               D->isCompleteDefinition() &&
-              !IsStructuralMatch(D, FoundRecord))
+              !IsStructuralMatch(D, FoundRecord)) {
+            ConflictingDecls.push_back(FoundDecl);
             continue;
-
-          if (IsFriendTemplate)
-            continue;
+          }
 
           AdoptDecl = FoundRecord;
           continue;
-        } else if (!SearchName) {
-          continue;
         }
-      }
+
+        continue;
+      } else if (isa<ValueDecl>(Found))
+        continue;
 
       ConflictingDecls.push_back(FoundDecl);
     }
@@ -2317,33 +2699,40 @@
       Name = Importer.HandleNameConflict(Name, DC, IDNS,
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
+      if (!Name)
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
+  ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+  if (!BeginLocOrErr)
+    return BeginLocOrErr.takeError();
+
   // Create the record declaration.
   RecordDecl *D2 = AdoptDecl;
-  SourceLocation StartLoc = Importer.Import(D->getBeginLoc());
   if (!D2) {
     CXXRecordDecl *D2CXX = nullptr;
     if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
       if (DCXX->isLambda()) {
-        TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo());
+        auto TInfoOrErr = import(DCXX->getLambdaTypeInfo());
+        if (!TInfoOrErr)
+          return TInfoOrErr.takeError();
         if (GetImportedOrCreateSpecialDecl(
                 D2CXX, CXXRecordDecl::CreateLambda, D, Importer.getToContext(),
-                DC, TInfo, Loc, DCXX->isDependentLambda(),
+                DC, *TInfoOrErr, Loc, DCXX->isDependentLambda(),
                 DCXX->isGenericLambda(), DCXX->getLambdaCaptureDefault()))
           return D2CXX;
-        Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl());
-        if (DCXX->getLambdaContextDecl() && !CDecl)
-          return nullptr;
-        D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), CDecl);
+        ExpectedDecl CDeclOrErr = import(DCXX->getLambdaContextDecl());
+        if (!CDeclOrErr)
+          return CDeclOrErr.takeError();
+        D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr);
       } else if (DCXX->isInjectedClassName()) {
         // We have to be careful to do a similar dance to the one in
         // Sema::ActOnStartCXXMemberDeclarations
         CXXRecordDecl *const PrevDecl = nullptr;
         const bool DelayTypeCreation = true;
         if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
-                                    D->getTagKind(), DC, StartLoc, Loc,
+                                    D->getTagKind(), DC, *BeginLocOrErr, Loc,
                                     Name.getAsIdentifierInfo(), PrevDecl,
                                     DelayTypeCreation))
           return D2CXX;
@@ -2351,7 +2740,7 @@
             D2CXX, dyn_cast<CXXRecordDecl>(DC));
       } else {
         if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
-                                    D->getTagKind(), DC, StartLoc, Loc,
+                                    D->getTagKind(), DC, *BeginLocOrErr, Loc,
                                     Name.getAsIdentifierInfo(),
                                     cast_or_null<CXXRecordDecl>(PrevDecl)))
           return D2CXX;
@@ -2365,10 +2754,9 @@
 
       if (ClassTemplateDecl *FromDescribed =
           DCXX->getDescribedClassTemplate()) {
-        auto *ToDescribed = cast_or_null<ClassTemplateDecl>(
-            Importer.Import(FromDescribed));
-        if (!ToDescribed)
-          return nullptr;
+        ClassTemplateDecl *ToDescribed;
+        if (Error Err = importInto(ToDescribed, FromDescribed))
+          return std::move(Err);
         D2CXX->setDescribedClassTemplate(ToDescribed);
         if (!DCXX->isInjectedClassName() && !IsFriendTemplate) {
           // In a record describing a template the type should be an
@@ -2398,51 +2786,58 @@
         TemplateSpecializationKind SK =
             MemberInfo->getTemplateSpecializationKind();
         CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass();
-        auto *ToInst =
-            cast_or_null<CXXRecordDecl>(Importer.Import(FromInst));
-        if (FromInst && !ToInst)
-          return nullptr;
-        D2CXX->setInstantiationOfMemberClass(ToInst, SK);
-        D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
-              Importer.Import(MemberInfo->getPointOfInstantiation()));
+
+        if (Expected<CXXRecordDecl *> ToInstOrErr = import(FromInst))
+          D2CXX->setInstantiationOfMemberClass(*ToInstOrErr, SK);
+        else
+          return ToInstOrErr.takeError();
+
+        if (ExpectedSLoc POIOrErr =
+            import(MemberInfo->getPointOfInstantiation()))
+          D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
+            *POIOrErr);
+        else
+          return POIOrErr.takeError();
       }
+
     } else {
       if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
-                                  D->getTagKind(), DC, StartLoc, Loc,
+                                  D->getTagKind(), DC, *BeginLocOrErr, Loc,
                                   Name.getAsIdentifierInfo(), PrevDecl))
         return D2;
       D2->setLexicalDeclContext(LexicalDC);
       LexicalDC->addDeclInternal(D2);
     }
 
-    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+    if (auto QualifierLocOrErr = import(D->getQualifierLoc()))
+      D2->setQualifierInfo(*QualifierLocOrErr);
+    else
+      return QualifierLocOrErr.takeError();
+
     if (D->isAnonymousStructOrUnion())
       D2->setAnonymousStructOrUnion(true);
   }
 
   Importer.MapImported(D, D2);
 
-  if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
-    return nullptr;
+  if (D->isCompleteDefinition())
+    if (Error Err = ImportDefinition(D, D2, IDK_Default))
+      return std::move(Err);
 
   return D2;
 }
 
-Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
   // Import the major distinguishing characteristics of this enumerator.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
-
   // Determine whether there are any other declarations with the same name and
   // in the same context.
   if (!LexicalDC->isFunctionOrMethod()) {
@@ -2467,18 +2862,22 @@
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
       if (!Name)
-        return nullptr;
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
-  Expr *Init = Importer.Import(D->getInitExpr());
-  if (D->getInitExpr() && !Init)
-    return nullptr;
+  ExpectedType TypeOrErr = import(D->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
+
+  ExpectedExpr InitOrErr = import(D->getInitExpr());
+  if (!InitOrErr)
+    return InitOrErr.takeError();
 
   EnumConstantDecl *ToEnumerator;
   if (GetImportedOrCreateDecl(
           ToEnumerator, D, Importer.getToContext(), cast<EnumDecl>(DC), Loc,
-          Name.getAsIdentifierInfo(), T, Init, D->getInitVal()))
+          Name.getAsIdentifierInfo(), *TypeOrErr, *InitOrErr, D->getInitVal()))
     return ToEnumerator;
 
   ToEnumerator->setAccess(D->getAccess());
@@ -2487,52 +2886,57 @@
   return ToEnumerator;
 }
 
-bool ASTNodeImporter::ImportTemplateInformation(FunctionDecl *FromFD,
-                                                FunctionDecl *ToFD) {
+Error ASTNodeImporter::ImportTemplateInformation(
+    FunctionDecl *FromFD, FunctionDecl *ToFD) {
   switch (FromFD->getTemplatedKind()) {
   case FunctionDecl::TK_NonTemplate:
   case FunctionDecl::TK_FunctionTemplate:
-    return false;
+    return Error::success();
 
   case FunctionDecl::TK_MemberSpecialization: {
-    auto *InstFD = cast_or_null<FunctionDecl>(
-          Importer.Import(FromFD->getInstantiatedFromMemberFunction()));
-    if (!InstFD)
-      return true;
-
     TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind();
-    SourceLocation POI = Importer.Import(
-          FromFD->getMemberSpecializationInfo()->getPointOfInstantiation());
-    ToFD->setInstantiationOfMemberFunction(InstFD, TSK);
-    ToFD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
-    return false;
+
+    if (Expected<FunctionDecl *> InstFDOrErr =
+        import(FromFD->getInstantiatedFromMemberFunction()))
+      ToFD->setInstantiationOfMemberFunction(*InstFDOrErr, TSK);
+    else
+      return InstFDOrErr.takeError();
+
+    if (ExpectedSLoc POIOrErr = import(
+        FromFD->getMemberSpecializationInfo()->getPointOfInstantiation()))
+      ToFD->getMemberSpecializationInfo()->setPointOfInstantiation(*POIOrErr);
+    else
+      return POIOrErr.takeError();
+
+    return Error::success();
   }
 
   case FunctionDecl::TK_FunctionTemplateSpecialization: {
-    FunctionTemplateDecl* Template;
-    OptionalTemplateArgsTy ToTemplArgs;
-    std::tie(Template, ToTemplArgs) =
+    auto FunctionAndArgsOrErr =
         ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
-    if (!Template || !ToTemplArgs)
-      return true;
+    if (!FunctionAndArgsOrErr)
+      return FunctionAndArgsOrErr.takeError();
 
     TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy(
-          Importer.getToContext(), *ToTemplArgs);
+          Importer.getToContext(), std::get<1>(*FunctionAndArgsOrErr));
 
     auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
     TemplateArgumentListInfo ToTAInfo;
     const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten;
     if (FromTAArgsAsWritten)
-      if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ToTAInfo))
-        return true;
+      if (Error Err = ImportTemplateArgumentListInfo(
+          *FromTAArgsAsWritten, ToTAInfo))
+        return Err;
 
-    SourceLocation POI = Importer.Import(FTSInfo->getPointOfInstantiation());
+    ExpectedSLoc POIOrErr = import(FTSInfo->getPointOfInstantiation());
+    if (!POIOrErr)
+      return POIOrErr.takeError();
 
     TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
     ToFD->setFunctionTemplateSpecialization(
-        Template, ToTAList, /* InsertPos= */ nullptr,
-        TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, POI);
-    return false;
+        std::get<0>(*FunctionAndArgsOrErr), ToTAList, /* InsertPos= */ nullptr,
+        TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, *POIOrErr);
+    return Error::success();
   }
 
   case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
@@ -2540,53 +2944,56 @@
     UnresolvedSet<8> TemplDecls;
     unsigned NumTemplates = FromInfo->getNumTemplates();
     for (unsigned I = 0; I < NumTemplates; I++) {
-      if (auto *ToFTD = cast_or_null<FunctionTemplateDecl>(
-              Importer.Import(FromInfo->getTemplate(I))))
-        TemplDecls.addDecl(ToFTD);
+      if (Expected<FunctionTemplateDecl *> ToFTDOrErr =
+          import(FromInfo->getTemplate(I)))
+        TemplDecls.addDecl(*ToFTDOrErr);
       else
-        return true;
+        return ToFTDOrErr.takeError();
     }
 
     // Import TemplateArgumentListInfo.
     TemplateArgumentListInfo ToTAInfo;
-    if (ImportTemplateArgumentListInfo(
-            FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(),
-            llvm::makeArrayRef(FromInfo->getTemplateArgs(),
-                               FromInfo->getNumTemplateArgs()),
-            ToTAInfo))
-      return true;
+    if (Error Err = ImportTemplateArgumentListInfo(
+        FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(),
+        llvm::makeArrayRef(
+            FromInfo->getTemplateArgs(), FromInfo->getNumTemplateArgs()),
+        ToTAInfo))
+      return Err;
 
     ToFD->setDependentTemplateSpecialization(Importer.getToContext(),
                                              TemplDecls, ToTAInfo);
-    return false;
+    return Error::success();
   }
   }
   llvm_unreachable("All cases should be covered!");
 }
 
-FunctionDecl *
+Expected<FunctionDecl *>
 ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
-  FunctionTemplateDecl* Template;
-  OptionalTemplateArgsTy ToTemplArgs;
-  std::tie(Template, ToTemplArgs) =
+  auto FunctionAndArgsOrErr =
       ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
-  if (!Template || !ToTemplArgs)
-    return nullptr;
+  if (!FunctionAndArgsOrErr)
+    return FunctionAndArgsOrErr.takeError();
 
+  FunctionTemplateDecl *Template;
+  TemplateArgsTy ToTemplArgs;
+  std::tie(Template, ToTemplArgs) = *FunctionAndArgsOrErr;
   void *InsertPos = nullptr;
-  auto *FoundSpec = Template->findSpecialization(*ToTemplArgs, InsertPos);
+  auto *FoundSpec = Template->findSpecialization(ToTemplArgs, InsertPos);
   return FoundSpec;
 }
 
-Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
 
-  SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(D);
+  SmallVector<Decl *, 2> Redecls = getCanonicalForwardRedeclChain(D);
   auto RedeclIt = Redecls.begin();
   // Import the first part of the decl chain. I.e. import all previous
   // declarations starting from the canonical decl.
-  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt)
-    if (!Importer.Import(*RedeclIt))
-      return nullptr;
+  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt) {
+    ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
+    if (!ToRedeclOrErr)
+      return ToRedeclOrErr.takeError();
+  }
   assert(*RedeclIt == D);
 
   // Import the major distinguishing characteristics of this function.
@@ -2594,8 +3001,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -2609,10 +3016,12 @@
   // FIXME handle member function templates (TK_MemberSpecialization) similarly?
   if (D->getTemplatedKind() ==
       FunctionDecl::TK_FunctionTemplateSpecialization) {
-    if (FunctionDecl *FoundFunction = FindFunctionTemplateSpecialization(D)) {
-      if (D->doesThisDeclarationHaveABody() &&
-          FoundFunction->hasBody())
-        return Importer.Imported(D, FoundFunction);
+    auto FoundFunctionOrErr = FindFunctionTemplateSpecialization(D);
+    if (!FoundFunctionOrErr)
+      return FoundFunctionOrErr.takeError();
+    if (FunctionDecl *FoundFunction = *FoundFunctionOrErr) {
+      if (D->doesThisDeclarationHaveABody() && FoundFunction->hasBody())
+        return Importer.MapImported(D, FoundFunction);
       FoundByLookup = FoundFunction;
     }
   }
@@ -2673,13 +3082,14 @@
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
       if (!Name)
-        return nullptr;
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
   DeclarationNameInfo NameInfo(Name, Loc);
   // Import additional name location/type info.
-  ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+  if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
+    return std::move(Err);
 
   QualType FromTy = D->getType();
   bool usedDifferentExceptionSpec = false;
@@ -2700,42 +3110,41 @@
     }
   }
 
-  // Import the type.
-  QualType T = Importer.Import(FromTy);
-  if (T.isNull())
-    return nullptr;
+  QualType T;
+  TypeSourceInfo *TInfo;
+  SourceLocation ToInnerLocStart, ToEndLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  if (auto Imp = importSeq(
+      FromTy, D->getTypeSourceInfo(), D->getInnerLocStart(),
+      D->getQualifierLoc(), D->getEndLoc()))
+    std::tie(T, TInfo, ToInnerLocStart, ToQualifierLoc, ToEndLoc) = *Imp;
+  else
+    return Imp.takeError();
 
   // Import the function parameters.
   SmallVector<ParmVarDecl *, 8> Parameters;
   for (auto P : D->parameters()) {
-    auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
-    if (!ToP)
-      return nullptr;
-
-    Parameters.push_back(ToP);
+    if (Expected<ParmVarDecl *> ToPOrErr = import(P))
+      Parameters.push_back(*ToPOrErr);
+    else
+      return ToPOrErr.takeError();
   }
 
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-  if (D->getTypeSourceInfo() && !TInfo)
-    return nullptr;
-
   // Create the imported function.
   FunctionDecl *ToFunction = nullptr;
-  SourceLocation InnerLocStart = Importer.Import(D->getInnerLocStart());
   if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
     if (GetImportedOrCreateDecl<CXXConstructorDecl>(
-            ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
-            InnerLocStart, NameInfo, T, TInfo, FromConstructor->isExplicit(),
-            D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
+        ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+        ToInnerLocStart, NameInfo, T, TInfo,
+        FromConstructor->isExplicit(),
+        D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
       return ToFunction;
     if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
-      SmallVector<CXXCtorInitializer *, 4> CtorInitializers;
-      for (auto *I : FromConstructor->inits()) {
-        auto *ToI = cast_or_null<CXXCtorInitializer>(Importer.Import(I));
-        if (!ToI && I)
-          return nullptr;
-        CtorInitializers.push_back(ToI);
-      }
+      SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
+      // Import first, then allocate memory and copy if there was no error.
+      if (Error Err = ImportContainerChecked(
+          FromConstructor->inits(), CtorInitializers))
+        return std::move(Err);
       auto **Memory =
           new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
       std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
@@ -2745,39 +3154,38 @@
     }
   } else if (isa<CXXDestructorDecl>(D)) {
     if (GetImportedOrCreateDecl<CXXDestructorDecl>(
-            ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
-            InnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
-            D->isImplicit()))
+        ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+        ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
+        D->isImplicit()))
       return ToFunction;
   } else if (CXXConversionDecl *FromConversion =
                  dyn_cast<CXXConversionDecl>(D)) {
     if (GetImportedOrCreateDecl<CXXConversionDecl>(
             ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
-            InnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
+            ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
             FromConversion->isExplicit(), D->isConstexpr(), SourceLocation()))
       return ToFunction;
   } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
     if (GetImportedOrCreateDecl<CXXMethodDecl>(
             ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
-            InnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
+            ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
             Method->isInlineSpecified(), D->isConstexpr(), SourceLocation()))
       return ToFunction;
   } else {
     if (GetImportedOrCreateDecl(ToFunction, D, Importer.getToContext(), DC,
-                                InnerLocStart, NameInfo, T, TInfo,
+                                ToInnerLocStart, NameInfo, T, TInfo,
                                 D->getStorageClass(), D->isInlineSpecified(),
                                 D->hasWrittenPrototype(), D->isConstexpr()))
       return ToFunction;
   }
 
-  // Import the qualifier, if any.
-  ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+  ToFunction->setQualifierInfo(ToQualifierLoc);
   ToFunction->setAccess(D->getAccess());
   ToFunction->setLexicalDeclContext(LexicalDC);
   ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
   ToFunction->setTrivial(D->isTrivial());
   ToFunction->setPure(D->isPure());
-  ToFunction->setRangeEnd(Importer.Import(D->getEndLoc()));
+  ToFunction->setRangeEnd(ToEndLoc);
 
   // Set the parameters.
   for (auto *Param : Parameters) {
@@ -2804,30 +3212,33 @@
 
   if (usedDifferentExceptionSpec) {
     // Update FunctionProtoType::ExtProtoInfo.
-    QualType T = Importer.Import(D->getType());
-    if (T.isNull())
-      return nullptr;
-    ToFunction->setType(T);
+    if (ExpectedType TyOrErr = import(D->getType()))
+      ToFunction->setType(*TyOrErr);
+    else
+      return TyOrErr.takeError();
   }
 
   // Import the describing template function, if any.
-  if (FromFT)
-    if (!Importer.Import(FromFT))
-      return nullptr;
+  if (FromFT) {
+    auto ToFTOrErr = import(FromFT);
+    if (!ToFTOrErr)
+      return ToFTOrErr.takeError();
+  }
 
   if (D->doesThisDeclarationHaveABody()) {
     if (Stmt *FromBody = D->getBody()) {
-      if (Stmt *ToBody = Importer.Import(FromBody)) {
-        ToFunction->setBody(ToBody);
-      }
+      if (ExpectedStmt ToBodyOrErr = import(FromBody))
+        ToFunction->setBody(*ToBodyOrErr);
+      else
+        return ToBodyOrErr.takeError();
     }
   }
 
   // FIXME: Other bits to merge?
 
   // If it is a template, import all related things.
-  if (ImportTemplateInformation(D, ToFunction))
-    return nullptr;
+  if (Error Err = ImportTemplateInformation(D, ToFunction))
+    return std::move(Err);
 
   bool IsFriend = D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend);
 
@@ -2848,9 +3259,11 @@
   }
 
   // Import the rest of the chain. I.e. import all subsequent declarations.
-  for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt)
-    if (!Importer.Import(*RedeclIt))
-      return nullptr;
+  for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
+    ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
+    if (!ToRedeclOrErr)
+      return ToRedeclOrErr.takeError();
+  }
 
   if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
     ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod);
@@ -2858,30 +3271,30 @@
   return ToFunction;
 }
 
-Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
   return VisitFunctionDecl(D);
 }
 
-Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
   return VisitCXXMethodDecl(D);
 }
 
-Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
   return VisitCXXMethodDecl(D);
 }
 
-Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
   return VisitCXXMethodDecl(D);
 }
 
-Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
   // Import the major distinguishing characteristics of a variable.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -2889,7 +3302,7 @@
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
   for (auto *FoundDecl : FoundDecls) {
-    if (auto *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
+    if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
       // For anonymous fields, match up by index.
       if (!Name &&
           ASTImporter::getFieldIndex(D) !=
@@ -2907,64 +3320,67 @@
           // We don't have yet the initializer set.
           if (FoundField->hasInClassInitializer() &&
               !FoundField->getInClassInitializer()) {
-            Expr *ToInitializer = Importer.Import(FromInitializer);
-            if (!ToInitializer)
-              // We can't return a nullptr here,
+            if (ExpectedExpr ToInitializerOrErr = import(FromInitializer))
+              FoundField->setInClassInitializer(*ToInitializerOrErr);
+            else {
+              // We can't return error here,
               // since we already mapped D as imported.
+              // FIXME: warning message?
+              consumeError(ToInitializerOrErr.takeError());
               return FoundField;
-            FoundField->setInClassInitializer(ToInitializer);
+            }
           }
         }
         return FoundField;
       }
 
+      // FIXME: Why is this case not handled with calling HandleNameConflict?
       Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
         << FoundField->getType();
-      return nullptr;
+
+      return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
-  // Import the type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
-
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-  Expr *BitWidth = Importer.Import(D->getBitWidth());
-  if (!BitWidth && D->getBitWidth())
-    return nullptr;
+  QualType ToType;
+  TypeSourceInfo *ToTInfo;
+  Expr *ToBitWidth;
+  SourceLocation ToInnerLocStart;
+  Expr *ToInitializer;
+  if (auto Imp = importSeq(
+      D->getType(), D->getTypeSourceInfo(), D->getBitWidth(),
+      D->getInnerLocStart(), D->getInClassInitializer()))
+    std::tie(
+        ToType, ToTInfo, ToBitWidth, ToInnerLocStart, ToInitializer) = *Imp;
+  else
+    return Imp.takeError();
 
   FieldDecl *ToField;
   if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getInnerLocStart()), Loc,
-                              Name.getAsIdentifierInfo(), T, TInfo, BitWidth,
-                              D->isMutable(), D->getInClassInitStyle()))
+                              ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
+                              ToType, ToTInfo, ToBitWidth, D->isMutable(),
+                              D->getInClassInitStyle()))
     return ToField;
 
   ToField->setAccess(D->getAccess());
   ToField->setLexicalDeclContext(LexicalDC);
-  if (Expr *FromInitializer = D->getInClassInitializer()) {
-    Expr *ToInitializer = Importer.Import(FromInitializer);
-    if (ToInitializer)
-      ToField->setInClassInitializer(ToInitializer);
-    else
-      return nullptr;
-  }
+  if (ToInitializer)
+    ToField->setInClassInitializer(ToInitializer);
   ToField->setImplicit(D->isImplicit());
   LexicalDC->addDeclInternal(ToField);
   return ToField;
 }
 
-Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
   // Import the major distinguishing characteristics of a variable.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -2990,39 +3406,40 @@
       if (!Name && I < N-1)
         continue;
 
+      // FIXME: Why is this case not handled with calling HandleNameConflict?
       Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
         << FoundField->getType();
-      return nullptr;
+
+      return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
   // Import the type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
+  auto TypeOrErr = import(D->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
 
   auto **NamedChain =
     new (Importer.getToContext()) NamedDecl*[D->getChainingSize()];
 
   unsigned i = 0;
-  for (auto *PI : D->chain()) {
-    Decl *D = Importer.Import(PI);
-    if (!D)
-      return nullptr;
-    NamedChain[i++] = cast<NamedDecl>(D);
-  }
+  for (auto *PI : D->chain())
+    if (Expected<NamedDecl *> ToD = import(PI))
+      NamedChain[i++] = *ToD;
+    else
+      return ToD.takeError();
 
   llvm::MutableArrayRef<NamedDecl *> CH = {NamedChain, D->getChainingSize()};
   IndirectFieldDecl *ToIndirectField;
   if (GetImportedOrCreateDecl(ToIndirectField, D, Importer.getToContext(), DC,
-                              Loc, Name.getAsIdentifierInfo(), T, CH))
+                              Loc, Name.getAsIdentifierInfo(), *TypeOrErr, CH))
     // FIXME here we leak `NamedChain` which is allocated before
     return ToIndirectField;
 
-  for (const auto *A : D->attrs())
-    ToIndirectField->addAttr(Importer.Import(A));
+  for (const auto *Attr : D->attrs())
+    ToIndirectField->addAttr(Importer.Import(Attr));
 
   ToIndirectField->setAccess(D->getAccess());
   ToIndirectField->setLexicalDeclContext(LexicalDC);
@@ -3030,13 +3447,11 @@
   return ToIndirectField;
 }
 
-Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
   // Import the major distinguishing characteristics of a declaration.
-  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-  DeclContext *LexicalDC = D->getDeclContext() == D->getLexicalDeclContext()
-      ? DC : Importer.ImportContext(D->getLexicalDeclContext());
-  if (!DC || !LexicalDC)
-    return nullptr;
+  DeclContext *DC, *LexicalDC;
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return std::move(Err);
 
   // Determine whether we've already imported this decl.
   // FriendDecl is not a NamedDecl so we cannot use localUncachedLookup.
@@ -3061,30 +3476,42 @@
   // Not found. Create it.
   FriendDecl::FriendUnion ToFU;
   if (NamedDecl *FriendD = D->getFriendDecl()) {
-    auto *ToFriendD = cast_or_null<NamedDecl>(Importer.Import(FriendD));
-    if (ToFriendD && FriendD->getFriendObjectKind() != Decl::FOK_None &&
+    NamedDecl *ToFriendD;
+    if (Error Err = importInto(ToFriendD, FriendD))
+      return std::move(Err);
+
+    if (FriendD->getFriendObjectKind() != Decl::FOK_None &&
         !(FriendD->isInIdentifierNamespace(Decl::IDNS_NonMemberOperator)))
       ToFriendD->setObjectOfFriendDecl(false);
 
     ToFU = ToFriendD;
-  }  else // The friend is a type, not a decl.
-    ToFU = Importer.Import(D->getFriendType());
-  if (!ToFU)
-    return nullptr;
+  } else { // The friend is a type, not a decl.
+    if (auto TSIOrErr = import(D->getFriendType()))
+      ToFU = *TSIOrErr;
+    else
+      return TSIOrErr.takeError();
+  }
 
   SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
   auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>();
   for (unsigned I = 0; I < D->NumTPLists; I++) {
-    TemplateParameterList *List = ImportTemplateParameterList(FromTPLists[I]);
-    if (!List)
-      return nullptr;
-    ToTPLists[I] = List;
+    if (auto ListOrErr = ImportTemplateParameterList(FromTPLists[I]))
+      ToTPLists[I] = *ListOrErr;
+    else
+      return ListOrErr.takeError();
   }
 
+  auto LocationOrErr = import(D->getLocation());
+  if (!LocationOrErr)
+    return LocationOrErr.takeError();
+  auto FriendLocOrErr = import(D->getFriendLoc());
+  if (!FriendLocOrErr)
+    return FriendLocOrErr.takeError();
+
   FriendDecl *FrD;
   if (GetImportedOrCreateDecl(FrD, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getLocation()), ToFU,
-                              Importer.Import(D->getFriendLoc()), ToTPLists))
+                              *LocationOrErr, ToFU,
+                              *FriendLocOrErr, ToTPLists))
     return FrD;
 
   FrD->setAccess(D->getAccess());
@@ -3093,14 +3520,14 @@
   return FrD;
 }
 
-Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
   // Import the major distinguishing characteristics of an ivar.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -3108,7 +3535,7 @@
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
   for (auto *FoundDecl : FoundDecls) {
-    if (auto *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
+    if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
       if (Importer.IsStructurallyEquivalent(D->getType(),
                                             FoundIvar->getType())) {
         Importer.MapImported(D, FoundIvar);
@@ -3119,26 +3546,27 @@
         << Name << D->getType() << FoundIvar->getType();
       Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
         << FoundIvar->getType();
-      return nullptr;
+
+      return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
-  // Import the type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
-
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-  Expr *BitWidth = Importer.Import(D->getBitWidth());
-  if (!BitWidth && D->getBitWidth())
-    return nullptr;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  Expr *ToBitWidth;
+  SourceLocation ToInnerLocStart;
+  if (auto Imp = importSeq(
+      D->getType(), D->getTypeSourceInfo(), D->getBitWidth(), D->getInnerLocStart()))
+    std::tie(ToType, ToTypeSourceInfo, ToBitWidth, ToInnerLocStart) = *Imp;
+  else
+    return Imp.takeError();
 
   ObjCIvarDecl *ToIvar;
   if (GetImportedOrCreateDecl(
           ToIvar, D, Importer.getToContext(), cast<ObjCContainerDecl>(DC),
-          Importer.Import(D->getInnerLocStart()), Loc,
-          Name.getAsIdentifierInfo(), T, TInfo, D->getAccessControl(), BitWidth,
-          D->getSynthesize()))
+          ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
+          ToType, ToTypeSourceInfo,
+          D->getAccessControl(),ToBitWidth, D->getSynthesize()))
     return ToIvar;
 
   ToIvar->setLexicalDeclContext(LexicalDC);
@@ -3146,15 +3574,17 @@
   return ToIvar;
 }
 
-Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
 
   SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(D);
   auto RedeclIt = Redecls.begin();
   // Import the first part of the decl chain. I.e. import all previous
   // declarations starting from the canonical decl.
-  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt)
-    if (!Importer.Import(*RedeclIt))
-      return nullptr;
+  for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt) {
+    ExpectedDecl RedeclOrErr = import(*RedeclIt);
+    if (!RedeclOrErr)
+      return RedeclOrErr.takeError();
+  }
   assert(*RedeclIt == D);
 
   // Import the major distinguishing characteristics of a variable.
@@ -3162,8 +3592,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -3213,11 +3643,11 @@
             if (isa<IncompleteArrayType>(FoundArray) &&
                 isa<ConstantArrayType>(TArray)) {
               // Import the type.
-              QualType T = Importer.Import(D->getType());
-              if (T.isNull())
-                return nullptr;
+              if (auto TyOrErr = import(D->getType()))
+                FoundVar->setType(*TyOrErr);
+              else
+                return TyOrErr.takeError();
 
-              FoundVar->setType(T);
               FoundByLookup = FoundVar;
               break;
             } else if (isa<IncompleteArrayType>(TArray) &&
@@ -3242,25 +3672,31 @@
                                          ConflictingDecls.data(),
                                          ConflictingDecls.size());
       if (!Name)
-        return nullptr;
+        return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
-  // Import the type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceLocation ToInnerLocStart;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  if (auto Imp = importSeq(
+      D->getType(), D->getTypeSourceInfo(), D->getInnerLocStart(),
+      D->getQualifierLoc()))
+    std::tie(ToType, ToTypeSourceInfo, ToInnerLocStart, ToQualifierLoc) = *Imp;
+  else
+    return Imp.takeError();
 
   // Create the imported variable.
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   VarDecl *ToVar;
   if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getInnerLocStart()), Loc,
-                              Name.getAsIdentifierInfo(), T, TInfo,
+                              ToInnerLocStart, Loc,
+                              Name.getAsIdentifierInfo(),
+                              ToType, ToTypeSourceInfo,
                               D->getStorageClass()))
     return ToVar;
 
-  ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+  ToVar->setQualifierInfo(ToQualifierLoc);
   ToVar->setAccess(D->getAccess());
   ToVar->setLexicalDeclContext(LexicalDC);
 
@@ -3269,8 +3705,8 @@
     ToVar->setPreviousDecl(Recent);
   }
 
-  if (ImportInitializer(D, ToVar))
-    return nullptr;
+  if (Error Err = ImportInitializer(D, ToVar))
+    return std::move(Err);
 
   if (D->isConstexpr())
     ToVar->setConstexpr(true);
@@ -3281,65 +3717,60 @@
     LexicalDC->addDeclInternal(ToVar);
 
   // Import the rest of the chain. I.e. import all subsequent declarations.
-  for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt)
-    if (!Importer.Import(*RedeclIt))
-      return nullptr;
+  for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
+    ExpectedDecl RedeclOrErr = import(*RedeclIt);
+    if (!RedeclOrErr)
+      return RedeclOrErr.takeError();
+  }
 
   return ToVar;
 }
 
-Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
   // Parameters are created in the translation unit's context, then moved
   // into the function declaration's context afterward.
   DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
 
-  // Import the name of this declaration.
-  DeclarationName Name = Importer.Import(D->getDeclName());
-  if (D->getDeclName() && !Name)
-    return nullptr;
-
-  // Import the location of this declaration.
-  SourceLocation Loc = Importer.Import(D->getLocation());
-
-  // Import the parameter's type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
+  DeclarationName ToDeclName;
+  SourceLocation ToLocation;
+  QualType ToType;
+  if (auto Imp = importSeq(D->getDeclName(), D->getLocation(), D->getType()))
+    std::tie(ToDeclName, ToLocation, ToType) = *Imp;
+  else
+    return Imp.takeError();
 
   // Create the imported parameter.
   ImplicitParamDecl *ToParm = nullptr;
-  if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC, Loc,
-                              Name.getAsIdentifierInfo(), T,
-                              D->getParameterKind()))
+  if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
+                              ToLocation, ToDeclName.getAsIdentifierInfo(),
+                              ToType, D->getParameterKind()))
     return ToParm;
   return ToParm;
 }
 
-Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
   // Parameters are created in the translation unit's context, then moved
   // into the function declaration's context afterward.
   DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
 
-  // Import the name of this declaration.
-  DeclarationName Name = Importer.Import(D->getDeclName());
-  if (D->getDeclName() && !Name)
-    return nullptr;
+  DeclarationName ToDeclName;
+  SourceLocation ToLocation, ToInnerLocStart;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  if (auto Imp = importSeq(
+      D->getDeclName(), D->getLocation(), D->getType(), D->getInnerLocStart(),
+      D->getTypeSourceInfo()))
+    std::tie(
+        ToDeclName, ToLocation, ToType, ToInnerLocStart,
+        ToTypeSourceInfo) = *Imp;
+  else
+    return Imp.takeError();
 
-  // Import the location of this declaration.
-  SourceLocation Loc = Importer.Import(D->getLocation());
-
-  // Import the parameter's type.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
-
-  // Create the imported parameter.
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
   ParmVarDecl *ToParm;
   if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getInnerLocStart()), Loc,
-                              Name.getAsIdentifierInfo(), T, TInfo,
-                              D->getStorageClass(),
+                              ToInnerLocStart, ToLocation,
+                              ToDeclName.getAsIdentifierInfo(), ToType,
+                              ToTypeSourceInfo, D->getStorageClass(),
                               /*DefaultArg*/ nullptr))
     return ToParm;
 
@@ -3347,21 +3778,19 @@
   ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
   ToParm->setKNRPromoted(D->isKNRPromoted());
 
-  Expr *ToDefArg = nullptr;
-  Expr *FromDefArg = nullptr;
   if (D->hasUninstantiatedDefaultArg()) {
-    FromDefArg = D->getUninstantiatedDefaultArg();
-    ToDefArg = Importer.Import(FromDefArg);
-    ToParm->setUninstantiatedDefaultArg(ToDefArg);
+    if (auto ToDefArgOrErr = import(D->getUninstantiatedDefaultArg()))
+      ToParm->setUninstantiatedDefaultArg(*ToDefArgOrErr);
+    else
+      return ToDefArgOrErr.takeError();
   } else if (D->hasUnparsedDefaultArg()) {
     ToParm->setUnparsedDefaultArg();
   } else if (D->hasDefaultArg()) {
-    FromDefArg = D->getDefaultArg();
-    ToDefArg = Importer.Import(FromDefArg);
-    ToParm->setDefaultArg(ToDefArg);
+    if (auto ToDefArgOrErr = import(D->getDefaultArg()))
+      ToParm->setDefaultArg(*ToDefArgOrErr);
+    else
+      return ToDefArgOrErr.takeError();
   }
-  if (FromDefArg && !ToDefArg)
-    return nullptr;
 
   if (D->isObjCMethodParameter()) {
     ToParm->setObjCMethodScopeInfo(D->getFunctionScopeIndex());
@@ -3374,14 +3803,14 @@
   return ToParm;
 }
 
-Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
   // Import the major distinguishing characteristics of a method.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -3401,7 +3830,8 @@
         Importer.ToDiag(FoundMethod->getLocation(),
                         diag::note_odr_objc_method_here)
           << D->isInstanceMethod() << Name;
-        return nullptr;
+
+        return make_error<ImportError>(ImportError::NameConflict);
       }
 
       // Check the number of parameters.
@@ -3412,7 +3842,8 @@
         Importer.ToDiag(FoundMethod->getLocation(),
                         diag::note_odr_objc_method_here)
           << D->isInstanceMethod() << Name;
-        return nullptr;
+
+        return make_error<ImportError>(ImportError::NameConflict);
       }
 
       // Check parameter types.
@@ -3427,7 +3858,8 @@
             << (*P)->getType() << (*FoundP)->getType();
           Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
             << (*FoundP)->getType();
-          return nullptr;
+
+          return make_error<ImportError>(ImportError::NameConflict);
         }
       }
 
@@ -3439,7 +3871,8 @@
         Importer.ToDiag(FoundMethod->getLocation(),
                         diag::note_odr_objc_method_here)
           << D->isInstanceMethod() << Name;
-        return nullptr;
+
+        return make_error<ImportError>(ImportError::NameConflict);
       }
 
       // FIXME: Any other bits we need to merge?
@@ -3447,18 +3880,20 @@
     }
   }
 
-  // Import the result type.
-  QualType ResultTy = Importer.Import(D->getReturnType());
-  if (ResultTy.isNull())
-    return nullptr;
-
-  TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
+  SourceLocation ToEndLoc;
+  QualType ToReturnType;
+  TypeSourceInfo *ToReturnTypeSourceInfo;
+  if (auto Imp = importSeq(
+      D->getEndLoc(), D->getReturnType(), D->getReturnTypeSourceInfo()))
+    std::tie(ToEndLoc, ToReturnType, ToReturnTypeSourceInfo) = *Imp;
+  else
+    return Imp.takeError();
 
   ObjCMethodDecl *ToMethod;
   if (GetImportedOrCreateDecl(
           ToMethod, D, Importer.getToContext(), Loc,
-          Importer.Import(D->getEndLoc()), Name.getObjCSelector(), ResultTy,
-          ReturnTInfo, DC, D->isInstanceMethod(), D->isVariadic(),
+          ToEndLoc, Name.getObjCSelector(), ToReturnType,
+          ToReturnTypeSourceInfo, DC, D->isInstanceMethod(), D->isVariadic(),
           D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
           D->getImplementationControl(), D->hasRelatedResultType()))
     return ToMethod;
@@ -3469,11 +3904,10 @@
   // Import the parameters
   SmallVector<ParmVarDecl *, 5> ToParams;
   for (auto *FromP : D->parameters()) {
-    auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
-    if (!ToP)
-      return nullptr;
-
-    ToParams.push_back(ToP);
+    if (Expected<ParmVarDecl *> ToPOrErr = import(FromP))
+      ToParams.push_back(*ToPOrErr);
+    else
+      return ToPOrErr.takeError();
   }
 
   // Set the parameters.
@@ -3482,82 +3916,99 @@
     ToMethod->addDeclInternal(ToParam);
   }
 
-  SmallVector<SourceLocation, 12> SelLocs;
-  D->getSelectorLocs(SelLocs);
-  for (auto &Loc : SelLocs)
-    Loc = Importer.Import(Loc);
+  SmallVector<SourceLocation, 12> FromSelLocs;
+  D->getSelectorLocs(FromSelLocs);
+  SmallVector<SourceLocation, 12> ToSelLocs(FromSelLocs.size());
+  if (Error Err = ImportContainerChecked(FromSelLocs, ToSelLocs))
+    return std::move(Err);
 
-  ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
+  ToMethod->setMethodParams(Importer.getToContext(), ToParams, ToSelLocs);
 
   ToMethod->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(ToMethod);
   return ToMethod;
 }
 
-Decl *ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
   // Import the major distinguishing characteristics of a category.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  TypeSourceInfo *BoundInfo = Importer.Import(D->getTypeSourceInfo());
-  if (!BoundInfo)
-    return nullptr;
+  SourceLocation ToVarianceLoc, ToLocation, ToColonLoc;
+  TypeSourceInfo *ToTypeSourceInfo;
+  if (auto Imp = importSeq(
+      D->getVarianceLoc(), D->getLocation(), D->getColonLoc(),
+      D->getTypeSourceInfo()))
+    std::tie(ToVarianceLoc, ToLocation, ToColonLoc, ToTypeSourceInfo) = *Imp;
+  else
+    return Imp.takeError();
 
   ObjCTypeParamDecl *Result;
   if (GetImportedOrCreateDecl(
           Result, D, Importer.getToContext(), DC, D->getVariance(),
-          Importer.Import(D->getVarianceLoc()), D->getIndex(),
-          Importer.Import(D->getLocation()), Name.getAsIdentifierInfo(),
-          Importer.Import(D->getColonLoc()), BoundInfo))
+          ToVarianceLoc, D->getIndex(),
+          ToLocation, Name.getAsIdentifierInfo(),
+          ToColonLoc, ToTypeSourceInfo))
     return Result;
 
   Result->setLexicalDeclContext(LexicalDC);
   return Result;
 }
 
-Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
   // Import the major distinguishing characteristics of a category.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  auto *ToInterface =
-      cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
-  if (!ToInterface)
-    return nullptr;
+  ObjCInterfaceDecl *ToInterface;
+  if (Error Err = importInto(ToInterface, D->getClassInterface()))
+    return std::move(Err);
 
   // Determine if we've already encountered this category.
   ObjCCategoryDecl *MergeWithCategory
     = ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
   ObjCCategoryDecl *ToCategory = MergeWithCategory;
   if (!ToCategory) {
+    SourceLocation ToAtStartLoc, ToCategoryNameLoc;
+    SourceLocation ToIvarLBraceLoc, ToIvarRBraceLoc;
+    if (auto Imp = importSeq(
+        D->getAtStartLoc(), D->getCategoryNameLoc(),
+        D->getIvarLBraceLoc(), D->getIvarRBraceLoc()))
+      std::tie(
+          ToAtStartLoc, ToCategoryNameLoc,
+          ToIvarLBraceLoc, ToIvarRBraceLoc) = *Imp;
+    else
+      return Imp.takeError();
 
     if (GetImportedOrCreateDecl(ToCategory, D, Importer.getToContext(), DC,
-                                Importer.Import(D->getAtStartLoc()), Loc,
-                                Importer.Import(D->getCategoryNameLoc()),
+                                ToAtStartLoc, Loc,
+                                ToCategoryNameLoc,
                                 Name.getAsIdentifierInfo(), ToInterface,
                                 /*TypeParamList=*/nullptr,
-                                Importer.Import(D->getIvarLBraceLoc()),
-                                Importer.Import(D->getIvarRBraceLoc())))
+                                ToIvarLBraceLoc,
+                                ToIvarRBraceLoc))
       return ToCategory;
 
     ToCategory->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(ToCategory);
-    // Import the type parameter list after calling Imported, to avoid
+    // Import the type parameter list after MapImported, to avoid
     // loops when bringing in their DeclContext.
-    ToCategory->setTypeParamList(ImportObjCTypeParamList(
-                                   D->getTypeParamList()));
+    if (auto PListOrErr = ImportObjCTypeParamList(D->getTypeParamList()))
+      ToCategory->setTypeParamList(*PListOrErr);
+    else
+      return PListOrErr.takeError();
 
     // Import protocols
     SmallVector<ObjCProtocolDecl *, 4> Protocols;
@@ -3568,45 +4019,48 @@
                                           FromProtoEnd = D->protocol_end();
          FromProto != FromProtoEnd;
          ++FromProto, ++FromProtoLoc) {
-      auto *ToProto =
-          cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
-      if (!ToProto)
-        return nullptr;
-      Protocols.push_back(ToProto);
-      ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+      if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
+        Protocols.push_back(*ToProtoOrErr);
+      else
+        return ToProtoOrErr.takeError();
+
+      if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
+        ProtocolLocs.push_back(*ToProtoLocOrErr);
+      else
+        return ToProtoLocOrErr.takeError();
     }
 
     // FIXME: If we're merging, make sure that the protocol list is the same.
     ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
                                 ProtocolLocs.data(), Importer.getToContext());
+
   } else {
     Importer.MapImported(D, ToCategory);
   }
 
   // Import all of the members of this category.
-  ImportDeclContext(D);
+  if (Error Err = ImportDeclContext(D))
+    return std::move(Err);
 
   // If we have an implementation, import it as well.
   if (D->getImplementation()) {
-    auto *Impl =
-        cast_or_null<ObjCCategoryImplDecl>(
-                                       Importer.Import(D->getImplementation()));
-    if (!Impl)
-      return nullptr;
-
-    ToCategory->setImplementation(Impl);
+    if (Expected<ObjCCategoryImplDecl *> ToImplOrErr =
+        import(D->getImplementation()))
+      ToCategory->setImplementation(*ToImplOrErr);
+    else
+      return ToImplOrErr.takeError();
   }
 
   return ToCategory;
 }
 
-bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
-                                       ObjCProtocolDecl *To,
-                                       ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportDefinition(
+    ObjCProtocolDecl *From, ObjCProtocolDecl *To, ImportDefinitionKind Kind) {
   if (To->getDefinition()) {
     if (shouldForceImportDeclContext(Kind))
-      ImportDeclContext(From);
-    return false;
+      if (Error Err = ImportDeclContext(From))
+        return Err;
+    return Error::success();
   }
 
   // Start the protocol definition
@@ -3615,17 +4069,22 @@
   // Import protocols
   SmallVector<ObjCProtocolDecl *, 4> Protocols;
   SmallVector<SourceLocation, 4> ProtocolLocs;
-  ObjCProtocolDecl::protocol_loc_iterator
-  FromProtoLoc = From->protocol_loc_begin();
+  ObjCProtocolDecl::protocol_loc_iterator FromProtoLoc =
+      From->protocol_loc_begin();
   for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(),
                                         FromProtoEnd = From->protocol_end();
        FromProto != FromProtoEnd;
        ++FromProto, ++FromProtoLoc) {
-    auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
-    if (!ToProto)
-      return true;
-    Protocols.push_back(ToProto);
-    ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+    if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
+      Protocols.push_back(*ToProtoOrErr);
+    else
+      return ToProtoOrErr.takeError();
+
+    if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
+      ProtocolLocs.push_back(*ToProtoLocOrErr);
+    else
+      return ToProtoLocOrErr.takeError();
+
   }
 
   // FIXME: If we're merging, make sure that the protocol list is the same.
@@ -3634,22 +4093,22 @@
 
   if (shouldForceImportDeclContext(Kind)) {
     // Import all of the members of this protocol.
-    ImportDeclContext(From, /*ForceImport=*/true);
+    if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+      return Err;
   }
-  return false;
+  return Error::success();
 }
 
-Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
   // If this protocol has a definition in the translation unit we're coming
   // from, but this particular declaration is not that definition, import the
   // definition and map to that.
   ObjCProtocolDecl *Definition = D->getDefinition();
   if (Definition && Definition != D) {
-    Decl *ImportedDef = Importer.Import(Definition);
-    if (!ImportedDef)
-      return nullptr;
-
-    return Importer.MapImported(D, ImportedDef);
+    if (ExpectedDecl ImportedDefOrErr = import(Definition))
+      return Importer.MapImported(D, *ImportedDefOrErr);
+    else
+      return ImportedDefOrErr.takeError();
   }
 
   // Import the major distinguishing characteristics of a protocol.
@@ -3657,8 +4116,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -3675,9 +4134,13 @@
 
   ObjCProtocolDecl *ToProto = MergeWithProtocol;
   if (!ToProto) {
+    auto ToAtBeginLocOrErr = import(D->getAtStartLoc());
+    if (!ToAtBeginLocOrErr)
+      return ToAtBeginLocOrErr.takeError();
+
     if (GetImportedOrCreateDecl(ToProto, D, Importer.getToContext(), DC,
                                 Name.getAsIdentifierInfo(), Loc,
-                                Importer.Import(D->getAtStartLoc()),
+                                *ToAtBeginLocOrErr,
                                 /*PrevDecl=*/nullptr))
       return ToProto;
     ToProto->setLexicalDeclContext(LexicalDC);
@@ -3686,29 +4149,39 @@
 
   Importer.MapImported(D, ToProto);
 
-  if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
-    return nullptr;
+  if (D->isThisDeclarationADefinition())
+    if (Error Err = ImportDefinition(D, ToProto))
+      return std::move(Err);
 
   return ToProto;
 }
 
-Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
-  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-  DeclContext *LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+ExpectedDecl ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+  DeclContext *DC, *LexicalDC;
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return std::move(Err);
 
-  SourceLocation ExternLoc = Importer.Import(D->getExternLoc());
-  SourceLocation LangLoc = Importer.Import(D->getLocation());
+  ExpectedSLoc ExternLocOrErr = import(D->getExternLoc());
+  if (!ExternLocOrErr)
+    return ExternLocOrErr.takeError();
+
+  ExpectedSLoc LangLocOrErr = import(D->getLocation());
+  if (!LangLocOrErr)
+    return LangLocOrErr.takeError();
 
   bool HasBraces = D->hasBraces();
 
   LinkageSpecDecl *ToLinkageSpec;
   if (GetImportedOrCreateDecl(ToLinkageSpec, D, Importer.getToContext(), DC,
-                              ExternLoc, LangLoc, D->getLanguage(), HasBraces))
+                              *ExternLocOrErr, *LangLocOrErr,
+                              D->getLanguage(), HasBraces))
     return ToLinkageSpec;
 
   if (HasBraces) {
-    SourceLocation RBraceLoc = Importer.Import(D->getRBraceLoc());
-    ToLinkageSpec->setRBraceLoc(RBraceLoc);
+    ExpectedSLoc RBraceLocOrErr = import(D->getRBraceLoc());
+    if (!RBraceLocOrErr)
+      return RBraceLocOrErr.takeError();
+    ToLinkageSpec->setRBraceLoc(*RBraceLocOrErr);
   }
 
   ToLinkageSpec->setLexicalDeclContext(LexicalDC);
@@ -3717,24 +4190,31 @@
   return ToLinkageSpec;
 }
 
-Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD = nullptr;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  DeclarationNameInfo NameInfo(Name,
-                               Importer.Import(D->getNameInfo().getLoc()));
-  ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+  SourceLocation ToLoc, ToUsingLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  if (auto Imp = importSeq(
+      D->getNameInfo().getLoc(), D->getUsingLoc(), D->getQualifierLoc()))
+    std::tie(ToLoc, ToUsingLoc, ToQualifierLoc) = *Imp;
+  else
+    return Imp.takeError();
+
+  DeclarationNameInfo NameInfo(Name, ToLoc);
+  if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
+    return std::move(Err);
 
   UsingDecl *ToUsing;
   if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getUsingLoc()),
-                              Importer.Import(D->getQualifierLoc()), NameInfo,
+                              ToUsingLoc, ToQualifierLoc, NameInfo,
                               D->hasTypename()))
     return ToUsing;
 
@@ -3743,48 +4223,45 @@
 
   if (NamedDecl *FromPattern =
       Importer.getFromContext().getInstantiatedFromUsingDecl(D)) {
-    if (auto *ToPattern =
-            dyn_cast_or_null<NamedDecl>(Importer.Import(FromPattern)))
-      Importer.getToContext().setInstantiatedFromUsingDecl(ToUsing, ToPattern);
+    if (Expected<NamedDecl *> ToPatternOrErr = import(FromPattern))
+      Importer.getToContext().setInstantiatedFromUsingDecl(
+          ToUsing, *ToPatternOrErr);
     else
-      return nullptr;
+      return ToPatternOrErr.takeError();
   }
 
-  for (auto *FromShadow : D->shadows()) {
-    if (auto *ToShadow =
-            dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromShadow)))
-      ToUsing->addShadowDecl(ToShadow);
+  for (UsingShadowDecl *FromShadow : D->shadows()) {
+    if (Expected<UsingShadowDecl *> ToShadowOrErr = import(FromShadow))
+      ToUsing->addShadowDecl(*ToShadowOrErr);
     else
-      // FIXME: We return a nullptr here but the definition is already created
+      // FIXME: We return error here but the definition is already created
       // and available with lookups. How to fix this?..
-      return nullptr;
+      return ToShadowOrErr.takeError();
   }
   return ToUsing;
 }
 
-Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD = nullptr;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  auto *ToUsing = dyn_cast_or_null<UsingDecl>(
-      Importer.Import(D->getUsingDecl()));
-  if (!ToUsing)
-    return nullptr;
+  Expected<UsingDecl *> ToUsingOrErr = import(D->getUsingDecl());
+  if (!ToUsingOrErr)
+    return ToUsingOrErr.takeError();
 
-  auto *ToTarget = dyn_cast_or_null<NamedDecl>(
-      Importer.Import(D->getTargetDecl()));
-  if (!ToTarget)
-    return nullptr;
+  Expected<NamedDecl *> ToTargetOrErr = import(D->getTargetDecl());
+  if (!ToTargetOrErr)
+    return ToTargetOrErr.takeError();
 
   UsingShadowDecl *ToShadow;
   if (GetImportedOrCreateDecl(ToShadow, D, Importer.getToContext(), DC, Loc,
-                              ToUsing, ToTarget))
+                              *ToUsingOrErr, *ToTargetOrErr))
     return ToShadow;
 
   ToShadow->setLexicalDeclContext(LexicalDC);
@@ -3792,14 +4269,13 @@
 
   if (UsingShadowDecl *FromPattern =
       Importer.getFromContext().getInstantiatedFromUsingShadowDecl(D)) {
-    if (auto *ToPattern =
-            dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromPattern)))
-      Importer.getToContext().setInstantiatedFromUsingShadowDecl(ToShadow,
-                                                                 ToPattern);
+    if (Expected<UsingShadowDecl *> ToPatternOrErr = import(FromPattern))
+      Importer.getToContext().setInstantiatedFromUsingShadowDecl(
+          ToShadow, *ToPatternOrErr);
     else
-      // FIXME: We return a nullptr here but the definition is already created
+      // FIXME: We return error here but the definition is already created
       // and available with lookups. How to fix this?..
-      return nullptr;
+      return ToPatternOrErr.takeError();
   }
 
   LexicalDC->addDeclInternal(ToShadow);
@@ -3807,32 +4283,40 @@
   return ToShadow;
 }
 
-Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD = nullptr;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  DeclContext *ToComAncestor = Importer.ImportContext(D->getCommonAncestor());
-  if (!ToComAncestor)
-    return nullptr;
+  auto ToComAncestorOrErr = Importer.ImportContext(D->getCommonAncestor());
+  if (!ToComAncestorOrErr)
+    return ToComAncestorOrErr.takeError();
 
-  auto *ToNominated = cast_or_null<NamespaceDecl>(
-      Importer.Import(D->getNominatedNamespace()));
-  if (!ToNominated)
-    return nullptr;
+  NamespaceDecl *ToNominatedNamespace;
+  SourceLocation ToUsingLoc, ToNamespaceKeyLocation, ToIdentLocation;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  if (auto Imp = importSeq(
+      D->getNominatedNamespace(), D->getUsingLoc(),
+      D->getNamespaceKeyLocation(), D->getQualifierLoc(),
+      D->getIdentLocation()))
+    std::tie(
+        ToNominatedNamespace, ToUsingLoc, ToNamespaceKeyLocation,
+        ToQualifierLoc, ToIdentLocation) = *Imp;
+  else
+    return Imp.takeError();
 
   UsingDirectiveDecl *ToUsingDir;
   if (GetImportedOrCreateDecl(ToUsingDir, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getUsingLoc()),
-                              Importer.Import(D->getNamespaceKeyLocation()),
-                              Importer.Import(D->getQualifierLoc()),
-                              Importer.Import(D->getIdentLocation()),
-                              ToNominated, ToComAncestor))
+                              ToUsingLoc,
+                              ToNamespaceKeyLocation,
+                              ToQualifierLoc,
+                              ToIdentLocation,
+                              ToNominatedNamespace, *ToComAncestorOrErr))
     return ToUsingDir;
 
   ToUsingDir->setLexicalDeclContext(LexicalDC);
@@ -3841,25 +4325,34 @@
   return ToUsingDir;
 }
 
-Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl(
+ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingValueDecl(
     UnresolvedUsingValueDecl *D) {
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD = nullptr;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
-  DeclarationNameInfo NameInfo(Name, Importer.Import(D->getNameInfo().getLoc()));
-  ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+  SourceLocation ToLoc, ToUsingLoc, ToEllipsisLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  if (auto Imp = importSeq(
+      D->getNameInfo().getLoc(), D->getUsingLoc(), D->getQualifierLoc(),
+      D->getEllipsisLoc()))
+    std::tie(ToLoc, ToUsingLoc, ToQualifierLoc, ToEllipsisLoc) = *Imp;
+  else
+    return Imp.takeError();
+
+  DeclarationNameInfo NameInfo(Name, ToLoc);
+  if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
+    return std::move(Err);
 
   UnresolvedUsingValueDecl *ToUsingValue;
   if (GetImportedOrCreateDecl(ToUsingValue, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getUsingLoc()),
-                              Importer.Import(D->getQualifierLoc()), NameInfo,
-                              Importer.Import(D->getEllipsisLoc())))
+                              ToUsingLoc, ToQualifierLoc, NameInfo,
+                              ToEllipsisLoc))
     return ToUsingValue;
 
   ToUsingValue->setAccess(D->getAccess());
@@ -3869,23 +4362,30 @@
   return ToUsingValue;
 }
 
-Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
+ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
     UnresolvedUsingTypenameDecl *D) {
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD = nullptr;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
+  SourceLocation ToUsingLoc, ToTypenameLoc, ToEllipsisLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  if (auto Imp = importSeq(
+      D->getUsingLoc(), D->getTypenameLoc(), D->getQualifierLoc(),
+      D->getEllipsisLoc()))
+    std::tie(ToUsingLoc, ToTypenameLoc, ToQualifierLoc, ToEllipsisLoc) = *Imp;
+  else
+    return Imp.takeError();
+
   UnresolvedUsingTypenameDecl *ToUsing;
   if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
-                              Importer.Import(D->getUsingLoc()),
-                              Importer.Import(D->getTypenameLoc()),
-                              Importer.Import(D->getQualifierLoc()), Loc, Name,
-                              Importer.Import(D->getEllipsisLoc())))
+                              ToUsingLoc, ToTypenameLoc,
+                              ToQualifierLoc, Loc, Name, ToEllipsisLoc))
     return ToUsing;
 
   ToUsing->setAccess(D->getAccess());
@@ -3895,16 +4395,17 @@
   return ToUsing;
 }
 
-bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
-                                       ObjCInterfaceDecl *To,
-                                       ImportDefinitionKind Kind) {
+
+Error ASTNodeImporter::ImportDefinition(
+    ObjCInterfaceDecl *From, ObjCInterfaceDecl *To, ImportDefinitionKind Kind) {
   if (To->getDefinition()) {
     // Check consistency of superclass.
     ObjCInterfaceDecl *FromSuper = From->getSuperClass();
     if (FromSuper) {
-      FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper));
-      if (!FromSuper)
-        return true;
+      if (auto FromSuperOrErr = import(FromSuper))
+        FromSuper = *FromSuperOrErr;
+      else
+        return FromSuperOrErr.takeError();
     }
 
     ObjCInterfaceDecl *ToSuper = To->getSuperClass();
@@ -3929,8 +4430,9 @@
     }
 
     if (shouldForceImportDeclContext(Kind))
-      ImportDeclContext(From);
-    return false;
+      if (Error Err = ImportDeclContext(From))
+        return Err;
+    return Error::success();
   }
 
   // Start the definition.
@@ -3938,28 +4440,32 @@
 
   // If this class has a superclass, import it.
   if (From->getSuperClass()) {
-    TypeSourceInfo *SuperTInfo = Importer.Import(From->getSuperClassTInfo());
-    if (!SuperTInfo)
-      return true;
-
-    To->setSuperClass(SuperTInfo);
+    if (auto SuperTInfoOrErr = import(From->getSuperClassTInfo()))
+      To->setSuperClass(*SuperTInfoOrErr);
+    else
+      return SuperTInfoOrErr.takeError();
   }
 
   // Import protocols
   SmallVector<ObjCProtocolDecl *, 4> Protocols;
   SmallVector<SourceLocation, 4> ProtocolLocs;
-  ObjCInterfaceDecl::protocol_loc_iterator
-  FromProtoLoc = From->protocol_loc_begin();
+  ObjCInterfaceDecl::protocol_loc_iterator FromProtoLoc =
+      From->protocol_loc_begin();
 
   for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(),
                                          FromProtoEnd = From->protocol_end();
        FromProto != FromProtoEnd;
        ++FromProto, ++FromProtoLoc) {
-    auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
-    if (!ToProto)
-      return true;
-    Protocols.push_back(ToProto);
-    ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+    if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
+      Protocols.push_back(*ToProtoOrErr);
+    else
+      return ToProtoOrErr.takeError();
+
+    if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
+      ProtocolLocs.push_back(*ToProtoLocOrErr);
+    else
+      return ToProtoLocOrErr.takeError();
+
   }
 
   // FIXME: If we're merging, make sure that the protocol list is the same.
@@ -3968,58 +4474,66 @@
 
   // Import categories. When the categories themselves are imported, they'll
   // hook themselves into this interface.
-  for (auto *Cat : From->known_categories())
-    Importer.Import(Cat);
+  for (auto *Cat : From->known_categories()) {
+    auto ToCatOrErr = import(Cat);
+    if (!ToCatOrErr)
+      return ToCatOrErr.takeError();
+  }
 
   // If we have an @implementation, import it as well.
   if (From->getImplementation()) {
-    auto *Impl = cast_or_null<ObjCImplementationDecl>(
-        Importer.Import(From->getImplementation()));
-    if (!Impl)
-      return true;
-
-    To->setImplementation(Impl);
+    if (Expected<ObjCImplementationDecl *> ToImplOrErr =
+        import(From->getImplementation()))
+      To->setImplementation(*ToImplOrErr);
+    else
+      return ToImplOrErr.takeError();
   }
 
   if (shouldForceImportDeclContext(Kind)) {
     // Import all of the members of this class.
-    ImportDeclContext(From, /*ForceImport=*/true);
+    if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+      return Err;
   }
-  return false;
+  return Error::success();
 }
 
-ObjCTypeParamList *
+Expected<ObjCTypeParamList *>
 ASTNodeImporter::ImportObjCTypeParamList(ObjCTypeParamList *list) {
   if (!list)
     return nullptr;
 
   SmallVector<ObjCTypeParamDecl *, 4> toTypeParams;
-  for (auto fromTypeParam : *list) {
-    auto *toTypeParam = cast_or_null<ObjCTypeParamDecl>(
-        Importer.Import(fromTypeParam));
-    if (!toTypeParam)
-      return nullptr;
-
-    toTypeParams.push_back(toTypeParam);
+  for (auto *fromTypeParam : *list) {
+    if (auto toTypeParamOrErr = import(fromTypeParam))
+      toTypeParams.push_back(*toTypeParamOrErr);
+    else
+      return toTypeParamOrErr.takeError();
   }
 
+  auto LAngleLocOrErr = import(list->getLAngleLoc());
+  if (!LAngleLocOrErr)
+    return LAngleLocOrErr.takeError();
+
+  auto RAngleLocOrErr = import(list->getRAngleLoc());
+  if (!RAngleLocOrErr)
+    return RAngleLocOrErr.takeError();
+
   return ObjCTypeParamList::create(Importer.getToContext(),
-                                   Importer.Import(list->getLAngleLoc()),
+                                   *LAngleLocOrErr,
                                    toTypeParams,
-                                   Importer.Import(list->getRAngleLoc()));
+                                   *RAngleLocOrErr);
 }
 
-Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
   // If this class has a definition in the translation unit we're coming from,
   // but this particular declaration is not that definition, import the
   // definition and map to that.
   ObjCInterfaceDecl *Definition = D->getDefinition();
   if (Definition && Definition != D) {
-    Decl *ImportedDef = Importer.Import(Definition);
-    if (!ImportedDef)
-      return nullptr;
-
-    return Importer.MapImported(D, ImportedDef);
+    if (ExpectedDecl ImportedDefOrErr = import(Definition))
+      return Importer.MapImported(D, *ImportedDefOrErr);
+    else
+      return ImportedDefOrErr.takeError();
   }
 
   // Import the major distinguishing characteristics of an @interface.
@@ -4027,8 +4541,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -4047,9 +4561,13 @@
   // Create an interface declaration, if one does not already exist.
   ObjCInterfaceDecl *ToIface = MergeWithIface;
   if (!ToIface) {
+    ExpectedSLoc AtBeginLocOrErr = import(D->getAtStartLoc());
+    if (!AtBeginLocOrErr)
+      return AtBeginLocOrErr.takeError();
+
     if (GetImportedOrCreateDecl(
             ToIface, D, Importer.getToContext(), DC,
-            Importer.Import(D->getAtStartLoc()), Name.getAsIdentifierInfo(),
+            *AtBeginLocOrErr, Name.getAsIdentifierInfo(),
             /*TypeParamList=*/nullptr,
             /*PrevDecl=*/nullptr, Loc, D->isImplicitInterfaceDecl()))
       return ToIface;
@@ -4057,91 +4575,99 @@
     LexicalDC->addDeclInternal(ToIface);
   }
   Importer.MapImported(D, ToIface);
-  // Import the type parameter list after calling Imported, to avoid
+  // Import the type parameter list after MapImported, to avoid
   // loops when bringing in their DeclContext.
-  ToIface->setTypeParamList(ImportObjCTypeParamList(
-                              D->getTypeParamListAsWritten()));
+  if (auto ToPListOrErr =
+      ImportObjCTypeParamList(D->getTypeParamListAsWritten()))
+    ToIface->setTypeParamList(*ToPListOrErr);
+  else
+    return ToPListOrErr.takeError();
 
-  if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
-    return nullptr;
+  if (D->isThisDeclarationADefinition())
+    if (Error Err = ImportDefinition(D, ToIface))
+      return std::move(Err);
 
   return ToIface;
 }
 
-Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
-  auto *Category = cast_or_null<ObjCCategoryDecl>(
-      Importer.Import(D->getCategoryDecl()));
-  if (!Category)
-    return nullptr;
+ExpectedDecl
+ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+  ObjCCategoryDecl *Category;
+  if (Error Err = importInto(Category, D->getCategoryDecl()))
+    return std::move(Err);
 
   ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
   if (!ToImpl) {
-    DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-    if (!DC)
-      return nullptr;
+    DeclContext *DC, *LexicalDC;
+    if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+      return std::move(Err);
 
-    SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
+    SourceLocation ToLocation, ToAtStartLoc, ToCategoryNameLoc;
+    if (auto Imp = importSeq(
+        D->getLocation(), D->getAtStartLoc(), D->getCategoryNameLoc()))
+      std::tie(ToLocation, ToAtStartLoc, ToCategoryNameLoc) = *Imp;
+    else
+      return Imp.takeError();
+
     if (GetImportedOrCreateDecl(
             ToImpl, D, Importer.getToContext(), DC,
             Importer.Import(D->getIdentifier()), Category->getClassInterface(),
-            Importer.Import(D->getLocation()),
-            Importer.Import(D->getAtStartLoc()), CategoryNameLoc))
+            ToLocation, ToAtStartLoc, ToCategoryNameLoc))
       return ToImpl;
 
-    DeclContext *LexicalDC = DC;
-    if (D->getDeclContext() != D->getLexicalDeclContext()) {
-      LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
-      if (!LexicalDC)
-        return nullptr;
-
-      ToImpl->setLexicalDeclContext(LexicalDC);
-    }
-
+    ToImpl->setLexicalDeclContext(LexicalDC);
     LexicalDC->addDeclInternal(ToImpl);
     Category->setImplementation(ToImpl);
   }
 
   Importer.MapImported(D, ToImpl);
-  ImportDeclContext(D);
+  if (Error Err = ImportDeclContext(D))
+    return std::move(Err);
+
   return ToImpl;
 }
 
-Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
   // Find the corresponding interface.
-  auto *Iface = cast_or_null<ObjCInterfaceDecl>(
-      Importer.Import(D->getClassInterface()));
-  if (!Iface)
-    return nullptr;
+  ObjCInterfaceDecl *Iface;
+  if (Error Err = importInto(Iface, D->getClassInterface()))
+    return std::move(Err);
 
   // Import the superclass, if any.
-  ObjCInterfaceDecl *Super = nullptr;
-  if (D->getSuperClass()) {
-    Super = cast_or_null<ObjCInterfaceDecl>(
-                                          Importer.Import(D->getSuperClass()));
-    if (!Super)
-      return nullptr;
-  }
+  ObjCInterfaceDecl *Super;
+  if (Error Err = importInto(Super, D->getSuperClass()))
+    return std::move(Err);
 
   ObjCImplementationDecl *Impl = Iface->getImplementation();
   if (!Impl) {
     // We haven't imported an implementation yet. Create a new @implementation
     // now.
+    DeclContext *DC, *LexicalDC;
+    if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+      return std::move(Err);
+
+    SourceLocation ToLocation, ToAtStartLoc, ToSuperClassLoc;
+    SourceLocation ToIvarLBraceLoc, ToIvarRBraceLoc;
+    if (auto Imp = importSeq(
+        D->getLocation(), D->getAtStartLoc(), D->getSuperClassLoc(),
+        D->getIvarLBraceLoc(), D->getIvarRBraceLoc()))
+      std::tie(
+          ToLocation, ToAtStartLoc, ToSuperClassLoc,
+          ToIvarLBraceLoc, ToIvarRBraceLoc) = *Imp;
+    else
+      return Imp.takeError();
+
     if (GetImportedOrCreateDecl(Impl, D, Importer.getToContext(),
-                                Importer.ImportContext(D->getDeclContext()),
-                                Iface, Super, Importer.Import(D->getLocation()),
-                                Importer.Import(D->getAtStartLoc()),
-                                Importer.Import(D->getSuperClassLoc()),
-                                Importer.Import(D->getIvarLBraceLoc()),
-                                Importer.Import(D->getIvarRBraceLoc())))
+                                DC, Iface, Super,
+                                ToLocation,
+                                ToAtStartLoc,
+                                ToSuperClassLoc,
+                                ToIvarLBraceLoc,
+                                ToIvarRBraceLoc))
       return Impl;
 
-    if (D->getDeclContext() != D->getLexicalDeclContext()) {
-      DeclContext *LexicalDC
-        = Importer.ImportContext(D->getLexicalDeclContext());
-      if (!LexicalDC)
-        return nullptr;
-      Impl->setLexicalDeclContext(LexicalDC);
-    }
+    Impl->setLexicalDeclContext(LexicalDC);
 
     // Associate the implementation with the class it implements.
     Iface->setImplementation(Impl);
@@ -4174,24 +4700,26 @@
       else
         Importer.FromDiag(D->getLocation(),
                           diag::note_odr_objc_missing_superclass);
-      return nullptr;
+
+      return make_error<ImportError>(ImportError::NameConflict);
     }
   }
 
   // Import all of the members of this @implementation.
-  ImportDeclContext(D);
+  if (Error Err = ImportDeclContext(D))
+    return std::move(Err);
 
   return Impl;
 }
 
-Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
   // Import the major distinguishing characteristics of an @property.
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -4207,7 +4735,8 @@
           << Name << D->getType() << FoundProp->getType();
         Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
           << FoundProp->getType();
-        return nullptr;
+
+        return make_error<ImportError>(ImportError::NameConflict);
       }
 
       // FIXME: Check property attributes, getters, setters, etc.?
@@ -4218,79 +4747,88 @@
     }
   }
 
-  // Import the type.
-  TypeSourceInfo *TSI = Importer.Import(D->getTypeSourceInfo());
-  if (!TSI)
-    return nullptr;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceLocation ToAtLoc, ToLParenLoc;
+  if (auto Imp = importSeq(
+      D->getType(), D->getTypeSourceInfo(), D->getAtLoc(), D->getLParenLoc()))
+    std::tie(ToType, ToTypeSourceInfo, ToAtLoc, ToLParenLoc) = *Imp;
+  else
+    return Imp.takeError();
 
   // Create the new property.
   ObjCPropertyDecl *ToProperty;
   if (GetImportedOrCreateDecl(
           ToProperty, D, Importer.getToContext(), DC, Loc,
-          Name.getAsIdentifierInfo(), Importer.Import(D->getAtLoc()),
-          Importer.Import(D->getLParenLoc()), Importer.Import(D->getType()),
-          TSI, D->getPropertyImplementation()))
+          Name.getAsIdentifierInfo(), ToAtLoc,
+          ToLParenLoc, ToType,
+          ToTypeSourceInfo, D->getPropertyImplementation()))
     return ToProperty;
 
+  Selector ToGetterName, ToSetterName;
+  SourceLocation ToGetterNameLoc, ToSetterNameLoc;
+  ObjCMethodDecl *ToGetterMethodDecl, *ToSetterMethodDecl;
+  ObjCIvarDecl *ToPropertyIvarDecl;
+  if (auto Imp = importSeq(
+      D->getGetterName(), D->getSetterName(),
+      D->getGetterNameLoc(), D->getSetterNameLoc(),
+      D->getGetterMethodDecl(), D->getSetterMethodDecl(),
+      D->getPropertyIvarDecl()))
+    std::tie(
+        ToGetterName, ToSetterName,
+        ToGetterNameLoc, ToSetterNameLoc,
+        ToGetterMethodDecl, ToSetterMethodDecl,
+        ToPropertyIvarDecl) = *Imp;
+  else
+    return Imp.takeError();
+
   ToProperty->setLexicalDeclContext(LexicalDC);
   LexicalDC->addDeclInternal(ToProperty);
 
   ToProperty->setPropertyAttributes(D->getPropertyAttributes());
   ToProperty->setPropertyAttributesAsWritten(
                                       D->getPropertyAttributesAsWritten());
-  ToProperty->setGetterName(Importer.Import(D->getGetterName()),
-                            Importer.Import(D->getGetterNameLoc()));
-  ToProperty->setSetterName(Importer.Import(D->getSetterName()),
-                            Importer.Import(D->getSetterNameLoc()));
-  ToProperty->setGetterMethodDecl(
-     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
-  ToProperty->setSetterMethodDecl(
-     cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
-  ToProperty->setPropertyIvarDecl(
-       cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
+  ToProperty->setGetterName(ToGetterName, ToGetterNameLoc);
+  ToProperty->setSetterName(ToSetterName, ToSetterNameLoc);
+  ToProperty->setGetterMethodDecl(ToGetterMethodDecl);
+  ToProperty->setSetterMethodDecl(ToSetterMethodDecl);
+  ToProperty->setPropertyIvarDecl(ToPropertyIvarDecl);
   return ToProperty;
 }
 
-Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
-  auto *Property = cast_or_null<ObjCPropertyDecl>(
-      Importer.Import(D->getPropertyDecl()));
-  if (!Property)
-    return nullptr;
+ExpectedDecl
+ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+  ObjCPropertyDecl *Property;
+  if (Error Err = importInto(Property, D->getPropertyDecl()))
+    return std::move(Err);
 
-  DeclContext *DC = Importer.ImportContext(D->getDeclContext());
-  if (!DC)
-    return nullptr;
+  DeclContext *DC, *LexicalDC;
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return std::move(Err);
 
-  // Import the lexical declaration context.
-  DeclContext *LexicalDC = DC;
-  if (D->getDeclContext() != D->getLexicalDeclContext()) {
-    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
-    if (!LexicalDC)
-      return nullptr;
-  }
-
-  auto *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
-  if (!InImpl)
-    return nullptr;
+  auto *InImpl = cast<ObjCImplDecl>(LexicalDC);
 
   // Import the ivar (for an @synthesize).
   ObjCIvarDecl *Ivar = nullptr;
-  if (D->getPropertyIvarDecl()) {
-    Ivar = cast_or_null<ObjCIvarDecl>(
-                                    Importer.Import(D->getPropertyIvarDecl()));
-    if (!Ivar)
-      return nullptr;
-  }
+  if (Error Err = importInto(Ivar, D->getPropertyIvarDecl()))
+    return std::move(Err);
 
   ObjCPropertyImplDecl *ToImpl
     = InImpl->FindPropertyImplDecl(Property->getIdentifier(),
                                    Property->getQueryKind());
   if (!ToImpl) {
+    SourceLocation ToBeginLoc, ToLocation, ToPropertyIvarDeclLoc;
+    if (auto Imp = importSeq(
+        D->getBeginLoc(), D->getLocation(), D->getPropertyIvarDeclLoc()))
+      std::tie(ToBeginLoc, ToLocation, ToPropertyIvarDeclLoc) = *Imp;
+    else
+      return Imp.takeError();
+
     if (GetImportedOrCreateDecl(ToImpl, D, Importer.getToContext(), DC,
-                                Importer.Import(D->getBeginLoc()),
-                                Importer.Import(D->getLocation()), Property,
+                                ToBeginLoc,
+                                ToLocation, Property,
                                 D->getPropertyImplementation(), Ivar,
-                                Importer.Import(D->getPropertyIvarDeclLoc())))
+                                ToPropertyIvarDeclLoc))
       return ToImpl;
 
     ToImpl->setLexicalDeclContext(LexicalDC);
@@ -4308,7 +4846,8 @@
                         diag::note_odr_objc_property_impl_kind)
         << D->getPropertyDecl()->getDeclName()
         << (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
-      return nullptr;
+
+      return make_error<ImportError>(ImportError::NameConflict);
     }
 
     // For @synthesize, check that we have the same
@@ -4322,7 +4861,8 @@
       Importer.FromDiag(D->getPropertyIvarDeclLoc(),
                         diag::note_odr_objc_synthesize_ivar_here)
         << D->getPropertyIvarDecl()->getDeclName();
-      return nullptr;
+
+      return make_error<ImportError>(ImportError::NameConflict);
     }
 
     // Merge the existing implementation with the new implementation.
@@ -4332,41 +4872,46 @@
   return ToImpl;
 }
 
-Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
   // For template arguments, we adopt the translation unit as our declaration
   // context. This context will be fixed when the actual template declaration
   // is created.
 
   // FIXME: Import default argument.
+
+  ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+  if (!BeginLocOrErr)
+    return BeginLocOrErr.takeError();
+
+  ExpectedSLoc LocationOrErr = import(D->getLocation());
+  if (!LocationOrErr)
+    return LocationOrErr.takeError();
+
   TemplateTypeParmDecl *ToD = nullptr;
   (void)GetImportedOrCreateDecl(
       ToD, D, Importer.getToContext(),
       Importer.getToContext().getTranslationUnitDecl(),
-      Importer.Import(D->getBeginLoc()), Importer.Import(D->getLocation()),
+      *BeginLocOrErr, *LocationOrErr,
       D->getDepth(), D->getIndex(), Importer.Import(D->getIdentifier()),
       D->wasDeclaredWithTypename(), D->isParameterPack());
   return ToD;
 }
 
-Decl *
+ExpectedDecl
 ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
-  // Import the name of this declaration.
-  DeclarationName Name = Importer.Import(D->getDeclName());
-  if (D->getDeclName() && !Name)
-    return nullptr;
-
-  // Import the location of this declaration.
-  SourceLocation Loc = Importer.Import(D->getLocation());
-
-  // Import the type of this declaration.
-  QualType T = Importer.Import(D->getType());
-  if (T.isNull())
-    return nullptr;
-
-  // Import type-source information.
-  TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-  if (D->getTypeSourceInfo() && !TInfo)
-    return nullptr;
+  DeclarationName ToDeclName;
+  SourceLocation ToLocation, ToInnerLocStart;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  if (auto Imp = importSeq(
+      D->getDeclName(), D->getLocation(), D->getType(), D->getTypeSourceInfo(),
+      D->getInnerLocStart()))
+    std::tie(
+        ToDeclName, ToLocation, ToType, ToTypeSourceInfo,
+        ToInnerLocStart) = *Imp;
+  else
+    return Imp.takeError();
 
   // FIXME: Import default argument.
 
@@ -4374,36 +4919,39 @@
   (void)GetImportedOrCreateDecl(
       ToD, D, Importer.getToContext(),
       Importer.getToContext().getTranslationUnitDecl(),
-      Importer.Import(D->getInnerLocStart()), Loc, D->getDepth(),
-      D->getPosition(), Name.getAsIdentifierInfo(), T, D->isParameterPack(),
-      TInfo);
+      ToInnerLocStart, ToLocation, D->getDepth(),
+      D->getPosition(), ToDeclName.getAsIdentifierInfo(), ToType,
+      D->isParameterPack(), ToTypeSourceInfo);
   return ToD;
 }
 
-Decl *
+ExpectedDecl
 ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
   // Import the name of this declaration.
-  DeclarationName Name = Importer.Import(D->getDeclName());
-  if (D->getDeclName() && !Name)
-    return nullptr;
+  auto NameOrErr = import(D->getDeclName());
+  if (!NameOrErr)
+    return NameOrErr.takeError();
 
   // Import the location of this declaration.
-  SourceLocation Loc = Importer.Import(D->getLocation());
+  ExpectedSLoc LocationOrErr = import(D->getLocation());
+  if (!LocationOrErr)
+    return LocationOrErr.takeError();
 
   // Import template parameters.
-  TemplateParameterList *TemplateParams
-    = ImportTemplateParameterList(D->getTemplateParameters());
-  if (!TemplateParams)
-    return nullptr;
+  auto TemplateParamsOrErr = ImportTemplateParameterList(
+      D->getTemplateParameters());
+  if (!TemplateParamsOrErr)
+    return TemplateParamsOrErr.takeError();
 
   // FIXME: Import default argument.
 
   TemplateTemplateParmDecl *ToD = nullptr;
   (void)GetImportedOrCreateDecl(
       ToD, D, Importer.getToContext(),
-      Importer.getToContext().getTranslationUnitDecl(), Loc, D->getDepth(),
-      D->getPosition(), D->isParameterPack(), Name.getAsIdentifierInfo(),
-      TemplateParams);
+      Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr,
+      D->getDepth(), D->getPosition(), D->isParameterPack(),
+      (*NameOrErr).getAsIdentifierInfo(),
+      *TemplateParamsOrErr);
   return ToD;
 }
 
@@ -4418,7 +4966,7 @@
   return TemplateWithDef;
 }
 
-Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
   bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
 
   // If this record has a definition in the translation unit we're coming from,
@@ -4427,12 +4975,11 @@
   auto *Definition =
       cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
   if (Definition && Definition != D->getTemplatedDecl() && !IsFriend) {
-    Decl *ImportedDef
-      = Importer.Import(Definition->getDescribedClassTemplate());
-    if (!ImportedDef)
-      return nullptr;
-
-    return Importer.MapImported(D, ImportedDef);
+    if (ExpectedDecl ImportedDefOrErr = import(
+        Definition->getDescribedClassTemplate()))
+      return Importer.MapImported(D, *ImportedDefOrErr);
+    else
+      return ImportedDefOrErr.takeError();
   }
 
   // Import the major distinguishing characteristics of this class template.
@@ -4440,8 +4987,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -4490,26 +5037,25 @@
     }
 
     if (!Name)
-      return nullptr;
+      return make_error<ImportError>(ImportError::NameConflict);
   }
 
   CXXRecordDecl *FromTemplated = D->getTemplatedDecl();
 
   // Create the declaration that is being templated.
-  auto *ToTemplated = cast_or_null<CXXRecordDecl>(
-      Importer.Import(FromTemplated));
-  if (!ToTemplated)
-    return nullptr;
+  CXXRecordDecl *ToTemplated;
+  if (Error Err = importInto(ToTemplated, FromTemplated))
+    return std::move(Err);
 
   // Create the class template declaration itself.
-  TemplateParameterList *TemplateParams =
-      ImportTemplateParameterList(D->getTemplateParameters());
-  if (!TemplateParams)
-    return nullptr;
+  auto TemplateParamsOrErr = ImportTemplateParameterList(
+      D->getTemplateParameters());
+  if (!TemplateParamsOrErr)
+    return TemplateParamsOrErr.takeError();
 
   ClassTemplateDecl *D2;
   if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name,
-                              TemplateParams, ToTemplated))
+                              *TemplateParamsOrErr, ToTemplated))
     return D2;
 
   ToTemplated->setDescribedClassTemplate(D2);
@@ -4534,48 +5080,33 @@
   return D2;
 }
 
-Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
+ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
                                           ClassTemplateSpecializationDecl *D) {
   // If this record has a definition in the translation unit we're coming from,
   // but this particular declaration is not that definition, import the
   // definition and map to that.
   TagDecl *Definition = D->getDefinition();
   if (Definition && Definition != D) {
-    Decl *ImportedDef = Importer.Import(Definition);
-    if (!ImportedDef)
-      return nullptr;
-
-    return Importer.MapImported(D, ImportedDef);
+    if (ExpectedDecl ImportedDefOrErr = import(Definition))
+      return Importer.MapImported(D, *ImportedDefOrErr);
+    else
+      return ImportedDefOrErr.takeError();
   }
 
-  auto *ClassTemplate =
-      cast_or_null<ClassTemplateDecl>(Importer.Import(
-                                                 D->getSpecializedTemplate()));
-  if (!ClassTemplate)
-    return nullptr;
+  ClassTemplateDecl *ClassTemplate;
+  if (Error Err = importInto(ClassTemplate, D->getSpecializedTemplate()))
+    return std::move(Err);
 
   // Import the context of this declaration.
-  DeclContext *DC = ClassTemplate->getDeclContext();
-  if (!DC)
-    return nullptr;
-
-  DeclContext *LexicalDC = DC;
-  if (D->getDeclContext() != D->getLexicalDeclContext()) {
-    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
-    if (!LexicalDC)
-      return nullptr;
-  }
-
-  // Import the location of this declaration.
-  SourceLocation StartLoc = Importer.Import(D->getBeginLoc());
-  SourceLocation IdLoc = Importer.Import(D->getLocation());
+  DeclContext *DC, *LexicalDC;
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return std::move(Err);
 
   // Import template arguments.
   SmallVector<TemplateArgument, 2> TemplateArgs;
-  if (ImportTemplateArguments(D->getTemplateArgs().data(),
-                              D->getTemplateArgs().size(),
-                              TemplateArgs))
-    return nullptr;
+  if (Error Err = ImportTemplateArguments(
+      D->getTemplateArgs().data(), D->getTemplateArgs().size(), TemplateArgs))
+    return std::move(Err);
 
   // Try to find an existing specialization with these template arguments.
   void *InsertPos = nullptr;
@@ -4602,13 +5133,21 @@
 
       // Import those those default field initializers which have been
       // instantiated in the "From" context, but not in the "To" context.
-      for (auto *FromField : D->fields())
-        Importer.Import(FromField);
+      for (auto *FromField : D->fields()) {
+        auto ToOrErr = import(FromField);
+        if (!ToOrErr)
+          // FIXME: return the error?
+          consumeError(ToOrErr.takeError());
+      }
 
       // Import those methods which have been instantiated in the
       // "From" context, but not in the "To" context.
-      for (CXXMethodDecl *FromM : D->methods())
-        Importer.Import(FromM);
+      for (CXXMethodDecl *FromM : D->methods()) {
+        auto ToOrErr = import(FromM);
+        if (!ToOrErr)
+          // FIXME: return the error?
+          consumeError(ToOrErr.takeError());
+      }
 
       // TODO Import instantiated default arguments.
       // TODO Import instantiated exception specifications.
@@ -4621,27 +5160,36 @@
   } else { // We either couldn't find any previous specialization in the "To"
            // context,  or we found one but without definition.  Let's create a
            // new specialization and register that at the class template.
+
+    // Import the location of this declaration.
+    ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+    if (!BeginLocOrErr)
+      return BeginLocOrErr.takeError();
+    ExpectedSLoc IdLocOrErr = import(D->getLocation());
+    if (!IdLocOrErr)
+      return IdLocOrErr.takeError();
+
     if (PartialSpec) {
       // Import TemplateArgumentListInfo.
       TemplateArgumentListInfo ToTAInfo;
       const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
-      if (ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
-        return nullptr;
+      if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
+        return std::move(Err);
 
-      QualType CanonInjType = Importer.Import(
-            PartialSpec->getInjectedSpecializationType());
-      if (CanonInjType.isNull())
-        return nullptr;
+      QualType CanonInjType;
+      if (Error Err = importInto(
+          CanonInjType, PartialSpec->getInjectedSpecializationType()))
+        return std::move(Err);
       CanonInjType = CanonInjType.getCanonicalType();
 
-      TemplateParameterList *ToTPList = ImportTemplateParameterList(
-            PartialSpec->getTemplateParameters());
-      if (!ToTPList && PartialSpec->getTemplateParameters())
-        return nullptr;
+      auto ToTPListOrErr = ImportTemplateParameterList(
+          PartialSpec->getTemplateParameters());
+      if (!ToTPListOrErr)
+        return ToTPListOrErr.takeError();
 
       if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
-              D2, D, Importer.getToContext(), D->getTagKind(), DC, StartLoc,
-              IdLoc, ToTPList, ClassTemplate,
+              D2, D, Importer.getToContext(), D->getTagKind(), DC,
+              *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
               llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
               ToTAInfo, CanonInjType,
               cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
@@ -4656,8 +5204,9 @@
 
     } else { // Not a partial specialization.
       if (GetImportedOrCreateDecl(
-              D2, D, Importer.getToContext(), D->getTagKind(), DC, StartLoc,
-              IdLoc, ClassTemplate, TemplateArgs, PrevDecl))
+              D2, D, Importer.getToContext(), D->getTagKind(), DC,
+              *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
+              PrevDecl))
         return D2;
 
       // Update InsertPos, because preceding import calls may have invalidated
@@ -4670,22 +5219,34 @@
     D2->setSpecializationKind(D->getSpecializationKind());
 
     // Import the qualifier, if any.
-    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+    if (auto LocOrErr = import(D->getQualifierLoc()))
+      D2->setQualifierInfo(*LocOrErr);
+    else
+      return LocOrErr.takeError();
 
     if (auto *TSI = D->getTypeAsWritten()) {
-      TypeSourceInfo *TInfo = Importer.Import(TSI);
-      if (!TInfo)
-        return nullptr;
-      D2->setTypeAsWritten(TInfo);
-      D2->setTemplateKeywordLoc(Importer.Import(D->getTemplateKeywordLoc()));
-      D2->setExternLoc(Importer.Import(D->getExternLoc()));
+      if (auto TInfoOrErr = import(TSI))
+        D2->setTypeAsWritten(*TInfoOrErr);
+      else
+        return TInfoOrErr.takeError();
+
+      if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
+        D2->setTemplateKeywordLoc(*LocOrErr);
+      else
+        return LocOrErr.takeError();
+
+      if (auto LocOrErr = import(D->getExternLoc()))
+        D2->setExternLoc(*LocOrErr);
+      else
+        return LocOrErr.takeError();
     }
 
-    SourceLocation POI = Importer.Import(D->getPointOfInstantiation());
-    if (POI.isValid())
-      D2->setPointOfInstantiation(POI);
-    else if (D->getPointOfInstantiation().isValid())
-      return nullptr;
+    if (D->getPointOfInstantiation().isValid()) {
+      if (auto POIOrErr = import(D->getPointOfInstantiation()))
+        D2->setPointOfInstantiation(*POIOrErr);
+      else
+        return POIOrErr.takeError();
+    }
 
     D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
 
@@ -4697,13 +5258,14 @@
       LexicalDC->addDeclInternal(D2);
     }
   }
-  if (D->isCompleteDefinition() && ImportDefinition(D, D2))
-    return nullptr;
+  if (D->isCompleteDefinition())
+    if (Error Err = ImportDefinition(D, D2))
+      return std::move(Err);
 
   return D2;
 }
 
-Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
   // If this variable has a definition in the translation unit we're coming
   // from,
   // but this particular declaration is not that definition, import the
@@ -4711,11 +5273,11 @@
   auto *Definition =
       cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
   if (Definition && Definition != D->getTemplatedDecl()) {
-    Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
-    if (!ImportedDef)
-      return nullptr;
-
-    return Importer.MapImported(D, ImportedDef);
+    if (ExpectedDecl ImportedDefOrErr = import(
+        Definition->getDescribedVarTemplate()))
+      return Importer.MapImported(D, *ImportedDefOrErr);
+    else
+      return ImportedDefOrErr.takeError();
   }
 
   // Import the major distinguishing characteristics of this variable template.
@@ -4723,8 +5285,8 @@
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
   if (ToD)
     return ToD;
 
@@ -4739,7 +5301,7 @@
       continue;
 
     Decl *Found = FoundDecl;
-    if (auto *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
+    if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
       if (IsStructuralMatch(D, FoundTemplate)) {
         // The variable templates structurally match; call it the same template.
         Importer.MapImported(D->getTemplatedDecl(),
@@ -4758,29 +5320,32 @@
   }
 
   if (!Name)
-    return nullptr;
+    // FIXME: Is it possible to get other error than name conflict?
+    // (Put this `if` into the previous `if`?)
+    return make_error<ImportError>(ImportError::NameConflict);
 
   VarDecl *DTemplated = D->getTemplatedDecl();
 
   // Import the type.
-  QualType T = Importer.Import(DTemplated->getType());
-  if (T.isNull())
-    return nullptr;
+  // FIXME: Value not used?
+  ExpectedType TypeOrErr = import(DTemplated->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
 
   // Create the declaration that is being templated.
-  auto *ToTemplated = dyn_cast_or_null<VarDecl>(Importer.Import(DTemplated));
-  if (!ToTemplated)
-    return nullptr;
+  VarDecl *ToTemplated;
+  if (Error Err = importInto(ToTemplated, DTemplated))
+    return std::move(Err);
 
   // Create the variable template declaration itself.
-  TemplateParameterList *TemplateParams =
-      ImportTemplateParameterList(D->getTemplateParameters());
-  if (!TemplateParams)
-    return nullptr;
+  auto TemplateParamsOrErr = ImportTemplateParameterList(
+      D->getTemplateParameters());
+  if (!TemplateParamsOrErr)
+    return TemplateParamsOrErr.takeError();
 
   VarTemplateDecl *ToVarTD;
   if (GetImportedOrCreateDecl(ToVarTD, D, Importer.getToContext(), DC, Loc,
-                              Name, TemplateParams, ToTemplated))
+                              Name, *TemplateParamsOrErr, ToTemplated))
     return ToVarTD;
 
   ToTemplated->setDescribedVarTemplate(ToVarTD);
@@ -4797,46 +5362,42 @@
   return ToVarTD;
 }
 
-Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
+ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
     VarTemplateSpecializationDecl *D) {
   // If this record has a definition in the translation unit we're coming from,
   // but this particular declaration is not that definition, import the
   // definition and map to that.
   VarDecl *Definition = D->getDefinition();
   if (Definition && Definition != D) {
-    Decl *ImportedDef = Importer.Import(Definition);
-    if (!ImportedDef)
-      return nullptr;
-
-    return Importer.MapImported(D, ImportedDef);
+    if (ExpectedDecl ImportedDefOrErr = import(Definition))
+      return Importer.MapImported(D, *ImportedDefOrErr);
+    else
+      return ImportedDefOrErr.takeError();
   }
 
-  auto *VarTemplate = cast_or_null<VarTemplateDecl>(
-      Importer.Import(D->getSpecializedTemplate()));
-  if (!VarTemplate)
-    return nullptr;
+  VarTemplateDecl *VarTemplate;
+  if (Error Err = importInto(VarTemplate, D->getSpecializedTemplate()))
+    return std::move(Err);
 
   // Import the context of this declaration.
-  DeclContext *DC = VarTemplate->getDeclContext();
-  if (!DC)
-    return nullptr;
-
-  DeclContext *LexicalDC = DC;
-  if (D->getDeclContext() != D->getLexicalDeclContext()) {
-    LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
-    if (!LexicalDC)
-      return nullptr;
-  }
+  DeclContext *DC, *LexicalDC;
+  if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+    return std::move(Err);
 
   // Import the location of this declaration.
-  SourceLocation StartLoc = Importer.Import(D->getBeginLoc());
-  SourceLocation IdLoc = Importer.Import(D->getLocation());
+  ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+  if (!BeginLocOrErr)
+    return BeginLocOrErr.takeError();
+
+  auto IdLocOrErr = import(D->getLocation());
+  if (!IdLocOrErr)
+    return IdLocOrErr.takeError();
 
   // Import template arguments.
   SmallVector<TemplateArgument, 2> TemplateArgs;
-  if (ImportTemplateArguments(D->getTemplateArgs().data(),
-                              D->getTemplateArgs().size(), TemplateArgs))
-    return nullptr;
+  if (Error Err = ImportTemplateArguments(
+      D->getTemplateArgs().data(), D->getTemplateArgs().size(), TemplateArgs))
+    return std::move(Err);
 
   // Try to find an existing specialization with these template arguments.
   void *InsertPos = nullptr;
@@ -4859,17 +5420,18 @@
     }
   } else {
     // Import the type.
-    QualType T = Importer.Import(D->getType());
-    if (T.isNull())
-      return nullptr;
+    QualType T;
+    if (Error Err = importInto(T, D->getType()))
+      return std::move(Err);
 
-    TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-    if (D->getTypeSourceInfo() && !TInfo)
-      return nullptr;
+    auto TInfoOrErr = import(D->getTypeSourceInfo());
+    if (!TInfoOrErr)
+      return TInfoOrErr.takeError();
 
     TemplateArgumentListInfo ToTAInfo;
-    if (ImportTemplateArgumentListInfo(D->getTemplateArgsInfo(), ToTAInfo))
-      return nullptr;
+    if (Error Err = ImportTemplateArgumentListInfo(
+        D->getTemplateArgsInfo(), ToTAInfo))
+      return std::move(Err);
 
     using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
     // Create a new specialization.
@@ -4878,41 +5440,47 @@
       TemplateArgumentListInfo ArgInfos;
       const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
       // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
-      if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos))
-        return nullptr;
+      if (Error Err = ImportTemplateArgumentListInfo(
+          *FromTAArgsAsWritten, ArgInfos))
+        return std::move(Err);
 
-      TemplateParameterList *ToTPList = ImportTemplateParameterList(
-            FromPartial->getTemplateParameters());
-      if (!ToTPList)
-        return nullptr;
+      auto ToTPListOrErr = ImportTemplateParameterList(
+          FromPartial->getTemplateParameters());
+      if (!ToTPListOrErr)
+        return ToTPListOrErr.takeError();
 
       PartVarSpecDecl *ToPartial;
       if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
-                                  StartLoc, IdLoc, ToTPList, VarTemplate, T,
-                                  TInfo, D->getStorageClass(), TemplateArgs,
-                                  ArgInfos))
+                                  *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
+                                  VarTemplate, T, *TInfoOrErr,
+                                  D->getStorageClass(), TemplateArgs, ArgInfos))
         return ToPartial;
 
-      auto *FromInst = FromPartial->getInstantiatedFromMember();
-      auto *ToInst = cast_or_null<PartVarSpecDecl>(Importer.Import(FromInst));
-      if (FromInst && !ToInst)
-        return nullptr;
+      if (Expected<PartVarSpecDecl *> ToInstOrErr = import(
+          FromPartial->getInstantiatedFromMember()))
+        ToPartial->setInstantiatedFromMember(*ToInstOrErr);
+      else
+        return ToInstOrErr.takeError();
 
-      ToPartial->setInstantiatedFromMember(ToInst);
       if (FromPartial->isMemberSpecialization())
         ToPartial->setMemberSpecialization();
 
       D2 = ToPartial;
+
     } else { // Full specialization
-      if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, StartLoc,
-                                  IdLoc, VarTemplate, T, TInfo,
+      if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC,
+                                  *BeginLocOrErr, *IdLocOrErr, VarTemplate,
+                                  T, *TInfoOrErr,
                                   D->getStorageClass(), TemplateArgs))
         return D2;
     }
 
-    SourceLocation POI = D->getPointOfInstantiation();
-    if (POI.isValid())
-      D2->setPointOfInstantiation(Importer.Import(POI));
+    if (D->getPointOfInstantiation().isValid()) {
+      if (ExpectedSLoc POIOrErr = import(D->getPointOfInstantiation()))
+        D2->setPointOfInstantiation(*POIOrErr);
+      else
+        return POIOrErr.takeError();
+    }
 
     D2->setSpecializationKind(D->getSpecializationKind());
     D2->setTemplateArgsInfo(ToTAInfo);
@@ -4921,7 +5489,10 @@
     VarTemplate->AddSpecialization(D2, InsertPos);
 
     // Import the qualifier, if any.
-    D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+    if (auto LocOrErr = import(D->getQualifierLoc()))
+      D2->setQualifierInfo(*LocOrErr);
+    else
+      return LocOrErr.takeError();
 
     if (D->isConstexpr())
       D2->setConstexpr(true);
@@ -4933,20 +5504,21 @@
     D2->setAccess(D->getAccess());
   }
 
-  if (ImportInitializer(D, D2))
-    return nullptr;
+  if (Error Err = ImportInitializer(D, D2))
+    return std::move(Err);
 
   return D2;
 }
 
-Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
   DeclContext *DC, *LexicalDC;
   DeclarationName Name;
   SourceLocation Loc;
   NamedDecl *ToD;
 
-  if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
-    return nullptr;
+  if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+    return std::move(Err);
 
   if (ToD)
     return ToD;
@@ -4961,7 +5533,8 @@
       if (!FoundDecl->isInIdentifierNamespace(IDNS))
         continue;
 
-      if (auto *FoundFunction = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
+      if (auto *FoundFunction =
+          dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
         if (FoundFunction->hasExternalFormalLinkage() &&
             D->hasExternalFormalLinkage()) {
           if (IsStructuralMatch(D, FoundFunction)) {
@@ -4971,22 +5544,22 @@
           }
         }
       }
+      // TODO: handle conflicting names
     }
   }
 
-  TemplateParameterList *Params =
-      ImportTemplateParameterList(D->getTemplateParameters());
-  if (!Params)
-    return nullptr;
+  auto ParamsOrErr = ImportTemplateParameterList(
+      D->getTemplateParameters());
+  if (!ParamsOrErr)
+    return ParamsOrErr.takeError();
 
-  auto *TemplatedFD =
-      cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl()));
-  if (!TemplatedFD)
-    return nullptr;
+  FunctionDecl *TemplatedFD;
+  if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl()))
+    return std::move(Err);
 
   FunctionTemplateDecl *ToFunc;
   if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
-                              Params, TemplatedFD))
+                              *ParamsOrErr, TemplatedFD))
     return ToFunc;
 
   TemplatedFD->setDescribedFunctionTemplate(ToFunc);
@@ -5001,2012 +5574,2074 @@
 // Import Statements
 //----------------------------------------------------------------------------
 
-DeclGroupRef ASTNodeImporter::ImportDeclGroup(DeclGroupRef DG) {
-  if (DG.isNull())
-    return DeclGroupRef::Create(Importer.getToContext(), nullptr, 0);
-  size_t NumDecls = DG.end() - DG.begin();
-  SmallVector<Decl *, 1> ToDecls(NumDecls);
-  auto &_Importer = this->Importer;
-  std::transform(DG.begin(), DG.end(), ToDecls.begin(),
-    [&_Importer](Decl *D) -> Decl * {
-      return _Importer.Import(D);
-    });
-  return DeclGroupRef::Create(Importer.getToContext(),
-                              ToDecls.begin(),
-                              NumDecls);
-}
-
-Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
+ExpectedStmt ASTNodeImporter::VisitStmt(Stmt *S) {
   Importer.FromDiag(S->getBeginLoc(), diag::err_unsupported_ast_node)
       << S->getStmtClassName();
-  return nullptr;
+  return make_error<ImportError>(ImportError::UnsupportedConstruct);
 }
 
-Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
+
+ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
   SmallVector<IdentifierInfo *, 4> Names;
   for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
     IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I));
     // ToII is nullptr when no symbolic name is given for output operand
     // see ParseStmtAsm::ParseAsmOperandsOpt
-    if (!ToII && S->getOutputIdentifier(I))
-      return nullptr;
     Names.push_back(ToII);
   }
+
   for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
     IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I));
     // ToII is nullptr when no symbolic name is given for input operand
     // see ParseStmtAsm::ParseAsmOperandsOpt
-    if (!ToII && S->getInputIdentifier(I))
-      return nullptr;
     Names.push_back(ToII);
   }
 
   SmallVector<StringLiteral *, 4> Clobbers;
   for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) {
-    auto *Clobber = cast_or_null<StringLiteral>(
-        Importer.Import(S->getClobberStringLiteral(I)));
-    if (!Clobber)
-      return nullptr;
-    Clobbers.push_back(Clobber);
+    if (auto ClobberOrErr = import(S->getClobberStringLiteral(I)))
+      Clobbers.push_back(*ClobberOrErr);
+    else
+      return ClobberOrErr.takeError();
+
   }
 
   SmallVector<StringLiteral *, 4> Constraints;
   for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
-    auto *Output = cast_or_null<StringLiteral>(
-        Importer.Import(S->getOutputConstraintLiteral(I)));
-    if (!Output)
-      return nullptr;
-    Constraints.push_back(Output);
+    if (auto OutputOrErr = import(S->getOutputConstraintLiteral(I)))
+      Constraints.push_back(*OutputOrErr);
+    else
+      return OutputOrErr.takeError();
   }
 
   for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
-    auto *Input = cast_or_null<StringLiteral>(
-        Importer.Import(S->getInputConstraintLiteral(I)));
-    if (!Input)
-      return nullptr;
-    Constraints.push_back(Input);
+    if (auto InputOrErr = import(S->getInputConstraintLiteral(I)))
+      Constraints.push_back(*InputOrErr);
+    else
+      return InputOrErr.takeError();
   }
 
   SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs());
-  if (ImportContainerChecked(S->outputs(), Exprs))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(S->outputs(), Exprs))
+    return std::move(Err);
 
-  if (ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs()))
-    return nullptr;
+  if (Error Err = ImportArrayChecked(
+      S->inputs(), Exprs.begin() + S->getNumOutputs()))
+    return std::move(Err);
 
-  auto *AsmStr = cast_or_null<StringLiteral>(
-      Importer.Import(S->getAsmString()));
-  if (!AsmStr)
-    return nullptr;
+  ExpectedSLoc AsmLocOrErr = import(S->getAsmLoc());
+  if (!AsmLocOrErr)
+    return AsmLocOrErr.takeError();
+  auto AsmStrOrErr = import(S->getAsmString());
+  if (!AsmStrOrErr)
+    return AsmStrOrErr.takeError();
+  ExpectedSLoc RParenLocOrErr = import(S->getRParenLoc());
+  if (!RParenLocOrErr)
+    return RParenLocOrErr.takeError();
 
   return new (Importer.getToContext()) GCCAsmStmt(
-        Importer.getToContext(),
-        Importer.Import(S->getAsmLoc()),
-        S->isSimple(),
-        S->isVolatile(),
-        S->getNumOutputs(),
-        S->getNumInputs(),
-        Names.data(),
-        Constraints.data(),
-        Exprs.data(),
-        AsmStr,
-        S->getNumClobbers(),
-        Clobbers.data(),
-        Importer.Import(S->getRParenLoc()));
+      Importer.getToContext(),
+      *AsmLocOrErr,
+      S->isSimple(),
+      S->isVolatile(),
+      S->getNumOutputs(),
+      S->getNumInputs(),
+      Names.data(),
+      Constraints.data(),
+      Exprs.data(),
+      *AsmStrOrErr,
+      S->getNumClobbers(),
+      Clobbers.data(),
+      *RParenLocOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
-  DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup());
-  for (auto *ToD : ToDG) {
-    if (!ToD)
-      return nullptr;
-  }
-  SourceLocation ToStartLoc = Importer.Import(S->getBeginLoc());
-  SourceLocation ToEndLoc = Importer.Import(S->getEndLoc());
-  return new (Importer.getToContext()) DeclStmt(ToDG, ToStartLoc, ToEndLoc);
+ExpectedStmt ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
+  auto Imp = importSeq(S->getDeclGroup(), S->getBeginLoc(), S->getEndLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  DeclGroupRef ToDG;
+  SourceLocation ToBeginLoc, ToEndLoc;
+  std::tie(ToDG, ToBeginLoc, ToEndLoc) = *Imp;
+
+  return new (Importer.getToContext()) DeclStmt(ToDG, ToBeginLoc, ToEndLoc);
 }
 
-Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) {
-  SourceLocation ToSemiLoc = Importer.Import(S->getSemiLoc());
-  return new (Importer.getToContext()) NullStmt(ToSemiLoc,
-                                                S->hasLeadingEmptyMacro());
+ExpectedStmt ASTNodeImporter::VisitNullStmt(NullStmt *S) {
+  ExpectedSLoc ToSemiLocOrErr = import(S->getSemiLoc());
+  if (!ToSemiLocOrErr)
+    return ToSemiLocOrErr.takeError();
+  return new (Importer.getToContext()) NullStmt(
+      *ToSemiLocOrErr, S->hasLeadingEmptyMacro());
 }
 
-Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
+ExpectedStmt ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
   SmallVector<Stmt *, 8> ToStmts(S->size());
 
-  if (ImportContainerChecked(S->body(), ToStmts))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(S->body(), ToStmts))
+    return std::move(Err);
 
-  SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
-  SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
-  return CompoundStmt::Create(Importer.getToContext(), ToStmts, ToLBraceLoc,
-                              ToRBraceLoc);
+  ExpectedSLoc ToLBracLocOrErr = import(S->getLBracLoc());
+  if (!ToLBracLocOrErr)
+    return ToLBracLocOrErr.takeError();
+
+  ExpectedSLoc ToRBracLocOrErr = import(S->getRBracLoc());
+  if (!ToRBracLocOrErr)
+    return ToRBracLocOrErr.takeError();
+
+  return CompoundStmt::Create(
+      Importer.getToContext(), ToStmts,
+      *ToLBracLocOrErr, *ToRBracLocOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
-  Expr *ToLHS = Importer.Import(S->getLHS());
-  if (!ToLHS)
-    return nullptr;
-  Expr *ToRHS = Importer.Import(S->getRHS());
-  if (!ToRHS && S->getRHS())
-    return nullptr;
-  Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
-  if (!ToSubStmt && S->getSubStmt())
-    return nullptr;
-  SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc());
-  SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc());
-  SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
-  auto *ToStmt = new (Importer.getToContext())
-      CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc);
+ExpectedStmt ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
+  auto Imp = importSeq(
+      S->getLHS(), S->getRHS(), S->getSubStmt(), S->getCaseLoc(),
+      S->getEllipsisLoc(), S->getColonLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  Expr *ToLHS, *ToRHS;
+  Stmt *ToSubStmt;
+  SourceLocation ToCaseLoc, ToEllipsisLoc, ToColonLoc;
+  std::tie(ToLHS, ToRHS, ToSubStmt, ToCaseLoc, ToEllipsisLoc, ToColonLoc) =
+      *Imp;
+
+  auto *ToStmt = new (Importer.getToContext()) CaseStmt(
+      ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc);
   ToStmt->setSubStmt(ToSubStmt);
+
   return ToStmt;
 }
 
-Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
-  SourceLocation ToDefaultLoc = Importer.Import(S->getDefaultLoc());
-  SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
-  Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
-  if (!ToSubStmt && S->getSubStmt())
-    return nullptr;
-  return new (Importer.getToContext()) DefaultStmt(ToDefaultLoc, ToColonLoc,
-                                                   ToSubStmt);
+ExpectedStmt ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
+  auto Imp = importSeq(S->getDefaultLoc(), S->getColonLoc(), S->getSubStmt());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToDefaultLoc, ToColonLoc;
+  Stmt *ToSubStmt;
+  std::tie(ToDefaultLoc, ToColonLoc, ToSubStmt) = *Imp;
+
+  return new (Importer.getToContext()) DefaultStmt(
+    ToDefaultLoc, ToColonLoc, ToSubStmt);
 }
 
-Stmt *ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
-  SourceLocation ToIdentLoc = Importer.Import(S->getIdentLoc());
-  auto *ToLabelDecl = cast_or_null<LabelDecl>(Importer.Import(S->getDecl()));
-  if (!ToLabelDecl && S->getDecl())
-    return nullptr;
-  Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
-  if (!ToSubStmt && S->getSubStmt())
-    return nullptr;
-  return new (Importer.getToContext()) LabelStmt(ToIdentLoc, ToLabelDecl,
-                                                 ToSubStmt);
+ExpectedStmt ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
+  auto Imp = importSeq(S->getIdentLoc(), S->getDecl(), S->getSubStmt());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToIdentLoc;
+  LabelDecl *ToLabelDecl;
+  Stmt *ToSubStmt;
+  std::tie(ToIdentLoc, ToLabelDecl, ToSubStmt) = *Imp;
+
+  return new (Importer.getToContext()) LabelStmt(
+      ToIdentLoc, ToLabelDecl, ToSubStmt);
 }
 
-Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
-  SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc());
+ExpectedStmt ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
+  ExpectedSLoc ToAttrLocOrErr = import(S->getAttrLoc());
+  if (!ToAttrLocOrErr)
+    return ToAttrLocOrErr.takeError();
   ArrayRef<const Attr*> FromAttrs(S->getAttrs());
   SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size());
-  if (ImportContainerChecked(FromAttrs, ToAttrs))
-    return nullptr;
-  Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
-  if (!ToSubStmt && S->getSubStmt())
-    return nullptr;
-  return AttributedStmt::Create(Importer.getToContext(), ToAttrLoc,
-                                ToAttrs, ToSubStmt);
+  if (Error Err = ImportContainerChecked(FromAttrs, ToAttrs))
+    return std::move(Err);
+  ExpectedStmt ToSubStmtOrErr = import(S->getSubStmt());
+  if (!ToSubStmtOrErr)
+    return ToSubStmtOrErr.takeError();
+
+  return AttributedStmt::Create(
+      Importer.getToContext(), *ToAttrLocOrErr, ToAttrs, *ToSubStmtOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitIfStmt(IfStmt *S) {
-  SourceLocation ToIfLoc = Importer.Import(S->getIfLoc());
-  Stmt *ToInit = Importer.Import(S->getInit());
-  if (!ToInit && S->getInit())
-    return nullptr;
-  VarDecl *ToConditionVariable = nullptr;
-  if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
-    ToConditionVariable =
-      dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
-    if (!ToConditionVariable)
-      return nullptr;
-  }
-  Expr *ToCondition = Importer.Import(S->getCond());
-  if (!ToCondition && S->getCond())
-    return nullptr;
-  Stmt *ToThenStmt = Importer.Import(S->getThen());
-  if (!ToThenStmt && S->getThen())
-    return nullptr;
-  SourceLocation ToElseLoc = Importer.Import(S->getElseLoc());
-  Stmt *ToElseStmt = Importer.Import(S->getElse());
-  if (!ToElseStmt && S->getElse())
-    return nullptr;
-  return new (Importer.getToContext()) IfStmt(Importer.getToContext(),
-                                              ToIfLoc, S->isConstexpr(),
-                                              ToInit,
-                                              ToConditionVariable,
-                                              ToCondition, ToThenStmt,
-                                              ToElseLoc, ToElseStmt);
+ExpectedStmt ASTNodeImporter::VisitIfStmt(IfStmt *S) {
+  auto Imp = importSeq(
+      S->getIfLoc(), S->getInit(), S->getConditionVariable(), S->getCond(),
+      S->getThen(), S->getElseLoc(), S->getElse());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToIfLoc, ToElseLoc;
+  Stmt *ToInit, *ToThen, *ToElse;
+  VarDecl *ToConditionVariable;
+  Expr *ToCond;
+  std::tie(
+      ToIfLoc, ToInit, ToConditionVariable, ToCond, ToThen, ToElseLoc, ToElse) =
+          *Imp;
+
+  return new (Importer.getToContext()) IfStmt(
+      Importer.getToContext(),
+      ToIfLoc, S->isConstexpr(), ToInit, ToConditionVariable, ToCond,
+      ToThen, ToElseLoc, ToElse);
 }
 
-Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
-  Stmt *ToInit = Importer.Import(S->getInit());
-  if (!ToInit && S->getInit())
-    return nullptr;
-  VarDecl *ToConditionVariable = nullptr;
-  if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
-    ToConditionVariable =
-      dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
-    if (!ToConditionVariable)
-      return nullptr;
-  }
-  Expr *ToCondition = Importer.Import(S->getCond());
-  if (!ToCondition && S->getCond())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
+  auto Imp = importSeq(
+      S->getInit(), S->getConditionVariable(), S->getCond(),
+      S->getBody(), S->getSwitchLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  Stmt *ToInit, *ToBody;
+  VarDecl *ToConditionVariable;
+  Expr *ToCond;
+  SourceLocation ToSwitchLoc;
+  std::tie(ToInit, ToConditionVariable, ToCond, ToBody, ToSwitchLoc) = *Imp;
+
   auto *ToStmt = new (Importer.getToContext()) SwitchStmt(
-                         Importer.getToContext(), ToInit,
-                         ToConditionVariable, ToCondition);
-  Stmt *ToBody = Importer.Import(S->getBody());
-  if (!ToBody && S->getBody())
-    return nullptr;
+      Importer.getToContext(), ToInit, ToConditionVariable, ToCond);
   ToStmt->setBody(ToBody);
-  ToStmt->setSwitchLoc(Importer.Import(S->getSwitchLoc()));
+  ToStmt->setSwitchLoc(ToSwitchLoc);
+
   // Now we have to re-chain the cases.
   SwitchCase *LastChainedSwitchCase = nullptr;
   for (SwitchCase *SC = S->getSwitchCaseList(); SC != nullptr;
        SC = SC->getNextSwitchCase()) {
-    auto *ToSC = dyn_cast_or_null<SwitchCase>(Importer.Import(SC));
-    if (!ToSC)
-      return nullptr;
+    Expected<SwitchCase *> ToSCOrErr = import(SC);
+    if (!ToSCOrErr)
+      return ToSCOrErr.takeError();
     if (LastChainedSwitchCase)
-      LastChainedSwitchCase->setNextSwitchCase(ToSC);
+      LastChainedSwitchCase->setNextSwitchCase(*ToSCOrErr);
     else
-      ToStmt->setSwitchCaseList(ToSC);
-    LastChainedSwitchCase = ToSC;
+      ToStmt->setSwitchCaseList(*ToSCOrErr);
+    LastChainedSwitchCase = *ToSCOrErr;
   }
+
   return ToStmt;
 }
 
-Stmt *ASTNodeImporter::VisitWhileStmt(WhileStmt *S) {
-  VarDecl *ToConditionVariable = nullptr;
-  if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
-    ToConditionVariable =
-      dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
-    if (!ToConditionVariable)
-      return nullptr;
-  }
-  Expr *ToCondition = Importer.Import(S->getCond());
-  if (!ToCondition && S->getCond())
-    return nullptr;
-  Stmt *ToBody = Importer.Import(S->getBody());
-  if (!ToBody && S->getBody())
-    return nullptr;
-  SourceLocation ToWhileLoc = Importer.Import(S->getWhileLoc());
-  return new (Importer.getToContext()) WhileStmt(Importer.getToContext(),
-                                                 ToConditionVariable,
-                                                 ToCondition, ToBody,
-                                                 ToWhileLoc);
+ExpectedStmt ASTNodeImporter::VisitWhileStmt(WhileStmt *S) {
+  auto Imp = importSeq(
+      S->getConditionVariable(), S->getCond(), S->getBody(), S->getWhileLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  VarDecl *ToConditionVariable;
+  Expr *ToCond;
+  Stmt *ToBody;
+  SourceLocation ToWhileLoc;
+  std::tie(ToConditionVariable, ToCond, ToBody, ToWhileLoc) = *Imp;
+
+  return new (Importer.getToContext()) WhileStmt(
+      Importer.getToContext(),
+      ToConditionVariable, ToCond, ToBody, ToWhileLoc);
 }
 
-Stmt *ASTNodeImporter::VisitDoStmt(DoStmt *S) {
-  Stmt *ToBody = Importer.Import(S->getBody());
-  if (!ToBody && S->getBody())
-    return nullptr;
-  Expr *ToCondition = Importer.Import(S->getCond());
-  if (!ToCondition && S->getCond())
-    return nullptr;
-  SourceLocation ToDoLoc = Importer.Import(S->getDoLoc());
-  SourceLocation ToWhileLoc = Importer.Import(S->getWhileLoc());
-  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
-  return new (Importer.getToContext()) DoStmt(ToBody, ToCondition,
-                                              ToDoLoc, ToWhileLoc,
-                                              ToRParenLoc);
+ExpectedStmt ASTNodeImporter::VisitDoStmt(DoStmt *S) {
+  auto Imp = importSeq(
+      S->getBody(), S->getCond(), S->getDoLoc(), S->getWhileLoc(),
+      S->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  Stmt *ToBody;
+  Expr *ToCond;
+  SourceLocation ToDoLoc, ToWhileLoc, ToRParenLoc;
+  std::tie(ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc) = *Imp;
+
+  return new (Importer.getToContext()) DoStmt(
+      ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc);
 }
 
-Stmt *ASTNodeImporter::VisitForStmt(ForStmt *S) {
-  Stmt *ToInit = Importer.Import(S->getInit());
-  if (!ToInit && S->getInit())
-    return nullptr;
-  Expr *ToCondition = Importer.Import(S->getCond());
-  if (!ToCondition && S->getCond())
-    return nullptr;
-  VarDecl *ToConditionVariable = nullptr;
-  if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
-    ToConditionVariable =
-      dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
-    if (!ToConditionVariable)
-      return nullptr;
-  }
-  Expr *ToInc = Importer.Import(S->getInc());
-  if (!ToInc && S->getInc())
-    return nullptr;
-  Stmt *ToBody = Importer.Import(S->getBody());
-  if (!ToBody && S->getBody())
-    return nullptr;
-  SourceLocation ToForLoc = Importer.Import(S->getForLoc());
-  SourceLocation ToLParenLoc = Importer.Import(S->getLParenLoc());
-  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
-  return new (Importer.getToContext()) ForStmt(Importer.getToContext(),
-                                               ToInit, ToCondition,
-                                               ToConditionVariable,
-                                               ToInc, ToBody,
-                                               ToForLoc, ToLParenLoc,
-                                               ToRParenLoc);
+ExpectedStmt ASTNodeImporter::VisitForStmt(ForStmt *S) {
+  auto Imp = importSeq(
+      S->getInit(), S->getCond(), S->getConditionVariable(), S->getInc(),
+      S->getBody(), S->getForLoc(), S->getLParenLoc(), S->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  Stmt *ToInit;
+  Expr *ToCond, *ToInc;
+  VarDecl *ToConditionVariable;
+  Stmt *ToBody;
+  SourceLocation ToForLoc, ToLParenLoc, ToRParenLoc;
+  std::tie(
+      ToInit, ToCond, ToConditionVariable,  ToInc, ToBody, ToForLoc,
+      ToLParenLoc, ToRParenLoc) = *Imp;
+
+  return new (Importer.getToContext()) ForStmt(
+      Importer.getToContext(),
+      ToInit, ToCond, ToConditionVariable, ToInc, ToBody, ToForLoc, ToLParenLoc,
+      ToRParenLoc);
 }
 
-Stmt *ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
-  LabelDecl *ToLabel = nullptr;
-  if (LabelDecl *FromLabel = S->getLabel()) {
-    ToLabel = dyn_cast_or_null<LabelDecl>(Importer.Import(FromLabel));
-    if (!ToLabel)
-      return nullptr;
-  }
-  SourceLocation ToGotoLoc = Importer.Import(S->getGotoLoc());
-  SourceLocation ToLabelLoc = Importer.Import(S->getLabelLoc());
-  return new (Importer.getToContext()) GotoStmt(ToLabel,
-                                                ToGotoLoc, ToLabelLoc);
+ExpectedStmt ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
+  auto Imp = importSeq(S->getLabel(), S->getGotoLoc(), S->getLabelLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  LabelDecl *ToLabel;
+  SourceLocation ToGotoLoc, ToLabelLoc;
+  std::tie(ToLabel, ToGotoLoc, ToLabelLoc) = *Imp;
+
+  return new (Importer.getToContext()) GotoStmt(
+      ToLabel, ToGotoLoc, ToLabelLoc);
 }
 
-Stmt *ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
-  SourceLocation ToGotoLoc = Importer.Import(S->getGotoLoc());
-  SourceLocation ToStarLoc = Importer.Import(S->getStarLoc());
-  Expr *ToTarget = Importer.Import(S->getTarget());
-  if (!ToTarget && S->getTarget())
-    return nullptr;
-  return new (Importer.getToContext()) IndirectGotoStmt(ToGotoLoc, ToStarLoc,
-                                                        ToTarget);
+ExpectedStmt ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+  auto Imp = importSeq(S->getGotoLoc(), S->getStarLoc(), S->getTarget());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToGotoLoc, ToStarLoc;
+  Expr *ToTarget;
+  std::tie(ToGotoLoc, ToStarLoc, ToTarget) = *Imp;
+
+  return new (Importer.getToContext()) IndirectGotoStmt(
+      ToGotoLoc, ToStarLoc, ToTarget);
 }
 
-Stmt *ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) {
-  SourceLocation ToContinueLoc = Importer.Import(S->getContinueLoc());
-  return new (Importer.getToContext()) ContinueStmt(ToContinueLoc);
+ExpectedStmt ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) {
+  ExpectedSLoc ToContinueLocOrErr = import(S->getContinueLoc());
+  if (!ToContinueLocOrErr)
+    return ToContinueLocOrErr.takeError();
+  return new (Importer.getToContext()) ContinueStmt(*ToContinueLocOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitBreakStmt(BreakStmt *S) {
-  SourceLocation ToBreakLoc = Importer.Import(S->getBreakLoc());
-  return new (Importer.getToContext()) BreakStmt(ToBreakLoc);
+ExpectedStmt ASTNodeImporter::VisitBreakStmt(BreakStmt *S) {
+  auto ToBreakLocOrErr = import(S->getBreakLoc());
+  if (!ToBreakLocOrErr)
+    return ToBreakLocOrErr.takeError();
+  return new (Importer.getToContext()) BreakStmt(*ToBreakLocOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
-  SourceLocation ToRetLoc = Importer.Import(S->getReturnLoc());
-  Expr *ToRetExpr = Importer.Import(S->getRetValue());
-  if (!ToRetExpr && S->getRetValue())
-    return nullptr;
-  auto *NRVOCandidate = const_cast<VarDecl *>(S->getNRVOCandidate());
-  auto *ToNRVOCandidate = cast_or_null<VarDecl>(Importer.Import(NRVOCandidate));
-  if (!ToNRVOCandidate && NRVOCandidate)
-    return nullptr;
-  return new (Importer.getToContext()) ReturnStmt(ToRetLoc, ToRetExpr,
-                                                  ToNRVOCandidate);
+ExpectedStmt ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
+  auto Imp = importSeq(
+      S->getReturnLoc(), S->getRetValue(), S->getNRVOCandidate());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToReturnLoc;
+  Expr *ToRetValue;
+  const VarDecl *ToNRVOCandidate;
+  std::tie(ToReturnLoc, ToRetValue, ToNRVOCandidate) = *Imp;
+
+  return new (Importer.getToContext()) ReturnStmt(
+      ToReturnLoc, ToRetValue, ToNRVOCandidate);
 }
 
-Stmt *ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) {
-  SourceLocation ToCatchLoc = Importer.Import(S->getCatchLoc());
-  VarDecl *ToExceptionDecl = nullptr;
-  if (VarDecl *FromExceptionDecl = S->getExceptionDecl()) {
-    ToExceptionDecl =
-      dyn_cast_or_null<VarDecl>(Importer.Import(FromExceptionDecl));
-    if (!ToExceptionDecl)
-      return nullptr;
-  }
-  Stmt *ToHandlerBlock = Importer.Import(S->getHandlerBlock());
-  if (!ToHandlerBlock && S->getHandlerBlock())
-    return nullptr;
-  return new (Importer.getToContext()) CXXCatchStmt(ToCatchLoc,
-                                                    ToExceptionDecl,
-                                                    ToHandlerBlock);
+ExpectedStmt ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) {
+  auto Imp = importSeq(
+      S->getCatchLoc(), S->getExceptionDecl(), S->getHandlerBlock());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToCatchLoc;
+  VarDecl *ToExceptionDecl;
+  Stmt *ToHandlerBlock;
+  std::tie(ToCatchLoc, ToExceptionDecl, ToHandlerBlock) = *Imp;
+
+  return new (Importer.getToContext()) CXXCatchStmt (
+      ToCatchLoc, ToExceptionDecl, ToHandlerBlock);
 }
 
-Stmt *ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
-  SourceLocation ToTryLoc = Importer.Import(S->getTryLoc());
-  Stmt *ToTryBlock = Importer.Import(S->getTryBlock());
-  if (!ToTryBlock && S->getTryBlock())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
+  ExpectedSLoc ToTryLocOrErr = import(S->getTryLoc());
+  if (!ToTryLocOrErr)
+    return ToTryLocOrErr.takeError();
+
+  ExpectedStmt ToTryBlockOrErr = import(S->getTryBlock());
+  if (!ToTryBlockOrErr)
+    return ToTryBlockOrErr.takeError();
+
   SmallVector<Stmt *, 1> ToHandlers(S->getNumHandlers());
   for (unsigned HI = 0, HE = S->getNumHandlers(); HI != HE; ++HI) {
     CXXCatchStmt *FromHandler = S->getHandler(HI);
-    if (Stmt *ToHandler = Importer.Import(FromHandler))
-      ToHandlers[HI] = ToHandler;
+    if (auto ToHandlerOrErr = import(FromHandler))
+      ToHandlers[HI] = *ToHandlerOrErr;
     else
-      return nullptr;
+      return ToHandlerOrErr.takeError();
   }
-  return CXXTryStmt::Create(Importer.getToContext(), ToTryLoc, ToTryBlock,
-                            ToHandlers);
+
+  return CXXTryStmt::Create(
+      Importer.getToContext(), *ToTryLocOrErr,*ToTryBlockOrErr, ToHandlers);
 }
 
-Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
-  auto *ToInit = dyn_cast_or_null<Stmt>(Importer.Import(S->getInit()));
-  if (!ToInit && S->getInit())
-    return nullptr;
-  auto *ToRange =
-    dyn_cast_or_null<DeclStmt>(Importer.Import(S->getRangeStmt()));
-  if (!ToRange && S->getRangeStmt())
-    return nullptr;
-  auto *ToBegin =
-    dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginStmt()));
-  if (!ToBegin && S->getBeginStmt())
-    return nullptr;
-  auto *ToEnd =
-    dyn_cast_or_null<DeclStmt>(Importer.Import(S->getEndStmt()));
-  if (!ToEnd && S->getEndStmt())
-    return nullptr;
-  Expr *ToCond = Importer.Import(S->getCond());
-  if (!ToCond && S->getCond())
-    return nullptr;
-  Expr *ToInc = Importer.Import(S->getInc());
-  if (!ToInc && S->getInc())
-    return nullptr;
-  auto *ToLoopVar =
-    dyn_cast_or_null<DeclStmt>(Importer.Import(S->getLoopVarStmt()));
-  if (!ToLoopVar && S->getLoopVarStmt())
-    return nullptr;
-  Stmt *ToBody = Importer.Import(S->getBody());
-  if (!ToBody && S->getBody())
-    return nullptr;
-  SourceLocation ToForLoc = Importer.Import(S->getForLoc());
-  SourceLocation ToCoawaitLoc = Importer.Import(S->getCoawaitLoc());
-  SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
-  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
-  return new (Importer.getToContext())
-      CXXForRangeStmt(ToInit, ToRange, ToBegin, ToEnd, ToCond, ToInc, ToLoopVar,
-                      ToBody, ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc);
+ExpectedStmt ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
+  auto Imp1 = importSeq(
+      S->getInit(), S->getRangeStmt(), S->getBeginStmt(), S->getEndStmt(),
+      S->getCond(), S->getInc(), S->getLoopVarStmt(), S->getBody());
+  if (!Imp1)
+    return Imp1.takeError();
+  auto Imp2 = importSeq(
+      S->getForLoc(), S->getCoawaitLoc(), S->getColonLoc(), S->getRParenLoc());
+  if (!Imp2)
+    return Imp2.takeError();
+
+  DeclStmt *ToRangeStmt, *ToBeginStmt, *ToEndStmt, *ToLoopVarStmt;
+  Expr *ToCond, *ToInc;
+  Stmt *ToInit, *ToBody;
+  std::tie(
+      ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
+      ToBody) = *Imp1;
+  SourceLocation ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc;
+  std::tie(ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc) = *Imp2;
+
+  return new (Importer.getToContext()) CXXForRangeStmt(
+      ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
+      ToBody, ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc);
 }
 
-Stmt *ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
-  Stmt *ToElem = Importer.Import(S->getElement());
-  if (!ToElem && S->getElement())
-    return nullptr;
-  Expr *ToCollect = Importer.Import(S->getCollection());
-  if (!ToCollect && S->getCollection())
-    return nullptr;
-  Stmt *ToBody = Importer.Import(S->getBody());
-  if (!ToBody && S->getBody())
-    return nullptr;
-  SourceLocation ToForLoc = Importer.Import(S->getForLoc());
-  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
-  return new (Importer.getToContext()) ObjCForCollectionStmt(ToElem,
-                                                             ToCollect,
-                                                             ToBody, ToForLoc,
+ExpectedStmt
+ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+  auto Imp = importSeq(
+      S->getElement(), S->getCollection(), S->getBody(),
+      S->getForLoc(), S->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  Stmt *ToElement, *ToBody;
+  Expr *ToCollection;
+  SourceLocation ToForLoc, ToRParenLoc;
+  std::tie(ToElement, ToCollection, ToBody, ToForLoc, ToRParenLoc) = *Imp;
+
+  return new (Importer.getToContext()) ObjCForCollectionStmt(ToElement,
+                                                             ToCollection,
+                                                             ToBody,
+                                                             ToForLoc,
                                                              ToRParenLoc);
 }
 
-Stmt *ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
-  SourceLocation ToAtCatchLoc = Importer.Import(S->getAtCatchLoc());
-  SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
-  VarDecl *ToExceptionDecl = nullptr;
-  if (VarDecl *FromExceptionDecl = S->getCatchParamDecl()) {
-    ToExceptionDecl =
-      dyn_cast_or_null<VarDecl>(Importer.Import(FromExceptionDecl));
-    if (!ToExceptionDecl)
-      return nullptr;
-  }
-  Stmt *ToBody = Importer.Import(S->getCatchBody());
-  if (!ToBody && S->getCatchBody())
-    return nullptr;
-  return new (Importer.getToContext()) ObjCAtCatchStmt(ToAtCatchLoc,
-                                                       ToRParenLoc,
-                                                       ToExceptionDecl,
-                                                       ToBody);
+ExpectedStmt ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+  auto Imp = importSeq(
+      S->getAtCatchLoc(), S->getRParenLoc(), S->getCatchParamDecl(),
+      S->getCatchBody());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToAtCatchLoc, ToRParenLoc;
+  VarDecl *ToCatchParamDecl;
+  Stmt *ToCatchBody;
+  std::tie(ToAtCatchLoc, ToRParenLoc, ToCatchParamDecl, ToCatchBody) = *Imp;
+
+  return new (Importer.getToContext()) ObjCAtCatchStmt (
+      ToAtCatchLoc, ToRParenLoc, ToCatchParamDecl, ToCatchBody);
 }
 
-Stmt *ASTNodeImporter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
-  SourceLocation ToAtFinallyLoc = Importer.Import(S->getAtFinallyLoc());
-  Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyBody());
-  if (!ToAtFinallyStmt && S->getFinallyBody())
-    return nullptr;
-  return new (Importer.getToContext()) ObjCAtFinallyStmt(ToAtFinallyLoc,
-                                                         ToAtFinallyStmt);
+ExpectedStmt ASTNodeImporter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+  ExpectedSLoc ToAtFinallyLocOrErr = import(S->getAtFinallyLoc());
+  if (!ToAtFinallyLocOrErr)
+    return ToAtFinallyLocOrErr.takeError();
+  ExpectedStmt ToAtFinallyStmtOrErr = import(S->getFinallyBody());
+  if (!ToAtFinallyStmtOrErr)
+    return ToAtFinallyStmtOrErr.takeError();
+  return new (Importer.getToContext()) ObjCAtFinallyStmt(*ToAtFinallyLocOrErr,
+                                                         *ToAtFinallyStmtOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
-  SourceLocation ToAtTryLoc = Importer.Import(S->getAtTryLoc());
-  Stmt *ToAtTryStmt = Importer.Import(S->getTryBody());
-  if (!ToAtTryStmt && S->getTryBody())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+  auto Imp = importSeq(
+      S->getAtTryLoc(), S->getTryBody(), S->getFinallyStmt());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToAtTryLoc;
+  Stmt *ToTryBody, *ToFinallyStmt;
+  std::tie(ToAtTryLoc, ToTryBody, ToFinallyStmt) = *Imp;
+
   SmallVector<Stmt *, 1> ToCatchStmts(S->getNumCatchStmts());
   for (unsigned CI = 0, CE = S->getNumCatchStmts(); CI != CE; ++CI) {
     ObjCAtCatchStmt *FromCatchStmt = S->getCatchStmt(CI);
-    if (Stmt *ToCatchStmt = Importer.Import(FromCatchStmt))
-      ToCatchStmts[CI] = ToCatchStmt;
+    if (ExpectedStmt ToCatchStmtOrErr = import(FromCatchStmt))
+      ToCatchStmts[CI] = *ToCatchStmtOrErr;
     else
-      return nullptr;
+      return ToCatchStmtOrErr.takeError();
   }
-  Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyStmt());
-  if (!ToAtFinallyStmt && S->getFinallyStmt())
-    return nullptr;
+
   return ObjCAtTryStmt::Create(Importer.getToContext(),
-                               ToAtTryLoc, ToAtTryStmt,
+                               ToAtTryLoc, ToTryBody,
                                ToCatchStmts.begin(), ToCatchStmts.size(),
-                               ToAtFinallyStmt);
+                               ToFinallyStmt);
 }
 
-Stmt *ASTNodeImporter::VisitObjCAtSynchronizedStmt
+ExpectedStmt ASTNodeImporter::VisitObjCAtSynchronizedStmt
   (ObjCAtSynchronizedStmt *S) {
-  SourceLocation ToAtSynchronizedLoc =
-    Importer.Import(S->getAtSynchronizedLoc());
-  Expr *ToSynchExpr = Importer.Import(S->getSynchExpr());
-  if (!ToSynchExpr && S->getSynchExpr())
-    return nullptr;
-  Stmt *ToSynchBody = Importer.Import(S->getSynchBody());
-  if (!ToSynchBody && S->getSynchBody())
-    return nullptr;
+  auto Imp = importSeq(
+      S->getAtSynchronizedLoc(), S->getSynchExpr(), S->getSynchBody());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToAtSynchronizedLoc;
+  Expr *ToSynchExpr;
+  Stmt *ToSynchBody;
+  std::tie(ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody) = *Imp;
+
   return new (Importer.getToContext()) ObjCAtSynchronizedStmt(
     ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody);
 }
 
-Stmt *ASTNodeImporter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
-  SourceLocation ToAtThrowLoc = Importer.Import(S->getThrowLoc());
-  Expr *ToThrow = Importer.Import(S->getThrowExpr());
-  if (!ToThrow && S->getThrowExpr())
-    return nullptr;
-  return new (Importer.getToContext()) ObjCAtThrowStmt(ToAtThrowLoc, ToThrow);
+ExpectedStmt ASTNodeImporter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+  ExpectedSLoc ToThrowLocOrErr = import(S->getThrowLoc());
+  if (!ToThrowLocOrErr)
+    return ToThrowLocOrErr.takeError();
+  ExpectedExpr ToThrowExprOrErr = import(S->getThrowExpr());
+  if (!ToThrowExprOrErr)
+    return ToThrowExprOrErr.takeError();
+  return new (Importer.getToContext()) ObjCAtThrowStmt(
+      *ToThrowLocOrErr, *ToThrowExprOrErr);
 }
 
-Stmt *ASTNodeImporter::VisitObjCAutoreleasePoolStmt
-  (ObjCAutoreleasePoolStmt *S) {
-  SourceLocation ToAtLoc = Importer.Import(S->getAtLoc());
-  Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
-  if (!ToSubStmt && S->getSubStmt())
-    return nullptr;
-  return new (Importer.getToContext()) ObjCAutoreleasePoolStmt(ToAtLoc,
-                                                               ToSubStmt);
+ExpectedStmt ASTNodeImporter::VisitObjCAutoreleasePoolStmt(
+    ObjCAutoreleasePoolStmt *S) {
+  ExpectedSLoc ToAtLocOrErr = import(S->getAtLoc());
+  if (!ToAtLocOrErr)
+    return ToAtLocOrErr.takeError();
+  ExpectedStmt ToSubStmtOrErr = import(S->getSubStmt());
+  if (!ToSubStmtOrErr)
+    return ToSubStmtOrErr.takeError();
+  return new (Importer.getToContext()) ObjCAutoreleasePoolStmt(*ToAtLocOrErr,
+                                                               *ToSubStmtOrErr);
 }
 
 //----------------------------------------------------------------------------
 // Import Expressions
 //----------------------------------------------------------------------------
-Expr *ASTNodeImporter::VisitExpr(Expr *E) {
+ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) {
   Importer.FromDiag(E->getBeginLoc(), diag::err_unsupported_ast_node)
       << E->getStmtClassName();
-  return nullptr;
+  return make_error<ImportError>(ImportError::UnsupportedConstruct);
 }
 
-Expr *ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
+  auto Imp = importSeq(
+      E->getBuiltinLoc(), E->getSubExpr(), E->getWrittenTypeInfo(),
+      E->getRParenLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr && E->getSubExpr())
-    return nullptr;
-
-  TypeSourceInfo *TInfo = Importer.Import(E->getWrittenTypeInfo());
-  if (!TInfo)
-    return nullptr;
+  SourceLocation ToBuiltinLoc, ToRParenLoc;
+  Expr *ToSubExpr;
+  TypeSourceInfo *ToWrittenTypeInfo;
+  QualType ToType;
+  std::tie(ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType) =
+      *Imp;
 
   return new (Importer.getToContext()) VAArgExpr(
-        Importer.Import(E->getBuiltinLoc()), SubExpr, TInfo,
-        Importer.Import(E->getRParenLoc()), T, E->isMicrosoftABI());
+      ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType,
+      E->isMicrosoftABI());
 }
 
-Expr *ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
 
-  return new (Importer.getToContext())
-      GNUNullExpr(T, Importer.Import(E->getBeginLoc()));
+ExpectedStmt ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
+  ExpectedType TypeOrErr = import(E->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
+
+  ExpectedSLoc BeginLocOrErr = import(E->getBeginLoc());
+  if (!BeginLocOrErr)
+    return BeginLocOrErr.takeError();
+
+  return new (Importer.getToContext()) GNUNullExpr(*TypeOrErr, *BeginLocOrErr);
 }
 
-Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
+  auto Imp = importSeq(
+      E->getBeginLoc(), E->getType(), E->getFunctionName());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *SL = cast_or_null<StringLiteral>(Importer.Import(E->getFunctionName()));
-  if (!SL && E->getFunctionName())
-    return nullptr;
+  SourceLocation ToBeginLoc;
+  QualType ToType;
+  StringLiteral *ToFunctionName;
+  std::tie(ToBeginLoc, ToType, ToFunctionName) = *Imp;
 
   return new (Importer.getToContext()) PredefinedExpr(
-      Importer.Import(E->getBeginLoc()), T, E->getIdentType(), SL);
+      ToBeginLoc, ToType, E->getIdentType(), ToFunctionName);
 }
 
-Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
-  auto *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
-  if (!ToD)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
+  auto Imp = importSeq(
+      E->getQualifierLoc(), E->getTemplateKeywordLoc(), E->getDecl(),
+      E->getLocation(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  NamedDecl *FoundD = nullptr;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  SourceLocation ToTemplateKeywordLoc, ToLocation;
+  ValueDecl *ToDecl;
+  QualType ToType;
+  std::tie(ToQualifierLoc, ToTemplateKeywordLoc, ToDecl, ToLocation, ToType) =
+      *Imp;
+
+  NamedDecl *ToFoundD = nullptr;
   if (E->getDecl() != E->getFoundDecl()) {
-    FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
-    if (!FoundD)
-      return nullptr;
+    auto FoundDOrErr = import(E->getFoundDecl());
+    if (!FoundDOrErr)
+      return FoundDOrErr.takeError();
+    ToFoundD = *FoundDOrErr;
   }
 
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
   TemplateArgumentListInfo ToTAInfo;
-  TemplateArgumentListInfo *ResInfo = nullptr;
+  TemplateArgumentListInfo *ToResInfo = nullptr;
   if (E->hasExplicitTemplateArgs()) {
-    if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
-      return nullptr;
-    ResInfo = &ToTAInfo;
+    if (Error Err =
+        ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+      return std::move(Err);
+    ToResInfo = &ToTAInfo;
   }
 
-  DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
-                                         Importer.Import(E->getQualifierLoc()),
-                                   Importer.Import(E->getTemplateKeywordLoc()),
-                                         ToD,
-                                        E->refersToEnclosingVariableOrCapture(),
-                                         Importer.Import(E->getLocation()),
-                                         T, E->getValueKind(),
-                                         FoundD, ResInfo);
+  auto *ToE = DeclRefExpr::Create(
+      Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl,
+      E->refersToEnclosingVariableOrCapture(), ToLocation, ToType,
+      E->getValueKind(), ToFoundD, ToResInfo);
   if (E->hadMultipleCandidates())
-    DRE->setHadMultipleCandidates(true);
-  return DRE;
+    ToE->setHadMultipleCandidates(true);
+  return ToE;
 }
 
-Expr *ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  ExpectedType TypeOrErr = import(E->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
 
-  return new (Importer.getToContext()) ImplicitValueInitExpr(T);
+  return new (Importer.getToContext()) ImplicitValueInitExpr(*TypeOrErr);
 }
 
-ASTNodeImporter::Designator
-ASTNodeImporter::ImportDesignator(const Designator &D) {
-  if (D.isFieldDesignator()) {
-    IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName());
-    // Caller checks for import error
-    return Designator(ToFieldName, Importer.Import(D.getDotLoc()),
-                      Importer.Import(D.getFieldLoc()));
-  }
-  if (D.isArrayDesignator())
-    return Designator(D.getFirstExprIndex(),
-                      Importer.Import(D.getLBracketLoc()),
-                      Importer.Import(D.getRBracketLoc()));
+ExpectedStmt ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  ExpectedExpr ToInitOrErr = import(E->getInit());
+  if (!ToInitOrErr)
+    return ToInitOrErr.takeError();
 
-  assert(D.isArrayRangeDesignator());
-  return Designator(D.getFirstExprIndex(),
-                    Importer.Import(D.getLBracketLoc()),
-                    Importer.Import(D.getEllipsisLoc()),
-                    Importer.Import(D.getRBracketLoc()));
-}
+  ExpectedSLoc ToEqualOrColonLocOrErr = import(E->getEqualOrColonLoc());
+  if (!ToEqualOrColonLocOrErr)
+    return ToEqualOrColonLocOrErr.takeError();
 
-
-Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) {
-  auto *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit()));
-  if (!Init)
-    return nullptr;
-
-  SmallVector<Expr *, 4> IndexExprs(DIE->getNumSubExprs() - 1);
+  SmallVector<Expr *, 4> ToIndexExprs(E->getNumSubExprs() - 1);
   // List elements from the second, the first is Init itself
-  for (unsigned I = 1, E = DIE->getNumSubExprs(); I < E; I++) {
-    if (auto *Arg = cast_or_null<Expr>(Importer.Import(DIE->getSubExpr(I))))
-      IndexExprs[I - 1] = Arg;
+  for (unsigned I = 1, N = E->getNumSubExprs(); I < N; I++) {
+    if (ExpectedExpr ToArgOrErr = import(E->getSubExpr(I)))
+      ToIndexExprs[I - 1] = *ToArgOrErr;
     else
-      return nullptr;
+      return ToArgOrErr.takeError();
   }
 
-  SmallVector<Designator, 4> Designators(DIE->size());
-  llvm::transform(DIE->designators(), Designators.begin(),
-                  [this](const Designator &D) -> Designator {
-                    return ImportDesignator(D);
-                  });
-
-  for (const auto &D : DIE->designators())
-    if (D.isFieldDesignator() && !D.getFieldName())
-      return nullptr;
+  SmallVector<Designator, 4> ToDesignators(E->size());
+  if (Error Err = ImportContainerChecked(E->designators(), ToDesignators))
+    return std::move(Err);
 
   return DesignatedInitExpr::Create(
-        Importer.getToContext(), Designators,
-        IndexExprs, Importer.Import(DIE->getEqualOrColonLoc()),
-        DIE->usesGNUSyntax(), Init);
+        Importer.getToContext(), ToDesignators,
+        ToIndexExprs, *ToEqualOrColonLocOrErr,
+        E->usesGNUSyntax(), *ToInitOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  return new (Importer.getToContext())
-      CXXNullPtrLiteralExpr(T, Importer.Import(E->getLocation()));
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return new (Importer.getToContext()) CXXNullPtrLiteralExpr(
+      *ToTypeOrErr, *ToLocationOrErr);
 }
 
-Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  return IntegerLiteral::Create(Importer.getToContext(),
-                                E->getValue(), T,
-                                Importer.Import(E->getLocation()));
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return IntegerLiteral::Create(
+      Importer.getToContext(), E->getValue(), *ToTypeOrErr, *ToLocationOrErr);
 }
 
-Expr *ASTNodeImporter::VisitFloatingLiteral(FloatingLiteral *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
 
-  return FloatingLiteral::Create(Importer.getToContext(),
-                                E->getValue(), E->isExact(), T,
-                                Importer.Import(E->getLocation()));
+ExpectedStmt ASTNodeImporter::VisitFloatingLiteral(FloatingLiteral *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
+
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return FloatingLiteral::Create(
+      Importer.getToContext(), E->getValue(), E->isExact(),
+      *ToTypeOrErr, *ToLocationOrErr);
 }
 
-Expr *ASTNodeImporter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitImaginaryLiteral(ImaginaryLiteral *E) {
+  auto ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  Expr *SubE = Importer.Import(E->getSubExpr());
-  if (!SubE)
-    return nullptr;
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
 
-  return new (Importer.getToContext()) ImaginaryLiteral(SubE, T);
+  return new (Importer.getToContext()) ImaginaryLiteral(
+      *ToSubExprOrErr, *ToTypeOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
-                                                        E->getKind(), T,
-                                          Importer.Import(E->getLocation()));
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return new (Importer.getToContext()) CharacterLiteral(
+      E->getValue(), E->getKind(), *ToTypeOrErr, *ToLocationOrErr);
 }
 
-Expr *ASTNodeImporter::VisitStringLiteral(StringLiteral *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitStringLiteral(StringLiteral *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  SmallVector<SourceLocation, 4> Locations(E->getNumConcatenated());
-  ImportArray(E->tokloc_begin(), E->tokloc_end(), Locations.begin());
+  SmallVector<SourceLocation, 4> ToLocations(E->getNumConcatenated());
+  if (Error Err = ImportArrayChecked(
+      E->tokloc_begin(), E->tokloc_end(), ToLocations.begin()))
+    return std::move(Err);
 
-  return StringLiteral::Create(Importer.getToContext(), E->getBytes(),
-                               E->getKind(), E->isPascal(), T,
-                               Locations.data(), Locations.size());
+  return StringLiteral::Create(
+      Importer.getToContext(), E->getBytes(), E->getKind(), E->isPascal(),
+      *ToTypeOrErr, ToLocations.data(), ToLocations.size());
 }
 
-Expr *ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  auto Imp = importSeq(
+      E->getLParenLoc(), E->getTypeSourceInfo(), E->getType(),
+      E->getInitializer());
+  if (!Imp)
+    return Imp.takeError();
 
-  TypeSourceInfo *TInfo = Importer.Import(E->getTypeSourceInfo());
-  if (!TInfo)
-    return nullptr;
-
-  Expr *Init = Importer.Import(E->getInitializer());
-  if (!Init)
-    return nullptr;
+  SourceLocation ToLParenLoc;
+  TypeSourceInfo *ToTypeSourceInfo;
+  QualType ToType;
+  Expr *ToInitializer;
+  std::tie(ToLParenLoc, ToTypeSourceInfo, ToType, ToInitializer) = *Imp;
 
   return new (Importer.getToContext()) CompoundLiteralExpr(
-        Importer.Import(E->getLParenLoc()), TInfo, T, E->getValueKind(),
-        Init, E->isFileScope());
+        ToLParenLoc, ToTypeSourceInfo, ToType, E->getValueKind(),
+        ToInitializer, E->isFileScope());
 }
 
-Expr *ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) {
+  auto Imp = importSeq(
+      E->getBuiltinLoc(), E->getType(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  SmallVector<Expr *, 6> Exprs(E->getNumSubExprs());
-  if (ImportArrayChecked(
-        E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(),
-        Exprs.begin()))
-    return nullptr;
+  SourceLocation ToBuiltinLoc, ToRParenLoc;
+  QualType ToType;
+  std::tie(ToBuiltinLoc, ToType, ToRParenLoc) = *Imp;
+
+  SmallVector<Expr *, 6> ToExprs(E->getNumSubExprs());
+  if (Error Err = ImportArrayChecked(
+      E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(),
+      ToExprs.begin()))
+    return std::move(Err);
 
   return new (Importer.getToContext()) AtomicExpr(
-        Importer.Import(E->getBuiltinLoc()), Exprs, T, E->getOp(),
-        Importer.Import(E->getRParenLoc()));
+      ToBuiltinLoc, ToExprs, ToType, E->getOp(), ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) {
+  auto Imp = importSeq(
+      E->getAmpAmpLoc(), E->getLabelLoc(), E->getLabel(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *ToLabel = cast_or_null<LabelDecl>(Importer.Import(E->getLabel()));
-  if (!ToLabel)
-    return nullptr;
+  SourceLocation ToAmpAmpLoc, ToLabelLoc;
+  LabelDecl *ToLabel;
+  QualType ToType;
+  std::tie(ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType) = *Imp;
 
   return new (Importer.getToContext()) AddrLabelExpr(
-        Importer.Import(E->getAmpAmpLoc()), Importer.Import(E->getLabelLoc()),
-        ToLabel, T);
+      ToAmpAmpLoc, ToLabelLoc, ToLabel, ToType);
 }
 
-Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
+  auto Imp = importSeq(E->getLParen(), E->getRParen(), E->getSubExpr());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToLParen, ToRParen;
+  Expr *ToSubExpr;
+  std::tie(ToLParen, ToRParen, ToSubExpr) = *Imp;
 
   return new (Importer.getToContext())
-                                  ParenExpr(Importer.Import(E->getLParen()),
-                                            Importer.Import(E->getRParen()),
-                                            SubExpr);
+      ParenExpr(ToLParen, ToRParen, ToSubExpr);
 }
 
-Expr *ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) {
-  SmallVector<Expr *, 4> Exprs(E->getNumExprs());
-  if (ImportContainerChecked(E->exprs(), Exprs))
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) {
+  SmallVector<Expr *, 4> ToExprs(E->getNumExprs());
+  if (Error Err = ImportContainerChecked(E->exprs(), ToExprs))
+    return std::move(Err);
+
+  ExpectedSLoc ToLParenLocOrErr = import(E->getLParenLoc());
+  if (!ToLParenLocOrErr)
+    return ToLParenLocOrErr.takeError();
+
+  ExpectedSLoc ToRParenLocOrErr = import(E->getRParenLoc());
+  if (!ToRParenLocOrErr)
+    return ToRParenLocOrErr.takeError();
 
   return new (Importer.getToContext()) ParenListExpr(
-        Importer.getToContext(), Importer.Import(E->getLParenLoc()),
-        Exprs, Importer.Import(E->getLParenLoc()));
+      Importer.getToContext(), *ToLParenLocOrErr, ToExprs, *ToRParenLocOrErr);
 }
 
-Expr *ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
+  auto Imp = importSeq(
+      E->getSubStmt(), E->getType(), E->getLParenLoc(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *ToSubStmt = cast_or_null<CompoundStmt>(
-      Importer.Import(E->getSubStmt()));
-  if (!ToSubStmt && E->getSubStmt())
-    return nullptr;
+  CompoundStmt *ToSubStmt;
+  QualType ToType;
+  SourceLocation ToLParenLoc, ToRParenLoc;
+  std::tie(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc) = *Imp;
 
-  return new (Importer.getToContext()) StmtExpr(ToSubStmt, T,
-        Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc()));
+  return new (Importer.getToContext()) StmtExpr(
+      ToSubStmt, ToType, ToLParenLoc, ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
+  auto Imp = importSeq(
+      E->getSubExpr(), E->getType(), E->getOperatorLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+  Expr *ToSubExpr;
+  QualType ToType;
+  SourceLocation ToOperatorLoc;
+  std::tie(ToSubExpr, ToType, ToOperatorLoc) = *Imp;
 
   return new (Importer.getToContext()) UnaryOperator(
-      SubExpr, E->getOpcode(), T, E->getValueKind(), E->getObjectKind(),
-      Importer.Import(E->getOperatorLoc()), E->canOverflow());
+      ToSubExpr, E->getOpcode(), ToType, E->getValueKind(), E->getObjectKind(),
+      ToOperatorLoc, E->canOverflow());
 }
 
-Expr *
+ExpectedStmt
 ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
-  QualType ResultType = Importer.Import(E->getType());
+  auto Imp = importSeq(E->getType(), E->getOperatorLoc(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  QualType ToType;
+  SourceLocation ToOperatorLoc, ToRParenLoc;
+  std::tie(ToType, ToOperatorLoc, ToRParenLoc) = *Imp;
 
   if (E->isArgumentType()) {
-    TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
-    if (!TInfo)
-      return nullptr;
+    Expected<TypeSourceInfo *> ToArgumentTypeInfoOrErr =
+        import(E->getArgumentTypeInfo());
+    if (!ToArgumentTypeInfoOrErr)
+      return ToArgumentTypeInfoOrErr.takeError();
 
-    return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
-                                           TInfo, ResultType,
-                                           Importer.Import(E->getOperatorLoc()),
-                                           Importer.Import(E->getRParenLoc()));
+    return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(
+        E->getKind(), *ToArgumentTypeInfoOrErr, ToType, ToOperatorLoc,
+        ToRParenLoc);
   }
 
-  Expr *SubExpr = Importer.Import(E->getArgumentExpr());
-  if (!SubExpr)
-    return nullptr;
+  ExpectedExpr ToArgumentExprOrErr = import(E->getArgumentExpr());
+  if (!ToArgumentExprOrErr)
+    return ToArgumentExprOrErr.takeError();
 
-  return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
-                                          SubExpr, ResultType,
-                                          Importer.Import(E->getOperatorLoc()),
-                                          Importer.Import(E->getRParenLoc()));
+  return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(
+      E->getKind(), *ToArgumentExprOrErr, ToType, ToOperatorLoc, ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
+  auto Imp = importSeq(
+      E->getLHS(), E->getRHS(), E->getType(), E->getOperatorLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *LHS = Importer.Import(E->getLHS());
-  if (!LHS)
-    return nullptr;
+  Expr *ToLHS, *ToRHS;
+  QualType ToType;
+  SourceLocation  ToOperatorLoc;
+  std::tie(ToLHS, ToRHS, ToType, ToOperatorLoc) = *Imp;
 
-  Expr *RHS = Importer.Import(E->getRHS());
-  if (!RHS)
-    return nullptr;
-
-  return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
-                                                      T, E->getValueKind(),
-                                                      E->getObjectKind(),
-                                           Importer.Import(E->getOperatorLoc()),
-                                                      E->getFPFeatures());
+  return new (Importer.getToContext()) BinaryOperator(
+      ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
+      E->getObjectKind(), ToOperatorLoc, E->getFPFeatures());
 }
 
-Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
+  auto Imp = importSeq(
+      E->getCond(), E->getQuestionLoc(), E->getLHS(), E->getColonLoc(),
+      E->getRHS(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToLHS = Importer.Import(E->getLHS());
-  if (!ToLHS)
-    return nullptr;
-
-  Expr *ToRHS = Importer.Import(E->getRHS());
-  if (!ToRHS)
-    return nullptr;
-
-  Expr *ToCond = Importer.Import(E->getCond());
-  if (!ToCond)
-    return nullptr;
+  Expr *ToCond, *ToLHS, *ToRHS;
+  SourceLocation ToQuestionLoc, ToColonLoc;
+  QualType ToType;
+  std::tie(ToCond, ToQuestionLoc, ToLHS, ToColonLoc, ToRHS, ToType) = *Imp;
 
   return new (Importer.getToContext()) ConditionalOperator(
-        ToCond, Importer.Import(E->getQuestionLoc()),
-        ToLHS, Importer.Import(E->getColonLoc()),
-        ToRHS, T, E->getValueKind(), E->getObjectKind());
+      ToCond, ToQuestionLoc, ToLHS, ToColonLoc, ToRHS, ToType,
+      E->getValueKind(), E->getObjectKind());
 }
 
-Expr *ASTNodeImporter::VisitBinaryConditionalOperator(
+ExpectedStmt ASTNodeImporter::VisitBinaryConditionalOperator(
     BinaryConditionalOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  auto Imp = importSeq(
+      E->getCommon(), E->getOpaqueValue(), E->getCond(), E->getTrueExpr(),
+      E->getFalseExpr(), E->getQuestionLoc(), E->getColonLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *Common = Importer.Import(E->getCommon());
-  if (!Common)
-    return nullptr;
-
-  Expr *Cond = Importer.Import(E->getCond());
-  if (!Cond)
-    return nullptr;
-
-  auto *OpaqueValue = cast_or_null<OpaqueValueExpr>(
-      Importer.Import(E->getOpaqueValue()));
-  if (!OpaqueValue)
-    return nullptr;
-
-  Expr *TrueExpr = Importer.Import(E->getTrueExpr());
-  if (!TrueExpr)
-    return nullptr;
-
-  Expr *FalseExpr = Importer.Import(E->getFalseExpr());
-  if (!FalseExpr)
-    return nullptr;
+  Expr *ToCommon, *ToCond, *ToTrueExpr, *ToFalseExpr;
+  OpaqueValueExpr *ToOpaqueValue;
+  SourceLocation ToQuestionLoc, ToColonLoc;
+  QualType ToType;
+  std::tie(
+      ToCommon, ToOpaqueValue, ToCond, ToTrueExpr, ToFalseExpr, ToQuestionLoc,
+      ToColonLoc, ToType) = *Imp;
 
   return new (Importer.getToContext()) BinaryConditionalOperator(
-        Common, OpaqueValue, Cond, TrueExpr, FalseExpr,
-        Importer.Import(E->getQuestionLoc()), Importer.Import(E->getColonLoc()),
-        T, E->getValueKind(), E->getObjectKind());
+      ToCommon, ToOpaqueValue, ToCond, ToTrueExpr, ToFalseExpr,
+      ToQuestionLoc, ToColonLoc, ToType, E->getValueKind(),
+      E->getObjectKind());
 }
 
-Expr *ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  auto Imp = importSeq(
+      E->getBeginLoc(), E->getQueriedTypeSourceInfo(),
+      E->getDimensionExpression(), E->getEndLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  TypeSourceInfo *ToQueried = Importer.Import(E->getQueriedTypeSourceInfo());
-  if (!ToQueried)
-    return nullptr;
-
-  Expr *Dim = Importer.Import(E->getDimensionExpression());
-  if (!Dim && E->getDimensionExpression())
-    return nullptr;
+  SourceLocation ToBeginLoc, ToEndLoc;
+  TypeSourceInfo *ToQueriedTypeSourceInfo;
+  Expr *ToDimensionExpression;
+  QualType ToType;
+  std::tie(
+      ToBeginLoc, ToQueriedTypeSourceInfo, ToDimensionExpression, ToEndLoc,
+      ToType) = *Imp;
 
   return new (Importer.getToContext()) ArrayTypeTraitExpr(
-      Importer.Import(E->getBeginLoc()), E->getTrait(), ToQueried,
-      E->getValue(), Dim, Importer.Import(E->getEndLoc()), T);
+      ToBeginLoc, E->getTrait(), ToQueriedTypeSourceInfo, E->getValue(),
+      ToDimensionExpression, ToEndLoc, ToType);
 }
 
-Expr *ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
+  auto Imp = importSeq(
+      E->getBeginLoc(), E->getQueriedExpression(), E->getEndLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToQueried = Importer.Import(E->getQueriedExpression());
-  if (!ToQueried)
-    return nullptr;
+  SourceLocation ToBeginLoc, ToEndLoc;
+  Expr *ToQueriedExpression;
+  QualType ToType;
+  std::tie(ToBeginLoc, ToQueriedExpression, ToEndLoc, ToType) = *Imp;
 
   return new (Importer.getToContext()) ExpressionTraitExpr(
-      Importer.Import(E->getBeginLoc()), E->getTrait(), ToQueried,
-      E->getValue(), Importer.Import(E->getEndLoc()), T);
+      ToBeginLoc, E->getTrait(), ToQueriedExpression, E->getValue(),
+      ToEndLoc, ToType);
 }
 
-Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
+  auto Imp = importSeq(
+      E->getLocation(), E->getType(), E->getSourceExpr());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *SourceExpr = Importer.Import(E->getSourceExpr());
-  if (!SourceExpr && E->getSourceExpr())
-    return nullptr;
+  SourceLocation ToLocation;
+  QualType ToType;
+  Expr *ToSourceExpr;
+  std::tie(ToLocation, ToType, ToSourceExpr) = *Imp;
 
   return new (Importer.getToContext()) OpaqueValueExpr(
-        Importer.Import(E->getLocation()), T, E->getValueKind(),
-        E->getObjectKind(), SourceExpr);
+      ToLocation, ToType, E->getValueKind(), E->getObjectKind(), ToSourceExpr);
 }
 
-Expr *ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+  auto Imp = importSeq(
+      E->getLHS(), E->getRHS(), E->getType(), E->getRBracketLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToLHS = Importer.Import(E->getLHS());
-  if (!ToLHS)
-    return nullptr;
-
-  Expr *ToRHS = Importer.Import(E->getRHS());
-  if (!ToRHS)
-    return nullptr;
+  Expr *ToLHS, *ToRHS;
+  SourceLocation ToRBracketLoc;
+  QualType ToType;
+  std::tie(ToLHS, ToRHS, ToType, ToRBracketLoc) = *Imp;
 
   return new (Importer.getToContext()) ArraySubscriptExpr(
-        ToLHS, ToRHS, T, E->getValueKind(), E->getObjectKind(),
-        Importer.Import(E->getRBracketLoc()));
+      ToLHS, ToRHS, ToType, E->getValueKind(), E->getObjectKind(),
+      ToRBracketLoc);
 }
 
-Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
+  auto Imp = importSeq(
+      E->getLHS(), E->getRHS(), E->getType(), E->getComputationLHSType(),
+      E->getComputationResultType(), E->getOperatorLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  QualType CompLHSType = Importer.Import(E->getComputationLHSType());
-  if (CompLHSType.isNull())
-    return nullptr;
+  Expr *ToLHS, *ToRHS;
+  QualType ToType, ToComputationLHSType, ToComputationResultType;
+  SourceLocation ToOperatorLoc;
+  std::tie(ToLHS, ToRHS, ToType, ToComputationLHSType, ToComputationResultType,
+      ToOperatorLoc) = *Imp;
 
-  QualType CompResultType = Importer.Import(E->getComputationResultType());
-  if (CompResultType.isNull())
-    return nullptr;
-
-  Expr *LHS = Importer.Import(E->getLHS());
-  if (!LHS)
-    return nullptr;
-
-  Expr *RHS = Importer.Import(E->getRHS());
-  if (!RHS)
-    return nullptr;
-
-  return new (Importer.getToContext())
-                        CompoundAssignOperator(LHS, RHS, E->getOpcode(),
-                                               T, E->getValueKind(),
-                                               E->getObjectKind(),
-                                               CompLHSType, CompResultType,
-                                           Importer.Import(E->getOperatorLoc()),
-                                               E->getFPFeatures());
+  return new (Importer.getToContext()) CompoundAssignOperator(
+      ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
+      E->getObjectKind(), ToComputationLHSType, ToComputationResultType,
+      ToOperatorLoc, E->getFPFeatures());
 }
 
-bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) {
+Expected<CXXCastPath>
+ASTNodeImporter::ImportCastPath(CastExpr *CE) {
+  CXXCastPath Path;
   for (auto I = CE->path_begin(), E = CE->path_end(); I != E; ++I) {
-    if (CXXBaseSpecifier *Spec = Importer.Import(*I))
-      Path.push_back(Spec);
+    if (auto SpecOrErr = import(*I))
+      Path.push_back(*SpecOrErr);
     else
-      return true;
+      return SpecOrErr.takeError();
   }
-  return false;
+  return Path;
 }
 
-Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
 
-  CXXCastPath BasePath;
-  if (ImportCastPath(E, BasePath))
-    return nullptr;
+  Expected<CXXCastPath> ToBasePathOrErr = ImportCastPath(E);
+  if (!ToBasePathOrErr)
+    return ToBasePathOrErr.takeError();
 
-  return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
-                                  SubExpr, &BasePath, E->getValueKind());
+  return ImplicitCastExpr::Create(
+      Importer.getToContext(), *ToTypeOrErr, E->getCastKind(), *ToSubExprOrErr,
+      &(*ToBasePathOrErr), E->getValueKind());
 }
 
-Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  auto Imp1 = importSeq(
+      E->getType(), E->getSubExpr(), E->getTypeInfoAsWritten());
+  if (!Imp1)
+    return Imp1.takeError();
 
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+  QualType ToType;
+  Expr *ToSubExpr;
+  TypeSourceInfo *ToTypeInfoAsWritten;
+  std::tie(ToType, ToSubExpr, ToTypeInfoAsWritten) = *Imp1;
 
-  TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
-  if (!TInfo && E->getTypeInfoAsWritten())
-    return nullptr;
-
-  CXXCastPath BasePath;
-  if (ImportCastPath(E, BasePath))
-    return nullptr;
+  Expected<CXXCastPath> ToBasePathOrErr = ImportCastPath(E);
+  if (!ToBasePathOrErr)
+    return ToBasePathOrErr.takeError();
+  CXXCastPath *ToBasePath = &(*ToBasePathOrErr);
 
   switch (E->getStmtClass()) {
   case Stmt::CStyleCastExprClass: {
     auto *CCE = cast<CStyleCastExpr>(E);
-    return CStyleCastExpr::Create(Importer.getToContext(), T,
-                                  E->getValueKind(), E->getCastKind(),
-                                  SubExpr, &BasePath, TInfo,
-                                  Importer.Import(CCE->getLParenLoc()),
-                                  Importer.Import(CCE->getRParenLoc()));
+    ExpectedSLoc ToLParenLocOrErr = import(CCE->getLParenLoc());
+    if (!ToLParenLocOrErr)
+      return ToLParenLocOrErr.takeError();
+    ExpectedSLoc ToRParenLocOrErr = import(CCE->getRParenLoc());
+    if (!ToRParenLocOrErr)
+      return ToRParenLocOrErr.takeError();
+    return CStyleCastExpr::Create(
+        Importer.getToContext(), ToType, E->getValueKind(), E->getCastKind(),
+        ToSubExpr, ToBasePath, ToTypeInfoAsWritten, *ToLParenLocOrErr,
+        *ToRParenLocOrErr);
   }
 
   case Stmt::CXXFunctionalCastExprClass: {
     auto *FCE = cast<CXXFunctionalCastExpr>(E);
-    return CXXFunctionalCastExpr::Create(Importer.getToContext(), T,
-                                         E->getValueKind(), TInfo,
-                                         E->getCastKind(), SubExpr, &BasePath,
-                                         Importer.Import(FCE->getLParenLoc()),
-                                         Importer.Import(FCE->getRParenLoc()));
+    ExpectedSLoc ToLParenLocOrErr = import(FCE->getLParenLoc());
+    if (!ToLParenLocOrErr)
+      return ToLParenLocOrErr.takeError();
+    ExpectedSLoc ToRParenLocOrErr = import(FCE->getRParenLoc());
+    if (!ToRParenLocOrErr)
+      return ToRParenLocOrErr.takeError();
+    return CXXFunctionalCastExpr::Create(
+        Importer.getToContext(), ToType, E->getValueKind(), ToTypeInfoAsWritten,
+        E->getCastKind(), ToSubExpr, ToBasePath, *ToLParenLocOrErr,
+        *ToRParenLocOrErr);
   }
 
   case Stmt::ObjCBridgedCastExprClass: {
-      auto *OCE = cast<ObjCBridgedCastExpr>(E);
-      return new (Importer.getToContext()) ObjCBridgedCastExpr(
-            Importer.Import(OCE->getLParenLoc()), OCE->getBridgeKind(),
-            E->getCastKind(), Importer.Import(OCE->getBridgeKeywordLoc()),
-            TInfo, SubExpr);
+    auto *OCE = cast<ObjCBridgedCastExpr>(E);
+    ExpectedSLoc ToLParenLocOrErr = import(OCE->getLParenLoc());
+    if (!ToLParenLocOrErr)
+      return ToLParenLocOrErr.takeError();
+    ExpectedSLoc ToBridgeKeywordLocOrErr = import(OCE->getBridgeKeywordLoc());
+    if (!ToBridgeKeywordLocOrErr)
+      return ToBridgeKeywordLocOrErr.takeError();
+    return new (Importer.getToContext()) ObjCBridgedCastExpr(
+        *ToLParenLocOrErr, OCE->getBridgeKind(), E->getCastKind(),
+        *ToBridgeKeywordLocOrErr, ToTypeInfoAsWritten, ToSubExpr);
   }
   default:
     llvm_unreachable("Cast expression of unsupported type!");
-    return nullptr;
+    return make_error<ImportError>(ImportError::UnsupportedConstruct);
   }
 }
 
-Expr *ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *OE) {
-  QualType T = Importer.Import(OE->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *E) {
+  SmallVector<OffsetOfNode, 4> ToNodes;
+  for (int I = 0, N = E->getNumComponents(); I < N; ++I) {
+    const OffsetOfNode &FromNode = E->getComponent(I);
 
-  SmallVector<OffsetOfNode, 4> Nodes;
-  for (int I = 0, E = OE->getNumComponents(); I < E; ++I) {
-    const OffsetOfNode &Node = OE->getComponent(I);
+    SourceLocation ToBeginLoc, ToEndLoc;
+    if (FromNode.getKind() != OffsetOfNode::Base) {
+      auto Imp = importSeq(FromNode.getBeginLoc(), FromNode.getEndLoc());
+      if (!Imp)
+        return Imp.takeError();
+      std::tie(ToBeginLoc, ToEndLoc) = *Imp;
+    }
 
-    switch (Node.getKind()) {
+    switch (FromNode.getKind()) {
     case OffsetOfNode::Array:
-      Nodes.push_back(OffsetOfNode(Importer.Import(Node.getBeginLoc()),
-                                   Node.getArrayExprIndex(),
-                                   Importer.Import(Node.getEndLoc())));
+      ToNodes.push_back(
+          OffsetOfNode(ToBeginLoc, FromNode.getArrayExprIndex(), ToEndLoc));
       break;
-
     case OffsetOfNode::Base: {
-      CXXBaseSpecifier *BS = Importer.Import(Node.getBase());
-      if (!BS && Node.getBase())
-        return nullptr;
-      Nodes.push_back(OffsetOfNode(BS));
+      auto ToBSOrErr = import(FromNode.getBase());
+      if (!ToBSOrErr)
+        return ToBSOrErr.takeError();
+      ToNodes.push_back(OffsetOfNode(*ToBSOrErr));
       break;
     }
     case OffsetOfNode::Field: {
-      auto *FD = cast_or_null<FieldDecl>(Importer.Import(Node.getField()));
-      if (!FD)
-        return nullptr;
-      Nodes.push_back(OffsetOfNode(Importer.Import(Node.getBeginLoc()), FD,
-                                   Importer.Import(Node.getEndLoc())));
+      auto ToFieldOrErr = import(FromNode.getField());
+      if (!ToFieldOrErr)
+        return ToFieldOrErr.takeError();
+      ToNodes.push_back(OffsetOfNode(ToBeginLoc, *ToFieldOrErr, ToEndLoc));
       break;
     }
     case OffsetOfNode::Identifier: {
-      IdentifierInfo *ToII = Importer.Import(Node.getFieldName());
-      if (!ToII)
-        return nullptr;
-      Nodes.push_back(OffsetOfNode(Importer.Import(Node.getBeginLoc()), ToII,
-                                   Importer.Import(Node.getEndLoc())));
+      IdentifierInfo *ToII = Importer.Import(FromNode.getFieldName());
+      ToNodes.push_back(OffsetOfNode(ToBeginLoc, ToII, ToEndLoc));
       break;
     }
     }
   }
 
-  SmallVector<Expr *, 4> Exprs(OE->getNumExpressions());
-  for (int I = 0, E = OE->getNumExpressions(); I < E; ++I) {
-    Expr *ToIndexExpr = Importer.Import(OE->getIndexExpr(I));
-    if (!ToIndexExpr)
-      return nullptr;
-    Exprs[I] = ToIndexExpr;
+  SmallVector<Expr *, 4> ToExprs(E->getNumExpressions());
+  for (int I = 0, N = E->getNumExpressions(); I < N; ++I) {
+    ExpectedExpr ToIndexExprOrErr = import(E->getIndexExpr(I));
+    if (!ToIndexExprOrErr)
+      return ToIndexExprOrErr.takeError();
+    ToExprs[I] = *ToIndexExprOrErr;
   }
 
-  TypeSourceInfo *TInfo = Importer.Import(OE->getTypeSourceInfo());
-  if (!TInfo && OE->getTypeSourceInfo())
-    return nullptr;
+  auto Imp = importSeq(
+      E->getType(), E->getTypeSourceInfo(), E->getOperatorLoc(),
+      E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  return OffsetOfExpr::Create(Importer.getToContext(), T,
-                              Importer.Import(OE->getOperatorLoc()),
-                              TInfo, Nodes, Exprs,
-                              Importer.Import(OE->getRParenLoc()));
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceLocation ToOperatorLoc, ToRParenLoc;
+  std::tie(ToType, ToTypeSourceInfo, ToOperatorLoc, ToRParenLoc) = *Imp;
+
+  return OffsetOfExpr::Create(
+      Importer.getToContext(), ToType, ToOperatorLoc, ToTypeSourceInfo, ToNodes,
+      ToExprs, ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getOperand(), E->getBeginLoc(), E->getEndLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *Operand = Importer.Import(E->getOperand());
-  if (!Operand)
-    return nullptr;
+  QualType ToType;
+  Expr *ToOperand;
+  SourceLocation ToBeginLoc, ToEndLoc;
+  std::tie(ToType, ToOperand, ToBeginLoc, ToEndLoc) = *Imp;
 
-  CanThrowResult CanThrow;
+  CanThrowResult ToCanThrow;
   if (E->isValueDependent())
-    CanThrow = CT_Dependent;
+    ToCanThrow = CT_Dependent;
   else
-    CanThrow = E->getValue() ? CT_Can : CT_Cannot;
+    ToCanThrow = E->getValue() ? CT_Can : CT_Cannot;
 
-  return new (Importer.getToContext())
-      CXXNoexceptExpr(T, Operand, CanThrow, Importer.Import(E->getBeginLoc()),
-                      Importer.Import(E->getEndLoc()));
+  return new (Importer.getToContext()) CXXNoexceptExpr(
+      ToType, ToOperand, ToCanThrow, ToBeginLoc, ToEndLoc);
 }
 
-Expr *ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) {
+  auto Imp = importSeq(E->getSubExpr(), E->getType(), E->getThrowLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr && E->getSubExpr())
-    return nullptr;
+  Expr *ToSubExpr;
+  QualType ToType;
+  SourceLocation ToThrowLoc;
+  std::tie(ToSubExpr, ToType, ToThrowLoc) = *Imp;
 
   return new (Importer.getToContext()) CXXThrowExpr(
-        SubExpr, T, Importer.Import(E->getThrowLoc()),
-        E->isThrownVariableInScope());
+      ToSubExpr, ToType, ToThrowLoc, E->isThrownVariableInScope());
 }
 
-Expr *ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
-  auto *Param = cast_or_null<ParmVarDecl>(Importer.Import(E->getParam()));
-  if (!Param)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+  ExpectedSLoc ToUsedLocOrErr = import(E->getUsedLocation());
+  if (!ToUsedLocOrErr)
+    return ToUsedLocOrErr.takeError();
+
+  auto ToParamOrErr = import(E->getParam());
+  if (!ToParamOrErr)
+    return ToParamOrErr.takeError();
 
   return CXXDefaultArgExpr::Create(
-        Importer.getToContext(), Importer.Import(E->getUsedLocation()), Param);
+      Importer.getToContext(), *ToUsedLocOrErr, *ToParamOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getTypeSourceInfo(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  TypeSourceInfo *TypeInfo = Importer.Import(E->getTypeSourceInfo());
-  if (!TypeInfo)
-    return nullptr;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceLocation ToRParenLoc;
+  std::tie(ToType, ToTypeSourceInfo, ToRParenLoc) = *Imp;
 
   return new (Importer.getToContext()) CXXScalarValueInitExpr(
-        T, TypeInfo, Importer.Import(E->getRParenLoc()));
+      ToType, ToTypeSourceInfo, ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
 
-  auto *Dtor = cast_or_null<CXXDestructorDecl>(
-        Importer.Import(const_cast<CXXDestructorDecl *>(
-                          E->getTemporary()->getDestructor())));
-  if (!Dtor)
-    return nullptr;
+  auto ToDtorOrErr = import(E->getTemporary()->getDestructor());
+  if (!ToDtorOrErr)
+    return ToDtorOrErr.takeError();
 
   ASTContext &ToCtx = Importer.getToContext();
-  CXXTemporary *Temp = CXXTemporary::Create(ToCtx, Dtor);
-  return CXXBindTemporaryExpr::Create(ToCtx, Temp, SubExpr);
+  CXXTemporary *Temp = CXXTemporary::Create(ToCtx, *ToDtorOrErr);
+  return CXXBindTemporaryExpr::Create(ToCtx, Temp, *ToSubExprOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) {
-  QualType T = Importer.Import(CE->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+  auto Imp = importSeq(
+      E->getConstructor(), E->getType(), E->getTypeSourceInfo(),
+      E->getParenOrBraceRange());
+  if (!Imp)
+    return Imp.takeError();
 
-  TypeSourceInfo *TInfo = Importer.Import(CE->getTypeSourceInfo());
-  if (!TInfo)
-    return nullptr;
+  CXXConstructorDecl *ToConstructor;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceRange ToParenOrBraceRange;
+  std::tie(ToConstructor, ToType, ToTypeSourceInfo, ToParenOrBraceRange) = *Imp;
 
-  SmallVector<Expr *, 8> Args(CE->getNumArgs());
-  if (ImportContainerChecked(CE->arguments(), Args))
-    return nullptr;
-
-  auto *Ctor = cast_or_null<CXXConstructorDecl>(
-        Importer.Import(CE->getConstructor()));
-  if (!Ctor)
-    return nullptr;
+  SmallVector<Expr *, 8> ToArgs(E->getNumArgs());
+  if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
+    return std::move(Err);
 
   return new (Importer.getToContext()) CXXTemporaryObjectExpr(
-      Importer.getToContext(), Ctor, T, TInfo, Args,
-      Importer.Import(CE->getParenOrBraceRange()), CE->hadMultipleCandidates(),
-      CE->isListInitialization(), CE->isStdInitListInitialization(),
-      CE->requiresZeroInitialization());
+      Importer.getToContext(), ToConstructor, ToType, ToTypeSourceInfo, ToArgs,
+      ToParenOrBraceRange, E->hadMultipleCandidates(),
+      E->isListInitialization(), E->isStdInitListInitialization(),
+      E->requiresZeroInitialization());
 }
 
-Expr *
+ExpectedStmt
 ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  auto Imp = importSeq(
+      E->getType(), E->GetTemporaryExpr(), E->getExtendingDecl());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *TempE = Importer.Import(E->GetTemporaryExpr());
-  if (!TempE)
-    return nullptr;
-
-  auto *ExtendedBy = cast_or_null<ValueDecl>(
-        Importer.Import(const_cast<ValueDecl *>(E->getExtendingDecl())));
-  if (!ExtendedBy && E->getExtendingDecl())
-    return nullptr;
+  QualType ToType;
+  Expr *ToTemporaryExpr;
+  const ValueDecl *ToExtendingDecl;
+  std::tie(ToType, ToTemporaryExpr, ToExtendingDecl) = *Imp;
 
   auto *ToMTE =  new (Importer.getToContext()) MaterializeTemporaryExpr(
-        T, TempE, E->isBoundToLvalueReference());
+      ToType, ToTemporaryExpr, E->isBoundToLvalueReference());
 
   // FIXME: Should ManglingNumber get numbers associated with 'to' context?
-  ToMTE->setExtendingDecl(ExtendedBy, E->getManglingNumber());
+  ToMTE->setExtendingDecl(ToExtendingDecl, E->getManglingNumber());
   return ToMTE;
 }
 
-Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getPattern(), E->getEllipsisLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *Pattern = Importer.Import(E->getPattern());
-  if (!Pattern)
-    return nullptr;
+  QualType ToType;
+  Expr *ToPattern;
+  SourceLocation ToEllipsisLoc;
+  std::tie(ToType, ToPattern, ToEllipsisLoc) = *Imp;
 
   return new (Importer.getToContext()) PackExpansionExpr(
-        T, Pattern, Importer.Import(E->getEllipsisLoc()),
-        E->getNumExpansions());
+      ToType, ToPattern, ToEllipsisLoc, E->getNumExpansions());
 }
 
-Expr *ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
-  auto *Pack = cast_or_null<NamedDecl>(Importer.Import(E->getPack()));
-  if (!Pack)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
+  auto Imp = importSeq(
+      E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToOperatorLoc, ToPackLoc, ToRParenLoc;
+  NamedDecl *ToPack;
+  std::tie(ToOperatorLoc, ToPack, ToPackLoc, ToRParenLoc) = *Imp;
 
   Optional<unsigned> Length;
-
   if (!E->isValueDependent())
     Length = E->getPackLength();
 
-  SmallVector<TemplateArgument, 8> PartialArguments;
+  SmallVector<TemplateArgument, 8> ToPartialArguments;
   if (E->isPartiallySubstituted()) {
-    if (ImportTemplateArguments(E->getPartialArguments().data(),
-                                E->getPartialArguments().size(),
-                                PartialArguments))
-      return nullptr;
+    if (Error Err = ImportTemplateArguments(
+        E->getPartialArguments().data(),
+        E->getPartialArguments().size(),
+        ToPartialArguments))
+      return std::move(Err);
   }
 
   return SizeOfPackExpr::Create(
-      Importer.getToContext(), Importer.Import(E->getOperatorLoc()), Pack,
-      Importer.Import(E->getPackLoc()), Importer.Import(E->getRParenLoc()),
-      Length, PartialArguments);
+      Importer.getToContext(), ToOperatorLoc, ToPack, ToPackLoc, ToRParenLoc,
+      Length, ToPartialArguments);
 }
 
-Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
-  QualType T = Importer.Import(CE->getType());
-  if (T.isNull())
-    return nullptr;
 
-  SmallVector<Expr *, 4> PlacementArgs(CE->getNumPlacementArgs());
-  if (ImportContainerChecked(CE->placement_arguments(), PlacementArgs))
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *E) {
+  auto Imp = importSeq(
+      E->getOperatorNew(), E->getOperatorDelete(), E->getTypeIdParens(),
+      E->getArraySize(), E->getInitializer(), E->getType(),
+      E->getAllocatedTypeSourceInfo(), E->getSourceRange(),
+      E->getDirectInitRange());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *OperatorNewDecl = cast_or_null<FunctionDecl>(
-        Importer.Import(CE->getOperatorNew()));
-  if (!OperatorNewDecl && CE->getOperatorNew())
-    return nullptr;
+  FunctionDecl *ToOperatorNew, *ToOperatorDelete;
+  SourceRange ToTypeIdParens, ToSourceRange, ToDirectInitRange;
+  Expr *ToArraySize, *ToInitializer;
+  QualType ToType;
+  TypeSourceInfo *ToAllocatedTypeSourceInfo;
+  std::tie(
+    ToOperatorNew, ToOperatorDelete, ToTypeIdParens, ToArraySize, ToInitializer,
+    ToType, ToAllocatedTypeSourceInfo, ToSourceRange, ToDirectInitRange) = *Imp;
 
-  auto *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
-        Importer.Import(CE->getOperatorDelete()));
-  if (!OperatorDeleteDecl && CE->getOperatorDelete())
-    return nullptr;
-
-  Expr *ToInit = Importer.Import(CE->getInitializer());
-  if (!ToInit && CE->getInitializer())
-    return nullptr;
-
-  TypeSourceInfo *TInfo = Importer.Import(CE->getAllocatedTypeSourceInfo());
-  if (!TInfo)
-    return nullptr;
-
-  Expr *ToArrSize = Importer.Import(CE->getArraySize());
-  if (!ToArrSize && CE->getArraySize())
-    return nullptr;
+  SmallVector<Expr *, 4> ToPlacementArgs(E->getNumPlacementArgs());
+  if (Error Err =
+      ImportContainerChecked(E->placement_arguments(), ToPlacementArgs))
+    return std::move(Err);
 
   return new (Importer.getToContext()) CXXNewExpr(
-        Importer.getToContext(),
-        CE->isGlobalNew(),
-        OperatorNewDecl, OperatorDeleteDecl,
-        CE->passAlignment(),
-        CE->doesUsualArrayDeleteWantSize(),
-        PlacementArgs,
-        Importer.Import(CE->getTypeIdParens()),
-        ToArrSize, CE->getInitializationStyle(), ToInit, T, TInfo,
-        Importer.Import(CE->getSourceRange()),
-        Importer.Import(CE->getDirectInitRange()));
+      Importer.getToContext(), E->isGlobalNew(), ToOperatorNew,
+      ToOperatorDelete, E->passAlignment(), E->doesUsualArrayDeleteWantSize(),
+      ToPlacementArgs, ToTypeIdParens, ToArraySize, E->getInitializationStyle(),
+      ToInitializer, ToType, ToAllocatedTypeSourceInfo, ToSourceRange,
+      ToDirectInitRange);
 }
 
-Expr *ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getOperatorDelete(), E->getArgument(), E->getBeginLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
-        Importer.Import(E->getOperatorDelete()));
-  if (!OperatorDeleteDecl && E->getOperatorDelete())
-    return nullptr;
-
-  Expr *ToArg = Importer.Import(E->getArgument());
-  if (!ToArg && E->getArgument())
-    return nullptr;
+  QualType ToType;
+  FunctionDecl *ToOperatorDelete;
+  Expr *ToArgument;
+  SourceLocation ToBeginLoc;
+  std::tie(ToType, ToOperatorDelete, ToArgument, ToBeginLoc) = *Imp;
 
   return new (Importer.getToContext()) CXXDeleteExpr(
-      T, E->isGlobalDelete(), E->isArrayForm(), E->isArrayFormAsWritten(),
-      E->doesUsualArrayDeleteWantSize(), OperatorDeleteDecl, ToArg,
-      Importer.Import(E->getBeginLoc()));
+      ToType, E->isGlobalDelete(), E->isArrayForm(), E->isArrayFormAsWritten(),
+      E->doesUsualArrayDeleteWantSize(), ToOperatorDelete, ToArgument,
+      ToBeginLoc);
 }
 
-Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getLocation(), E->getConstructor(),
+      E->getParenOrBraceRange());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *ToCCD =
-    dyn_cast_or_null<CXXConstructorDecl>(Importer.Import(E->getConstructor()));
-  if (!ToCCD)
-    return nullptr;
+  QualType ToType;
+  SourceLocation ToLocation;
+  CXXConstructorDecl *ToConstructor;
+  SourceRange ToParenOrBraceRange;
+  std::tie(ToType, ToLocation, ToConstructor, ToParenOrBraceRange) = *Imp;
 
   SmallVector<Expr *, 6> ToArgs(E->getNumArgs());
-  if (ImportContainerChecked(E->arguments(), ToArgs))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
+    return std::move(Err);
 
-  return CXXConstructExpr::Create(Importer.getToContext(), T,
-                                  Importer.Import(E->getLocation()),
-                                  ToCCD, E->isElidable(),
-                                  ToArgs, E->hadMultipleCandidates(),
-                                  E->isListInitialization(),
-                                  E->isStdInitListInitialization(),
-                                  E->requiresZeroInitialization(),
-                                  E->getConstructionKind(),
-                                  Importer.Import(E->getParenOrBraceRange()));
+  return CXXConstructExpr::Create(
+      Importer.getToContext(), ToType, ToLocation, ToConstructor,
+      E->isElidable(), ToArgs, E->hadMultipleCandidates(),
+      E->isListInitialization(), E->isStdInitListInitialization(),
+      E->requiresZeroInitialization(), E->getConstructionKind(),
+      ToParenOrBraceRange);
 }
 
-Expr *ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *EWC) {
-  Expr *SubExpr = Importer.Import(EWC->getSubExpr());
-  if (!SubExpr && EWC->getSubExpr())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *E) {
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
 
-  SmallVector<ExprWithCleanups::CleanupObject, 8> Objs(EWC->getNumObjects());
-  for (unsigned I = 0, E = EWC->getNumObjects(); I < E; I++)
-    if (ExprWithCleanups::CleanupObject Obj =
-        cast_or_null<BlockDecl>(Importer.Import(EWC->getObject(I))))
-      Objs[I] = Obj;
-    else
-      return nullptr;
+  SmallVector<ExprWithCleanups::CleanupObject, 8> ToObjects(E->getNumObjects());
+  if (Error Err = ImportContainerChecked(E->getObjects(), ToObjects))
+    return std::move(Err);
 
-  return ExprWithCleanups::Create(Importer.getToContext(),
-                                  SubExpr, EWC->cleanupsHaveSideEffects(),
-                                  Objs);
+  return ExprWithCleanups::Create(
+      Importer.getToContext(), *ToSubExprOrErr, E->cleanupsHaveSideEffects(),
+      ToObjects);
 }
 
-Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+  auto Imp = importSeq(
+      E->getCallee(), E->getType(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToFn = Importer.Import(E->getCallee());
-  if (!ToFn)
-    return nullptr;
+  Expr *ToCallee;
+  QualType ToType;
+  SourceLocation ToRParenLoc;
+  std::tie(ToCallee, ToType, ToRParenLoc) = *Imp;
 
   SmallVector<Expr *, 4> ToArgs(E->getNumArgs());
-  if (ImportContainerChecked(E->arguments(), ToArgs))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
+    return std::move(Err);
 
   return new (Importer.getToContext()) CXXMemberCallExpr(
-        Importer.getToContext(), ToFn, ToArgs, T, E->getValueKind(),
-        Importer.Import(E->getRParenLoc()));
+      Importer.getToContext(), ToCallee, ToArgs, ToType, E->getValueKind(),
+      ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  return new (Importer.getToContext())
-  CXXThisExpr(Importer.Import(E->getLocation()), T, E->isImplicit());
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return new (Importer.getToContext()) CXXThisExpr(
+      *ToLocationOrErr, *ToTypeOrErr, E->isImplicit());
 }
 
-Expr *ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  return new (Importer.getToContext())
-  CXXBoolLiteralExpr(E->getValue(), T, Importer.Import(E->getLocation()));
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return new (Importer.getToContext()) CXXBoolLiteralExpr(
+      E->getValue(), *ToTypeOrErr, *ToLocationOrErr);
 }
 
+ExpectedStmt ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
+  auto Imp1 = importSeq(
+      E->getBase(), E->getOperatorLoc(), E->getQualifierLoc(),
+      E->getTemplateKeywordLoc(), E->getMemberDecl(), E->getType());
+  if (!Imp1)
+    return Imp1.takeError();
 
-Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  Expr *ToBase;
+  SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  ValueDecl *ToMemberDecl;
+  QualType ToType;
+  std::tie(
+      ToBase, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl,
+      ToType) = *Imp1;
 
-  Expr *ToBase = Importer.Import(E->getBase());
-  if (!ToBase && E->getBase())
-    return nullptr;
-
-  auto *ToMember = dyn_cast<ValueDecl>(Importer.Import(E->getMemberDecl()));
-  if (!ToMember && E->getMemberDecl())
-    return nullptr;
-
-  auto *ToDecl =
-      dyn_cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl().getDecl()));
-  if (!ToDecl && E->getFoundDecl().getDecl())
-    return nullptr;
+  auto Imp2 = importSeq(
+      E->getFoundDecl().getDecl(), E->getMemberNameInfo().getName(),
+      E->getMemberNameInfo().getLoc(), E->getLAngleLoc(), E->getRAngleLoc());
+  if (!Imp2)
+    return Imp2.takeError();
+  NamedDecl *ToDecl;
+  DeclarationName ToName;
+  SourceLocation ToLoc, ToLAngleLoc, ToRAngleLoc;
+  std::tie(ToDecl, ToName, ToLoc, ToLAngleLoc, ToRAngleLoc) = *Imp2;
 
   DeclAccessPair ToFoundDecl =
       DeclAccessPair::make(ToDecl, E->getFoundDecl().getAccess());
 
-  DeclarationNameInfo ToMemberNameInfo(
-    Importer.Import(E->getMemberNameInfo().getName()),
-    Importer.Import(E->getMemberNameInfo().getLoc()));
+  DeclarationNameInfo ToMemberNameInfo(ToName, ToLoc);
 
   if (E->hasExplicitTemplateArgs()) {
-    return nullptr; // FIXME: handle template arguments
+    // FIXME: handle template arguments
+    return make_error<ImportError>(ImportError::UnsupportedConstruct);
   }
 
-  return MemberExpr::Create(Importer.getToContext(), ToBase,
-                            E->isArrow(),
-                            Importer.Import(E->getOperatorLoc()),
-                            Importer.Import(E->getQualifierLoc()),
-                            Importer.Import(E->getTemplateKeywordLoc()),
-                            ToMember, ToFoundDecl, ToMemberNameInfo,
-                            nullptr, T, E->getValueKind(),
-                            E->getObjectKind());
+  return MemberExpr::Create(
+      Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
+      ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl, ToFoundDecl,
+      ToMemberNameInfo, nullptr, ToType, E->getValueKind(), E->getObjectKind());
 }
 
-Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr(
-    CXXPseudoDestructorExpr *E) {
-  Expr *BaseE = Importer.Import(E->getBase());
-  if (!BaseE)
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
+  auto Imp = importSeq(
+      E->getBase(), E->getOperatorLoc(), E->getQualifierLoc(),
+      E->getScopeTypeInfo(), E->getColonColonLoc(), E->getTildeLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  TypeSourceInfo *ScopeInfo = Importer.Import(E->getScopeTypeInfo());
-  if (!ScopeInfo && E->getScopeTypeInfo())
-    return nullptr;
+  Expr *ToBase;
+  SourceLocation ToOperatorLoc, ToColonColonLoc, ToTildeLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  TypeSourceInfo *ToScopeTypeInfo;
+  std::tie(
+      ToBase, ToOperatorLoc, ToQualifierLoc, ToScopeTypeInfo, ToColonColonLoc,
+      ToTildeLoc) = *Imp;
 
   PseudoDestructorTypeStorage Storage;
   if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) {
     IdentifierInfo *ToII = Importer.Import(FromII);
-    if (!ToII)
-      return nullptr;
-    Storage = PseudoDestructorTypeStorage(
-          ToII, Importer.Import(E->getDestroyedTypeLoc()));
+    ExpectedSLoc ToDestroyedTypeLocOrErr = import(E->getDestroyedTypeLoc());
+    if (!ToDestroyedTypeLocOrErr)
+      return ToDestroyedTypeLocOrErr.takeError();
+    Storage = PseudoDestructorTypeStorage(ToII, *ToDestroyedTypeLocOrErr);
   } else {
-    TypeSourceInfo *TI = Importer.Import(E->getDestroyedTypeInfo());
-    if (!TI)
-      return nullptr;
-    Storage = PseudoDestructorTypeStorage(TI);
+    if (auto ToTIOrErr = import(E->getDestroyedTypeInfo()))
+      Storage = PseudoDestructorTypeStorage(*ToTIOrErr);
+    else
+      return ToTIOrErr.takeError();
   }
 
   return new (Importer.getToContext()) CXXPseudoDestructorExpr(
-        Importer.getToContext(), BaseE, E->isArrow(),
-        Importer.Import(E->getOperatorLoc()),
-        Importer.Import(E->getQualifierLoc()),
-        ScopeInfo, Importer.Import(E->getColonColonLoc()),
-        Importer.Import(E->getTildeLoc()), Storage);
+      Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
+      ToQualifierLoc, ToScopeTypeInfo, ToColonColonLoc, ToTildeLoc, Storage);
 }
 
-Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
+ExpectedStmt ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
     CXXDependentScopeMemberExpr *E) {
-  Expr *Base = nullptr;
-  if (!E->isImplicitAccess()) {
-    Base = Importer.Import(E->getBase());
-    if (!Base)
-      return nullptr;
-  }
+  auto Imp = importSeq(
+      E->getType(), E->getOperatorLoc(), E->getQualifierLoc(),
+      E->getTemplateKeywordLoc(), E->getFirstQualifierFoundInScope());
+  if (!Imp)
+    return Imp.takeError();
 
-  QualType BaseType = Importer.Import(E->getBaseType());
-  if (BaseType.isNull())
-    return nullptr;
+  QualType ToType;
+  SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  NamedDecl *ToFirstQualifierFoundInScope;
+  std::tie(
+      ToType, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
+      ToFirstQualifierFoundInScope) = *Imp;
+
+  Expr *ToBase = nullptr;
+  if (!E->isImplicitAccess()) {
+    if (ExpectedExpr ToBaseOrErr = import(E->getBase()))
+      ToBase = *ToBaseOrErr;
+    else
+      return ToBaseOrErr.takeError();
+  }
 
   TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
   if (E->hasExplicitTemplateArgs()) {
-    if (ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
-                                       E->template_arguments(), ToTAInfo))
-      return nullptr;
+    if (Error Err = ImportTemplateArgumentListInfo(
+        E->getLAngleLoc(), E->getRAngleLoc(), E->template_arguments(),
+        ToTAInfo))
+      return std::move(Err);
     ResInfo = &ToTAInfo;
   }
 
-  DeclarationName Name = Importer.Import(E->getMember());
-  if (!E->getMember().isEmpty() && Name.isEmpty())
-    return nullptr;
-
-  DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E->getMemberLoc()));
+  auto ToMemberNameInfoOrErr = importSeq(E->getMember(), E->getMemberLoc());
+  if (!ToMemberNameInfoOrErr)
+    return ToMemberNameInfoOrErr.takeError();
+  DeclarationNameInfo ToMemberNameInfo(
+      std::get<0>(*ToMemberNameInfoOrErr), std::get<1>(*ToMemberNameInfoOrErr));
   // Import additional name location/type info.
-  ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo);
-  auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope());
-  if (!ToFQ && E->getFirstQualifierFoundInScope())
-    return nullptr;
+  if (Error Err = ImportDeclarationNameLoc(
+      E->getMemberNameInfo(), ToMemberNameInfo))
+    return std::move(Err);
 
   return CXXDependentScopeMemberExpr::Create(
-      Importer.getToContext(), Base, BaseType, E->isArrow(),
-      Importer.Import(E->getOperatorLoc()),
-      Importer.Import(E->getQualifierLoc()),
-      Importer.Import(E->getTemplateKeywordLoc()),
-      cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo);
+      Importer.getToContext(), ToBase, ToType, E->isArrow(), ToOperatorLoc,
+      ToQualifierLoc, ToTemplateKeywordLoc, ToFirstQualifierFoundInScope,
+      ToMemberNameInfo, ResInfo);
 }
 
-Expr *
+ExpectedStmt
 ASTNodeImporter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
-  DeclarationName Name = Importer.Import(E->getDeclName());
-  if (!E->getDeclName().isEmpty() && Name.isEmpty())
-    return nullptr;
+  auto Imp = importSeq(
+      E->getQualifierLoc(), E->getTemplateKeywordLoc(), E->getDeclName(),
+      E->getExprLoc(), E->getLAngleLoc(), E->getRAngleLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  DeclarationNameInfo NameInfo(Name, Importer.Import(E->getExprLoc()));
-  ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+  NestedNameSpecifierLoc ToQualifierLoc;
+  SourceLocation ToTemplateKeywordLoc, ToExprLoc, ToLAngleLoc, ToRAngleLoc;
+  DeclarationName ToDeclName;
+  std::tie(
+      ToQualifierLoc, ToTemplateKeywordLoc, ToDeclName, ToExprLoc,
+      ToLAngleLoc, ToRAngleLoc) = *Imp;
 
-  TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()),
-                                    Importer.Import(E->getRAngleLoc()));
+  DeclarationNameInfo ToNameInfo(ToDeclName, ToExprLoc);
+  if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
+    return std::move(Err);
+
+  TemplateArgumentListInfo ToTAInfo(ToLAngleLoc, ToRAngleLoc);
   TemplateArgumentListInfo *ResInfo = nullptr;
   if (E->hasExplicitTemplateArgs()) {
-    if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
-      return nullptr;
+    if (Error Err =
+        ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+      return std::move(Err);
     ResInfo = &ToTAInfo;
   }
 
   return DependentScopeDeclRefExpr::Create(
-      Importer.getToContext(), Importer.Import(E->getQualifierLoc()),
-      Importer.Import(E->getTemplateKeywordLoc()), NameInfo, ResInfo);
+      Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc,
+      ToNameInfo, ResInfo);
 }
 
-Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
-    CXXUnresolvedConstructExpr *CE) {
-  unsigned NumArgs = CE->arg_size();
+ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
+    CXXUnresolvedConstructExpr *E) {
+  auto Imp = importSeq(
+      E->getLParenLoc(), E->getRParenLoc(), E->getTypeSourceInfo());
+  if (!Imp)
+    return Imp.takeError();
 
-  SmallVector<Expr *, 8> ToArgs(NumArgs);
-  if (ImportArrayChecked(CE->arg_begin(), CE->arg_end(), ToArgs.begin()))
-    return nullptr;
+  SourceLocation ToLParenLoc, ToRParenLoc;
+  TypeSourceInfo *ToTypeSourceInfo;
+  std::tie(ToLParenLoc, ToRParenLoc, ToTypeSourceInfo) = *Imp;
+
+  SmallVector<Expr *, 8> ToArgs(E->arg_size());
+  if (Error Err =
+      ImportArrayChecked(E->arg_begin(), E->arg_end(), ToArgs.begin()))
+    return std::move(Err);
 
   return CXXUnresolvedConstructExpr::Create(
-      Importer.getToContext(), Importer.Import(CE->getTypeSourceInfo()),
-      Importer.Import(CE->getLParenLoc()), llvm::makeArrayRef(ToArgs),
-      Importer.Import(CE->getRParenLoc()));
+      Importer.getToContext(), ToTypeSourceInfo, ToLParenLoc,
+      llvm::makeArrayRef(ToArgs), ToRParenLoc);
 }
 
-Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
-  auto *NamingClass =
-      cast_or_null<CXXRecordDecl>(Importer.Import(E->getNamingClass()));
-  if (E->getNamingClass() && !NamingClass)
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
+  Expected<CXXRecordDecl *> ToNamingClassOrErr = import(E->getNamingClass());
+  if (!ToNamingClassOrErr)
+    return ToNamingClassOrErr.takeError();
 
-  DeclarationName Name = Importer.Import(E->getName());
-  if (E->getName() && !Name)
-    return nullptr;
+  auto ToQualifierLocOrErr = import(E->getQualifierLoc());
+  if (!ToQualifierLocOrErr)
+    return ToQualifierLocOrErr.takeError();
 
-  DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc()));
+  auto ToNameInfoOrErr = importSeq(E->getName(), E->getNameLoc());
+  if (!ToNameInfoOrErr)
+    return ToNameInfoOrErr.takeError();
+  DeclarationNameInfo ToNameInfo(
+      std::get<0>(*ToNameInfoOrErr), std::get<1>(*ToNameInfoOrErr));
   // Import additional name location/type info.
-  ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+  if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
+    return std::move(Err);
 
   UnresolvedSet<8> ToDecls;
-  for (auto *D : E->decls()) {
-    if (auto *To = cast_or_null<NamedDecl>(Importer.Import(D)))
-      ToDecls.addDecl(To);
+  for (auto *D : E->decls())
+    if (auto ToDOrErr = import(D))
+      ToDecls.addDecl(cast<NamedDecl>(*ToDOrErr));
     else
-      return nullptr;
-  }
+      return ToDOrErr.takeError();
 
-  TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
-  if (E->hasExplicitTemplateArgs()) {
-    if (ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
-                                       E->template_arguments(), ToTAInfo))
-      return nullptr;
-    ResInfo = &ToTAInfo;
-  }
+  if (E->hasExplicitTemplateArgs() && E->getTemplateKeywordLoc().isValid()) {
+    TemplateArgumentListInfo ToTAInfo;
+    if (Error Err = ImportTemplateArgumentListInfo(
+        E->getLAngleLoc(), E->getRAngleLoc(), E->template_arguments(),
+        ToTAInfo))
+      return std::move(Err);
 
-  if (ResInfo || E->getTemplateKeywordLoc().isValid())
+    ExpectedSLoc ToTemplateKeywordLocOrErr = import(E->getTemplateKeywordLoc());
+    if (!ToTemplateKeywordLocOrErr)
+      return ToTemplateKeywordLocOrErr.takeError();
+
     return UnresolvedLookupExpr::Create(
-        Importer.getToContext(), NamingClass,
-        Importer.Import(E->getQualifierLoc()),
-        Importer.Import(E->getTemplateKeywordLoc()), NameInfo, E->requiresADL(),
-        ResInfo, ToDecls.begin(), ToDecls.end());
+        Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
+        *ToTemplateKeywordLocOrErr, ToNameInfo, E->requiresADL(), &ToTAInfo,
+        ToDecls.begin(), ToDecls.end());
+  }
 
   return UnresolvedLookupExpr::Create(
-      Importer.getToContext(), NamingClass,
-      Importer.Import(E->getQualifierLoc()), NameInfo, E->requiresADL(),
-      E->isOverloaded(), ToDecls.begin(), ToDecls.end());
+      Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
+      ToNameInfo, E->requiresADL(), E->isOverloaded(), ToDecls.begin(),
+      ToDecls.end());
 }
 
-Expr *ASTNodeImporter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
-  DeclarationName Name = Importer.Import(E->getName());
-  if (!E->getName().isEmpty() && Name.isEmpty())
-    return nullptr;
-  DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc()));
-  // Import additional name location/type info.
-  ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+ExpectedStmt
+ASTNodeImporter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
+  auto Imp1 = importSeq(
+      E->getType(), E->getOperatorLoc(), E->getQualifierLoc(),
+      E->getTemplateKeywordLoc());
+  if (!Imp1)
+    return Imp1.takeError();
 
-  QualType BaseType = Importer.Import(E->getType());
-  if (!E->getType().isNull() && BaseType.isNull())
-    return nullptr;
+  QualType ToType;
+  SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  std::tie(ToType, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc) = *Imp1;
+
+  auto Imp2 = importSeq(E->getName(), E->getNameLoc());
+  if (!Imp2)
+    return Imp2.takeError();
+  DeclarationNameInfo ToNameInfo(std::get<0>(*Imp2), std::get<1>(*Imp2));
+  // Import additional name location/type info.
+  if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
+    return std::move(Err);
 
   UnresolvedSet<8> ToDecls;
-  for (Decl *D : E->decls()) {
-    if (NamedDecl *To = cast_or_null<NamedDecl>(Importer.Import(D)))
-      ToDecls.addDecl(To);
+  for (Decl *D : E->decls())
+    if (auto ToDOrErr = import(D))
+      ToDecls.addDecl(cast<NamedDecl>(*ToDOrErr));
     else
-      return nullptr;
-  }
+      return ToDOrErr.takeError();
 
   TemplateArgumentListInfo ToTAInfo;
   TemplateArgumentListInfo *ResInfo = nullptr;
   if (E->hasExplicitTemplateArgs()) {
-    if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
-      return nullptr;
+    if (Error Err =
+        ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+      return std::move(Err);
     ResInfo = &ToTAInfo;
   }
 
-  Expr *BaseE = E->isImplicitAccess() ? nullptr : Importer.Import(E->getBase());
-  if (!BaseE && !E->isImplicitAccess() && E->getBase()) {
-    return nullptr;
+  Expr *ToBase = nullptr;
+  if (!E->isImplicitAccess()) {
+    if (ExpectedExpr ToBaseOrErr = import(E->getBase()))
+      ToBase = *ToBaseOrErr;
+    else
+      return ToBaseOrErr.takeError();
   }
 
   return UnresolvedMemberExpr::Create(
-      Importer.getToContext(), E->hasUnresolvedUsing(), BaseE, BaseType,
-      E->isArrow(), Importer.Import(E->getOperatorLoc()),
-      Importer.Import(E->getQualifierLoc()),
-      Importer.Import(E->getTemplateKeywordLoc()), NameInfo, ResInfo,
-      ToDecls.begin(), ToDecls.end());
+      Importer.getToContext(), E->hasUnresolvedUsing(), ToBase, ToType,
+      E->isArrow(), ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
+      ToNameInfo, ResInfo, ToDecls.begin(), ToDecls.end());
 }
 
-Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCallExpr(CallExpr *E) {
+  auto Imp = importSeq(E->getCallee(), E->getType(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToCallee = Importer.Import(E->getCallee());
-  if (!ToCallee && E->getCallee())
-    return nullptr;
+  Expr *ToCallee;
+  QualType ToType;
+  SourceLocation ToRParenLoc;
+  std::tie(ToCallee, ToType, ToRParenLoc) = *Imp;
 
   unsigned NumArgs = E->getNumArgs();
-  SmallVector<Expr *, 2> ToArgs(NumArgs);
-  if (ImportContainerChecked(E->arguments(), ToArgs))
-     return nullptr;
-
-  auto **ToArgs_Copied = new (Importer.getToContext()) Expr*[NumArgs];
-
-  for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai)
-    ToArgs_Copied[ai] = ToArgs[ai];
+  llvm::SmallVector<Expr *, 2> ToArgs(NumArgs);
+  if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
+     return std::move(Err);
 
   if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
     return new (Importer.getToContext()) CXXOperatorCallExpr(
-          Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, T,
-          OCE->getValueKind(), Importer.Import(OCE->getRParenLoc()),
-          OCE->getFPFeatures());
+        Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, ToType,
+        OCE->getValueKind(), ToRParenLoc, OCE->getFPFeatures());
   }
 
-  return new (Importer.getToContext())
-    CallExpr(Importer.getToContext(), ToCallee,
-             llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(),
-             Importer.Import(E->getRParenLoc()));
+  return new (Importer.getToContext()) CallExpr(
+      Importer.getToContext(), ToCallee, ToArgs, ToType, E->getValueKind(),
+      ToRParenLoc);
 }
 
-Optional<LambdaCapture>
-ASTNodeImporter::ImportLambdaCapture(const LambdaCapture &From) {
-  VarDecl *Var = nullptr;
-  if (From.capturesVariable()) {
-    Var = cast_or_null<VarDecl>(Importer.Import(From.getCapturedVar()));
-    if (!Var)
-      return None;
-  }
-
-  return LambdaCapture(Importer.Import(From.getLocation()), From.isImplicit(),
-                       From.getCaptureKind(), Var,
-                       From.isPackExpansion()
-                         ? Importer.Import(From.getEllipsisLoc())
-                         : SourceLocation());
-}
-
-Expr *ASTNodeImporter::VisitLambdaExpr(LambdaExpr *LE) {
-  CXXRecordDecl *FromClass = LE->getLambdaClass();
-  auto *ToClass = dyn_cast_or_null<CXXRecordDecl>(Importer.Import(FromClass));
-  if (!ToClass)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
+  CXXRecordDecl *FromClass = E->getLambdaClass();
+  auto ToClassOrErr = import(FromClass);
+  if (!ToClassOrErr)
+    return ToClassOrErr.takeError();
+  CXXRecordDecl *ToClass = *ToClassOrErr;
 
   // NOTE: lambda classes are created with BeingDefined flag set up.
   // It means that ImportDefinition doesn't work for them and we should fill it
   // manually.
   if (ToClass->isBeingDefined()) {
     for (auto FromField : FromClass->fields()) {
-      auto *ToField = cast_or_null<FieldDecl>(Importer.Import(FromField));
-      if (!ToField)
-        return nullptr;
+      auto ToFieldOrErr = import(FromField);
+      if (!ToFieldOrErr)
+        return ToFieldOrErr.takeError();
     }
   }
 
-  auto *ToCallOp = dyn_cast_or_null<CXXMethodDecl>(
-        Importer.Import(LE->getCallOperator()));
-  if (!ToCallOp)
-    return nullptr;
+  auto ToCallOpOrErr = import(E->getCallOperator());
+  if (!ToCallOpOrErr)
+    return ToCallOpOrErr.takeError();
 
   ToClass->completeDefinition();
 
-  unsigned NumCaptures = LE->capture_size();
-  SmallVector<LambdaCapture, 8> Captures;
-  Captures.reserve(NumCaptures);
-  for (const auto &FromCapture : LE->captures()) {
-    if (auto ToCapture = ImportLambdaCapture(FromCapture))
-      Captures.push_back(*ToCapture);
+  SmallVector<LambdaCapture, 8> ToCaptures;
+  ToCaptures.reserve(E->capture_size());
+  for (const auto &FromCapture : E->captures()) {
+    if (auto ToCaptureOrErr = import(FromCapture))
+      ToCaptures.push_back(*ToCaptureOrErr);
     else
-      return nullptr;
+      return ToCaptureOrErr.takeError();
   }
 
-  SmallVector<Expr *, 8> InitCaptures(NumCaptures);
-  if (ImportContainerChecked(LE->capture_inits(), InitCaptures))
-    return nullptr;
+  SmallVector<Expr *, 8> ToCaptureInits(E->capture_size());
+  if (Error Err = ImportContainerChecked(E->capture_inits(), ToCaptureInits))
+    return std::move(Err);
+
+  auto Imp = importSeq(
+      E->getIntroducerRange(), E->getCaptureDefaultLoc(), E->getEndLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceRange ToIntroducerRange;
+  SourceLocation ToCaptureDefaultLoc, ToEndLoc;
+  std::tie(ToIntroducerRange, ToCaptureDefaultLoc, ToEndLoc) = *Imp;
 
   return LambdaExpr::Create(
-      Importer.getToContext(), ToClass,
-      Importer.Import(LE->getIntroducerRange()), LE->getCaptureDefault(),
-      Importer.Import(LE->getCaptureDefaultLoc()), Captures,
-      LE->hasExplicitParameters(), LE->hasExplicitResultType(), InitCaptures,
-      Importer.Import(LE->getEndLoc()), LE->containsUnexpandedParameterPack());
+      Importer.getToContext(), ToClass, ToIntroducerRange,
+      E->getCaptureDefault(), ToCaptureDefaultLoc, ToCaptures,
+      E->hasExplicitParameters(), E->hasExplicitResultType(), ToCaptureInits,
+      ToEndLoc, E->containsUnexpandedParameterPack());
 }
 
-Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) {
-  QualType T = Importer.Import(ILE->getType());
-  if (T.isNull())
-    return nullptr;
 
-  SmallVector<Expr *, 4> Exprs(ILE->getNumInits());
-  if (ImportContainerChecked(ILE->inits(), Exprs))
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitInitListExpr(InitListExpr *E) {
+  auto Imp = importSeq(E->getLBraceLoc(), E->getRBraceLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToLBraceLoc, ToRBraceLoc;
+  QualType ToType;
+  std::tie(ToLBraceLoc, ToRBraceLoc, ToType) = *Imp;
+
+  SmallVector<Expr *, 4> ToExprs(E->getNumInits());
+  if (Error Err = ImportContainerChecked(E->inits(), ToExprs))
+    return std::move(Err);
 
   ASTContext &ToCtx = Importer.getToContext();
   InitListExpr *To = new (ToCtx) InitListExpr(
-        ToCtx, Importer.Import(ILE->getLBraceLoc()),
-        Exprs, Importer.Import(ILE->getLBraceLoc()));
-  To->setType(T);
+      ToCtx, ToLBraceLoc, ToExprs, ToRBraceLoc);
+  To->setType(ToType);
 
-  if (ILE->hasArrayFiller()) {
-    Expr *Filler = Importer.Import(ILE->getArrayFiller());
-    if (!Filler)
-      return nullptr;
-    To->setArrayFiller(Filler);
+  if (E->hasArrayFiller()) {
+    if (ExpectedExpr ToFillerOrErr = import(E->getArrayFiller()))
+      To->setArrayFiller(*ToFillerOrErr);
+    else
+      return ToFillerOrErr.takeError();
   }
 
-  if (FieldDecl *FromFD = ILE->getInitializedFieldInUnion()) {
-    auto *ToFD = cast_or_null<FieldDecl>(Importer.Import(FromFD));
-    if (!ToFD)
-      return nullptr;
-    To->setInitializedFieldInUnion(ToFD);
+  if (FieldDecl *FromFD = E->getInitializedFieldInUnion()) {
+    if (auto ToFDOrErr = import(FromFD))
+      To->setInitializedFieldInUnion(*ToFDOrErr);
+    else
+      return ToFDOrErr.takeError();
   }
 
-  if (InitListExpr *SyntForm = ILE->getSyntacticForm()) {
-    auto *ToSyntForm = cast_or_null<InitListExpr>(Importer.Import(SyntForm));
-    if (!ToSyntForm)
-      return nullptr;
-    To->setSyntacticForm(ToSyntForm);
+  if (InitListExpr *SyntForm = E->getSyntacticForm()) {
+    if (auto ToSyntFormOrErr = import(SyntForm))
+      To->setSyntacticForm(*ToSyntFormOrErr);
+    else
+      return ToSyntFormOrErr.takeError();
   }
 
   // Copy InitListExprBitfields, which are not handled in the ctor of
   // InitListExpr.
-  To->sawArrayRangeDesignator(ILE->hadArrayRangeDesignator());
+  To->sawArrayRangeDesignator(E->hadArrayRangeDesignator());
 
   return To;
 }
 
-Expr *ASTNodeImporter::VisitCXXStdInitializerListExpr(
+ExpectedStmt ASTNodeImporter::VisitCXXStdInitializerListExpr(
     CXXStdInitializerListExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
 
-  Expr *SE = Importer.Import(E->getSubExpr());
-  if (!SE)
-    return nullptr;
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
 
-  return new (Importer.getToContext()) CXXStdInitializerListExpr(T, SE);
+  return new (Importer.getToContext()) CXXStdInitializerListExpr(
+      *ToTypeOrErr, *ToSubExprOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCXXInheritedCtorInitExpr(
+ExpectedStmt ASTNodeImporter::VisitCXXInheritedCtorInitExpr(
     CXXInheritedCtorInitExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  auto Imp = importSeq(E->getLocation(), E->getType(), E->getConstructor());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *Ctor = cast_or_null<CXXConstructorDecl>(Importer.Import(
-      E->getConstructor()));
-  if (!Ctor)
-    return nullptr;
+  SourceLocation ToLocation;
+  QualType ToType;
+  CXXConstructorDecl *ToConstructor;
+  std::tie(ToLocation, ToType, ToConstructor) = *Imp;
 
   return new (Importer.getToContext()) CXXInheritedCtorInitExpr(
-      Importer.Import(E->getLocation()), T, Ctor,
-      E->constructsVBase(), E->inheritedFromVBase());
+      ToLocation, ToType, ToConstructor, E->constructsVBase(),
+      E->inheritedFromVBase());
 }
 
-Expr *ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
-  QualType ToType = Importer.Import(E->getType());
-  if (ToType.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
+  auto Imp = importSeq(E->getType(), E->getCommonExpr(), E->getSubExpr());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToCommon = Importer.Import(E->getCommonExpr());
-  if (!ToCommon && E->getCommonExpr())
-    return nullptr;
+  QualType ToType;
+  Expr *ToCommonExpr, *ToSubExpr;
+  std::tie(ToType, ToCommonExpr, ToSubExpr) = *Imp;
 
-  Expr *ToSubExpr = Importer.Import(E->getSubExpr());
-  if (!ToSubExpr && E->getSubExpr())
-    return nullptr;
-
-  return new (Importer.getToContext())
-      ArrayInitLoopExpr(ToType, ToCommon, ToSubExpr);
+  return new (Importer.getToContext()) ArrayInitLoopExpr(
+      ToType, ToCommonExpr, ToSubExpr);
 }
 
-Expr *ASTNodeImporter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
-  QualType ToType = Importer.Import(E->getType());
-  if (ToType.isNull())
-    return nullptr;
-  return new (Importer.getToContext()) ArrayInitIndexExpr(ToType);
+ExpectedStmt ASTNodeImporter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
+  return new (Importer.getToContext()) ArrayInitIndexExpr(*ToTypeOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
-  auto *ToField = dyn_cast_or_null<FieldDecl>(Importer.Import(DIE->getField()));
-  if (!ToField && DIE->getField())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
+  ExpectedSLoc ToBeginLocOrErr = import(E->getBeginLoc());
+  if (!ToBeginLocOrErr)
+    return ToBeginLocOrErr.takeError();
+
+  auto ToFieldOrErr = import(E->getField());
+  if (!ToFieldOrErr)
+    return ToFieldOrErr.takeError();
 
   return CXXDefaultInitExpr::Create(
-      Importer.getToContext(), Importer.Import(DIE->getBeginLoc()), ToField);
+      Importer.getToContext(), *ToBeginLocOrErr, *ToFieldOrErr);
 }
 
-Expr *ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
-  QualType ToType = Importer.Import(E->getType());
-  if (ToType.isNull() && !E->getType().isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getSubExpr(), E->getTypeInfoAsWritten(),
+      E->getOperatorLoc(), E->getRParenLoc(), E->getAngleBrackets());
+  if (!Imp)
+    return Imp.takeError();
+
+  QualType ToType;
+  Expr *ToSubExpr;
+  TypeSourceInfo *ToTypeInfoAsWritten;
+  SourceLocation ToOperatorLoc, ToRParenLoc;
+  SourceRange ToAngleBrackets;
+  std::tie(
+      ToType, ToSubExpr, ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc,
+      ToAngleBrackets) = *Imp;
+
   ExprValueKind VK = E->getValueKind();
   CastKind CK = E->getCastKind();
-  Expr *ToOp = Importer.Import(E->getSubExpr());
-  if (!ToOp && E->getSubExpr())
-    return nullptr;
-  CXXCastPath BasePath;
-  if (ImportCastPath(E, BasePath))
-    return nullptr;
-  TypeSourceInfo *ToWritten = Importer.Import(E->getTypeInfoAsWritten());
-  SourceLocation ToOperatorLoc = Importer.Import(E->getOperatorLoc());
-  SourceLocation ToRParenLoc = Importer.Import(E->getRParenLoc());
-  SourceRange ToAngleBrackets = Importer.Import(E->getAngleBrackets());
+  auto ToBasePathOrErr = ImportCastPath(E);
+  if (!ToBasePathOrErr)
+    return ToBasePathOrErr.takeError();
 
   if (isa<CXXStaticCastExpr>(E)) {
     return CXXStaticCastExpr::Create(
-        Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath,
-        ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
+        Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
+        ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
   } else if (isa<CXXDynamicCastExpr>(E)) {
     return CXXDynamicCastExpr::Create(
-        Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath,
-        ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
+        Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
+        ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
   } else if (isa<CXXReinterpretCastExpr>(E)) {
     return CXXReinterpretCastExpr::Create(
-        Importer.getToContext(), ToType, VK, CK, ToOp, &BasePath,
-        ToWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
+        Importer.getToContext(), ToType, VK, CK, ToSubExpr, &(*ToBasePathOrErr),
+        ToTypeInfoAsWritten, ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
   } else if (isa<CXXConstCastExpr>(E)) {
-    return CXXConstCastExpr::Create(Importer.getToContext(), ToType, VK, ToOp,
-                                    ToWritten, ToOperatorLoc, ToRParenLoc,
-                                    ToAngleBrackets);
+    return CXXConstCastExpr::Create(
+        Importer.getToContext(), ToType, VK, ToSubExpr, ToTypeInfoAsWritten,
+        ToOperatorLoc, ToRParenLoc, ToAngleBrackets);
   } else {
-    return nullptr;
+    llvm_unreachable("Unknown cast type");
+    return make_error<ImportError>();
   }
 }
 
-Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
+ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
     SubstNonTypeTemplateParmExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  auto Imp = importSeq(
+      E->getType(), E->getExprLoc(), E->getParameter(), E->getReplacement());
+  if (!Imp)
+    return Imp.takeError();
 
-  auto *Param = cast_or_null<NonTypeTemplateParmDecl>(
-        Importer.Import(E->getParameter()));
-  if (!Param)
-    return nullptr;
-
-  Expr *Replacement = Importer.Import(E->getReplacement());
-  if (!Replacement)
-    return nullptr;
+  QualType ToType;
+  SourceLocation ToExprLoc;
+  NonTypeTemplateParmDecl *ToParameter;
+  Expr *ToReplacement;
+  std::tie(ToType, ToExprLoc, ToParameter, ToReplacement) = *Imp;
 
   return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
-        T, E->getValueKind(), Importer.Import(E->getExprLoc()), Param,
-        Replacement);
+      ToType, E->getValueKind(), ToExprLoc, ToParameter, ToReplacement);
 }
 
-Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
-  QualType ToType = Importer.Import(E->getType());
-  if (ToType.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getBeginLoc(), E->getEndLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  QualType ToType;
+  SourceLocation ToBeginLoc, ToEndLoc;
+  std::tie(ToType, ToBeginLoc, ToEndLoc) = *Imp;
 
   SmallVector<TypeSourceInfo *, 4> ToArgs(E->getNumArgs());
-  if (ImportContainerChecked(E->getArgs(), ToArgs))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(E->getArgs(), ToArgs))
+    return std::move(Err);
 
   // According to Sema::BuildTypeTrait(), if E is value-dependent,
   // Value is always false.
-  bool ToValue = false;
-  if (!E->isValueDependent())
-    ToValue = E->getValue();
+  bool ToValue = (E->isValueDependent() ? false : E->getValue());
 
   return TypeTraitExpr::Create(
-      Importer.getToContext(), ToType, Importer.Import(E->getBeginLoc()),
-      E->getTrait(), ToArgs, Importer.Import(E->getEndLoc()), ToValue);
+      Importer.getToContext(), ToType, ToBeginLoc, E->getTrait(), ToArgs,
+      ToEndLoc, ToValue);
 }
 
-Expr *ASTNodeImporter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
-  QualType ToType = Importer.Import(E->getType());
-  if (ToType.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
+
+  auto ToSourceRangeOrErr = import(E->getSourceRange());
+  if (!ToSourceRangeOrErr)
+    return ToSourceRangeOrErr.takeError();
 
   if (E->isTypeOperand()) {
-    TypeSourceInfo *TSI = Importer.Import(E->getTypeOperandSourceInfo());
-    if (!TSI)
-      return nullptr;
-
-    return new (Importer.getToContext())
-        CXXTypeidExpr(ToType, TSI, Importer.Import(E->getSourceRange()));
+    if (auto ToTSIOrErr = import(E->getTypeOperandSourceInfo()))
+      return new (Importer.getToContext()) CXXTypeidExpr(
+          *ToTypeOrErr, *ToTSIOrErr, *ToSourceRangeOrErr);
+    else
+      return ToTSIOrErr.takeError();
   }
 
-  Expr *Op = Importer.Import(E->getExprOperand());
-  if (!Op)
-    return nullptr;
+  ExpectedExpr ToExprOperandOrErr = import(E->getExprOperand());
+  if (!ToExprOperandOrErr)
+    return ToExprOperandOrErr.takeError();
 
-  return new (Importer.getToContext())
-      CXXTypeidExpr(ToType, Op, Importer.Import(E->getSourceRange()));
+  return new (Importer.getToContext()) CXXTypeidExpr(
+      *ToTypeOrErr, *ToExprOperandOrErr, *ToSourceRangeOrErr);
 }
 
 void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
                                       CXXMethodDecl *FromMethod) {
-  for (auto *FromOverriddenMethod : FromMethod->overridden_methods())
-    ToMethod->addOverriddenMethod(
-      cast<CXXMethodDecl>(Importer.Import(const_cast<CXXMethodDecl*>(
-                                            FromOverriddenMethod))));
+  for (auto *FromOverriddenMethod : FromMethod->overridden_methods()) {
+    if (auto ImportedOrErr = import(FromOverriddenMethod))
+      ToMethod->getCanonicalDecl()->addOverriddenMethod(cast<CXXMethodDecl>(
+          (*ImportedOrErr)->getCanonicalDecl()));
+    else
+      consumeError(ImportedOrErr.takeError());
+  }
 }
 
 ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
@@ -7025,24 +7660,26 @@
   if (FromT.isNull())
     return {};
 
-  const Type *fromTy = FromT.getTypePtr();
+  const Type *FromTy = FromT.getTypePtr();
 
   // Check whether we've already imported this type.
   llvm::DenseMap<const Type *, const Type *>::iterator Pos
-    = ImportedTypes.find(fromTy);
+    = ImportedTypes.find(FromTy);
   if (Pos != ImportedTypes.end())
     return ToContext.getQualifiedType(Pos->second, FromT.getLocalQualifiers());
 
   // Import the type
   ASTNodeImporter Importer(*this);
-  QualType ToT = Importer.Visit(fromTy);
-  if (ToT.isNull())
-    return ToT;
+  ExpectedType ToTOrErr = Importer.Visit(FromTy);
+  if (!ToTOrErr) {
+    llvm::consumeError(ToTOrErr.takeError());
+    return {};
+  }
 
   // Record the imported type.
-  ImportedTypes[fromTy] = ToT.getTypePtr();
+  ImportedTypes[FromTy] = (*ToTOrErr).getTypePtr();
 
-  return ToContext.getQualifiedType(ToT, FromT.getLocalQualifiers());
+  return ToContext.getQualifiedType(*ToTOrErr, FromT.getLocalQualifiers());
 }
 
 TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
@@ -7070,7 +7707,8 @@
   if (Pos != ImportedDecls.end()) {
     Decl *ToD = Pos->second;
     // FIXME: move this call to ImportDeclParts().
-    ASTNodeImporter(*this).ImportDefinitionIfNeeded(FromD, ToD);
+    if (Error Err = ASTNodeImporter(*this).ImportDefinitionIfNeeded(FromD, ToD))
+      llvm::consumeError(std::move(Err));
     return ToD;
   } else {
     return nullptr;
@@ -7092,9 +7730,12 @@
   }
 
   // Import the type.
-  ToD = Importer.Visit(FromD);
-  if (!ToD)
+  ExpectedDecl ToDOrErr = Importer.Visit(FromD);
+  if (!ToDOrErr) {
+    llvm::consumeError(ToDOrErr.takeError());
     return nullptr;
+  }
+  ToD = *ToDOrErr;
 
   // Notify subclasses.
   Imported(FromD, ToD);
@@ -7103,7 +7744,7 @@
   return ToD;
 }
 
-DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
+Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
   if (!FromDC)
     return FromDC;
 
@@ -7118,8 +7759,9 @@
     if (ToRecord->isCompleteDefinition()) {
       // Do nothing.
     } else if (FromRecord->isCompleteDefinition()) {
-      ASTNodeImporter(*this).ImportDefinition(FromRecord, ToRecord,
-                                              ASTNodeImporter::IDK_Basic);
+      if (Error Err = ASTNodeImporter(*this).ImportDefinition(
+          FromRecord, ToRecord, ASTNodeImporter::IDK_Basic))
+        return std::move(Err);
     } else {
       CompleteDecl(ToRecord);
     }
@@ -7128,8 +7770,9 @@
     if (ToEnum->isCompleteDefinition()) {
       // Do nothing.
     } else if (FromEnum->isCompleteDefinition()) {
-      ASTNodeImporter(*this).ImportDefinition(FromEnum, ToEnum,
-                                              ASTNodeImporter::IDK_Basic);
+      if (Error Err = ASTNodeImporter(*this).ImportDefinition(
+          FromEnum, ToEnum, ASTNodeImporter::IDK_Basic))
+        return std::move(Err);
     } else {
       CompleteDecl(ToEnum);
     }
@@ -7138,8 +7781,9 @@
     if (ToClass->getDefinition()) {
       // Do nothing.
     } else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) {
-      ASTNodeImporter(*this).ImportDefinition(FromDef, ToClass,
-                                              ASTNodeImporter::IDK_Basic);
+      if (Error Err = ASTNodeImporter(*this).ImportDefinition(
+          FromDef, ToClass, ASTNodeImporter::IDK_Basic))
+        return std::move(Err);
     } else {
       CompleteDecl(ToClass);
     }
@@ -7148,8 +7792,9 @@
     if (ToProto->getDefinition()) {
       // Do nothing.
     } else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) {
-      ASTNodeImporter(*this).ImportDefinition(FromDef, ToProto,
-                                              ASTNodeImporter::IDK_Basic);
+      if (Error Err = ASTNodeImporter(*this).ImportDefinition(
+          FromDef, ToProto, ASTNodeImporter::IDK_Basic))
+        return std::move(Err);
     } else {
       CompleteDecl(ToProto);
     }
@@ -7174,13 +7819,15 @@
   if (Pos != ImportedStmts.end())
     return Pos->second;
 
-  // Import the type
+  // Import the statement.
   ASTNodeImporter Importer(*this);
-  Stmt *ToS = Importer.Visit(FromS);
-  if (!ToS)
+  ExpectedStmt ToSOrErr = Importer.Visit(FromS);
+  if (!ToSOrErr) {
+    llvm::consumeError(ToSOrErr.takeError());
     return nullptr;
+  }
 
-  if (auto *ToE = dyn_cast<Expr>(ToS)) {
+  if (auto *ToE = dyn_cast<Expr>(*ToSOrErr)) {
     auto *FromE = cast<Expr>(FromS);
     // Copy ExprBitfields, which may not be handled in Expr subclasses
     // constructors.
@@ -7194,8 +7841,8 @@
   }
 
   // Record the imported declaration.
-  ImportedStmts[FromS] = ToS;
-  return ToS;
+  ImportedStmts[FromS] = *ToSOrErr;
+  return *ToSOrErr;
 }
 
 NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
@@ -7398,12 +8045,14 @@
       return {};
 
     ASTNodeImporter Importer(*this);
-    TemplateArgument ArgPack
+    Expected<TemplateArgument> ArgPack
       = Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
-    if (ArgPack.isNull())
+    if (!ArgPack) {
+      llvm::consumeError(ArgPack.takeError());
       return {};
+    }
 
-    return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack);
+    return ToContext.getSubstTemplateTemplateParmPack(Param, *ArgPack);
   }
   }
 
@@ -7545,48 +8194,54 @@
   return Imported;
 }
 
-void ASTImporter::ImportDefinition(Decl *From) {
+Error ASTImporter::ImportDefinition_New(Decl *From) {
   Decl *To = Import(From);
   if (!To)
-    return;
+    return llvm::make_error<ImportError>();
 
   if (auto *FromDC = cast<DeclContext>(From)) {
     ASTNodeImporter Importer(*this);
 
     if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
       if (!ToRecord->getDefinition()) {
-        Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord,
-                                  ASTNodeImporter::IDK_Everything);
-        return;
+        return Importer.ImportDefinition(
+            cast<RecordDecl>(FromDC), ToRecord,
+            ASTNodeImporter::IDK_Everything);
       }
     }
 
     if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
       if (!ToEnum->getDefinition()) {
-        Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum,
-                                  ASTNodeImporter::IDK_Everything);
-        return;
+        return Importer.ImportDefinition(
+            cast<EnumDecl>(FromDC), ToEnum, ASTNodeImporter::IDK_Everything);
       }
     }
 
     if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
       if (!ToIFace->getDefinition()) {
-        Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace,
-                                  ASTNodeImporter::IDK_Everything);
-        return;
+        return Importer.ImportDefinition(
+            cast<ObjCInterfaceDecl>(FromDC), ToIFace,
+            ASTNodeImporter::IDK_Everything);
       }
     }
 
     if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
       if (!ToProto->getDefinition()) {
-        Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto,
-                                  ASTNodeImporter::IDK_Everything);
-        return;
+        return Importer.ImportDefinition(
+            cast<ObjCProtocolDecl>(FromDC), ToProto,
+            ASTNodeImporter::IDK_Everything);
       }
     }
 
-    Importer.ImportDeclContext(FromDC, true);
+    return Importer.ImportDeclContext(FromDC, true);
   }
+
+  return Error::success();
+}
+
+void ASTImporter::ImportDefinition(Decl *From) {
+  Error Err = ImportDefinition_New(From);
+  llvm::consumeError(std::move(Err));
 }
 
 DeclarationName ASTImporter::Import(DeclarationName FromName) {
