r344783 - [ASTImporter] Added error handling for AST import.

Balazs Keri via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 19 06:32:20 PDT 2018


Author: balazske
Date: Fri Oct 19 06:32:20 2018
New Revision: 344783

URL: http://llvm.org/viewvc/llvm-project?rev=344783&view=rev
Log:
[ASTImporter] Added error handling for AST import.

Summary:
The goal of this change is to make the ASTImporter::Import functions return
llvm::Expected instead of the imported type.
As first part the ASTNodeImporter visit functions are updated to return with
llvm::Expected. Various `import` functions are added to ASTNodeImporter to
simplify the code and have a common place for interface towards ASTImporter
(from ASTNodeImporter). There is some temporary code that is needed before
ASTImporter is updated.

Reviewers: a.sidorin, a_sidorin, xazax.hun

Reviewed By: a_sidorin

Subscribers: dkrupp, Szelethus, rnkovacs, martong, jfb, cfe-commits

Differential Revision: https://reviews.llvm.org/D51633

Modified:
    cfe/trunk/include/clang/AST/ASTImporter.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/ExternalASTMerger.cpp
    cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=344783&r1=344782&r2=344783&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Fri Oct 19 06:32:20 2018
@@ -25,7 +25,9 @@
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Error.h"
 #include <utility>
 
 namespace clang {
@@ -43,6 +45,29 @@ class TagDecl;
 class TypeSourceInfo;
 class Attr;
 
+  class ImportError : public llvm::ErrorInfo<ImportError> {
+  public:
+    /// \brief Kind of error when importing an AST component.
+    enum ErrorKind {
+        NameConflict, /// Naming ambiguity (likely ODR violation).
+        UnsupportedConstruct, /// Not supported node or case.
+        Unknown /// Other error.
+    };
+
+    ErrorKind Error;
+
+    static char ID;
+
+    ImportError() : Error(Unknown) { }
+    ImportError(const ImportError &Other) : Error(Other.Error) { }
+    ImportError(ErrorKind Error) : Error(Error) { }
+
+    std::string toString() const;
+
+    void log(raw_ostream &OS) const override;
+    std::error_code convertToErrorCode() const override;
+  };
+
   // \brief Returns with a list of declarations started from the canonical decl
   // then followed by subsequent decls in the translation unit.
   // This gives a canonical list for each entry in the redecl chain.
@@ -122,6 +147,24 @@ class Attr;
     /// to-be-completed forward declarations when possible.
     bool isMinimalImport() const { return Minimal; }
 
+    /// \brief Import the given object, returns the result.
+    ///
+    /// \param To Import the object into this variable.
+    /// \param From Object to import.
+    /// \return Error information (success or error).
+    template <typename ImportT>
+    LLVM_NODISCARD llvm::Error importInto(ImportT &To, const ImportT &From) {
+      To = Import(From);
+      if (From && !To)
+          return llvm::make_error<ImportError>();
+      return llvm::Error::success();
+      // FIXME: this should be the final code
+      //auto ToOrErr = Import(From);
+      //if (ToOrErr)
+      //  To = *ToOrErr;
+      //return ToOrErr.takeError();
+    }
+
     /// Import the given type from the "from" context into the "to"
     /// context.
     ///
@@ -161,8 +204,8 @@ class Attr;
     /// AST context into the "to" AST context.
     ///
     /// \returns the equivalent declaration context in the "to"
-    /// context, or a NULL type if an error occurred.
-    DeclContext *ImportContext(DeclContext *FromDC);
+    /// context, or error value.
+    llvm::Expected<DeclContext *> ImportContext(DeclContext *FromDC);
 
     /// Import the given expression from the "from" context into the
     /// "to" context.
@@ -220,7 +263,8 @@ class Attr;
     /// Import the given identifier from the "from" context
     /// into the "to" context.
     ///
-    /// \returns the equivalent identifier in the "to" context.
+    /// \returns the equivalent identifier in the "to" context. Note: It
+    /// returns nullptr only if the FromId was nullptr.
     IdentifierInfo *Import(const IdentifierInfo *FromId);
 
     /// Import the given Objective-C selector from the "from"
@@ -251,8 +295,10 @@ class Attr;
 
     /// Import the definition of the given declaration, including all of
     /// the declarations it contains.
-    ///
-    /// This routine is intended to be used
+    LLVM_NODISCARD llvm::Error ImportDefinition_New(Decl *From);
+
+    // FIXME: Compatibility function.
+    // Usages of this should be changed to ImportDefinition_New.
     void ImportDefinition(Decl *From);
 
     /// Cope with a name conflict when importing a declaration into the
@@ -336,9 +382,9 @@ class Attr;
 
     /// Determine the index of a field in its parent record.
     /// F should be a field (or indirect field) declaration.
-    /// \returns The index of the field in its parent context, starting from 1.
-    /// 0 is returned on error (parent context is non-record).
-    static unsigned getFieldIndex(Decl *F);
+    /// \returns The index of the field in its parent context (starting from 0).
+    /// On error `None` is returned (parent context is non-record).
+    static llvm::Optional<unsigned> getFieldIndex(Decl *F);
 
   };
 

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=344783&r1=344782&r2=344783&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Fri Oct 19 06:32:20 2018
@@ -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.");
-
-    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;
+  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>;
+
+  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.");
+  void ImportError::log(raw_ostream &OS) const {
+    OS << toString();
+  }
 
-    return 0;
+  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 @@ namespace clang {
       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 @@ namespace clang {
     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 @@ namespace clang {
   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 @@ namespace clang {
              (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 @@ namespace clang {
     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);
-
-    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(
+    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);
+
+    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);
-                     });
-    }
-
-    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;
+      for (; Ibegin != Iend; ++Ibegin, ++Obegin) {
+        Expected<ItemT> ToOrErr = import(*Ibegin);
+        if (!ToOrErr)
+          return ToOrErr.takeError();
+        *Obegin = *ToOrErr;
+      }
+      return Error::success();
     }
 
+    // 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 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();
 
-  return std::make_tuple(Template, ToTemplArgs);
+  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 @@ ASTNodeImporter::ImportFunctionTemplateW
 
 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 @@ QualType ASTNodeImporter::VisitBuiltinTy
   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();
+
+  ExpectedType ClassTypeOrErr = import(QualType(T->getClass(), 0));
+  if (!ClassTypeOrErr)
+    return ClassTypeOrErr.takeError();
 
-  QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
-  return Importer.getToContext().getMemberPointerType(ToPointeeType,
-                                                      ClassType.getTypePtr());
+  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 {};
-
-  Expr *Size = Importer.Import(T->getSizeExpr());
-  if (!Size)
-    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();
 
-  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 @@ QualType ASTNodeImporter::VisitFunctionP
   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 {};
-
-  auto *ToPrevD =
-      cast_or_null<UnresolvedUsingTypenameDecl>(
-        Importer.Import(T->getDecl()->getPreviousDecl()));
-  if (!ToPrevD && T->getDecl()->getPreviousDecl())
-    return {};
+  UnresolvedUsingTypenameDecl *ToD;
+  Decl *ToPrevD;
+  if (auto Imp = importSeq(T->getDecl(), T->getDecl()->getPreviousDecl()))
+    std::tie(ToD, ToPrevD) = *Imp;
+  else
+    return Imp.takeError();
 
-  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 {};
-
-  QualType InjType = Importer.Import(T->getInjectedSpecializationType());
-  if (InjType.isNull())
-    return {};
+  Expected<CXXRecordDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
+
+  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 @@ QualType ASTNodeImporter::VisitInjectedC
   };
 
   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 {};
-
-  QualType Replacement = Importer.Import(T->getReplacementType());
-  if (Replacement.isNull())
-    return {};
-  Replacement = Replacement.getCanonicalType();
+  ExpectedType ReplacedOrErr = import(QualType(T->getReplacedParameter(), 0));
+  if (!ReplacedOrErr)
+    return ReplacedOrErr.takeError();
+  const TemplateTypeParmType *Replaced =
+      cast<TemplateTypeParmType>((*ReplacedOrErr).getTypePtr());
+
+  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 {};
-  }
-
-  QualType ToNamedType = Importer.Import(T->getNamedType());
-  if (ToNamedType.isNull())
-    return {};
-
-  TagDecl *OwnedTagDecl =
-      cast_or_null<TagDecl>(Importer.Import(T->getOwnedTagDecl()));
-  if (!OwnedTagDecl && T->getOwnedTagDecl())
-    return {};
+  auto ToQualifierOrErr = import(T->getQualifier());
+  if (!ToQualifierOrErr)
+    return ToQualifierOrErr.takeError();
+
+  ExpectedType ToNamedTypeOrErr = import(T->getNamedType());
+  if (!ToNamedTypeOrErr)
+    return ToNamedTypeOrErr.takeError();
+
+  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 {};
-
-  return Importer.getToContext().getObjCInterfaceType(Class);
+ExpectedType
+ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
+  Expected<ObjCInterfaceDecl *> ToDeclOrErr = import(T->getDecl());
+  if (!ToDeclOrErr)
+    return ToDeclOrErr.takeError();
+
+  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 @@ bool ASTNodeImporter::ImportDeclParts(Na
       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 @@ ASTNodeImporter::ImportDeclarationNameLo
   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());
+  }
+
+  return Error::success();
+}
+
+Error ASTNodeImporter::ImportDeclContext(
+    Decl *FromD, DeclContext *&ToDC, DeclContext *&ToLexicalDC) {
+  auto ToDCOrErr = Importer.ImportContext(FromD->getDeclContext());
+  if (!ToDCOrErr)
+    return ToDCOrErr.takeError();
+  ToDC = *ToDCOrErr;
 
-  for (auto *From : FromDC->decls())
-    Importer.Import(From);
+  if (FromD->getDeclContext() != FromD->getLexicalDeclContext()) {
+    auto ToLexicalDCOrErr = Importer.ImportContext(
+        FromD->getLexicalDeclContext());
+    if (!ToLexicalDCOrErr)
+      return ToLexicalDCOrErr.takeError();
+    ToLexicalDC = *ToLexicalDCOrErr;
+  } else
+    ToLexicalDC = ToDC;
+
+  return Error::success();
 }
 
-void ASTNodeImporter::ImportImplicitMethods(
+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 @@ bool ASTNodeImporter::ImportDefinition(R
 
     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 @@ bool ASTNodeImporter::ImportInitializer(
   }
 
   // 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);
-
-  QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
-  if (T.isNull())
-    return true;
+  if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
+    return Err;
 
-  QualType ToPromotionType = Importer.Import(From->getPromotionType());
-  if (ToPromotionType.isNull())
-    return true;
+  ExpectedType ToTypeOrErr =
+      import(Importer.getFromContext().getTypeDeclType(From));
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
+
+  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);
-}
-
-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);
+  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);
+}
+
+Error ASTNodeImporter::ImportTemplateArguments(
+    const TemplateArgument *FromArgs, unsigned NumFromArgs,
+    SmallVectorImpl<TemplateArgument> &ToArgs) {
+  for (unsigned I = 0; I != NumFromArgs; ++I) {
+    if (auto ToOrErr = import(FromArgs[I]))
+      ToArgs.push_back(*ToOrErr);
     else
-      return None;
-  } else {
-    ToInfo = TemplateArgumentLocInfo(
-          Importer.Import(FromInfo.getTemplateQualifierLoc()),
-          Importer.Import(FromInfo.getTemplateNameLoc()),
-          Importer.Import(FromInfo.getTemplateEllipsisLoc()));
+      return ToOrErr.takeError();
   }
-  return TemplateArgumentLoc(Arg, ToInfo);
-}
-
-bool 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);
-  }
+  return Error::success();
+}
 
-  return false;
+// FIXME: Do not forget to remove this and use only 'import'.
+Expected<TemplateArgument>
+ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
+  return import(From);
 }
 
-// We cannot use Optional<> pattern here and below because
-// TemplateArgumentListInfo's operator new is declared as deleted so it cannot
-// be stored in Optional.
 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 @@ bool ASTNodeImporter::IsStructuralMatch(
   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 @@ Decl *ASTNodeImporter::VisitEmptyDecl(Em
   return ToD;
 }
 
-Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
   TranslationUnitDecl *ToD =
     Importer.getToContext().getTranslationUnitDecl();
 
@@ -1760,18 +2111,23 @@ Decl *ASTNodeImporter::VisitTranslationU
   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 @@ Decl *ASTNodeImporter::VisitAccessSpecDe
   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 @@ Decl *ASTNodeImporter::VisitStaticAssert
   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 @@ Decl *ASTNodeImporter::VisitNamespaceDec
       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 @@ Decl *ASTNodeImporter::VisitNamespaceDec
   }
   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 @@ Decl *ASTNodeImporter::VisitNamespaceAli
   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 @@ Decl *ASTNodeImporter::VisitTypedefNameD
       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 @@ Decl *ASTNodeImporter::VisitTypedefNameD
                                          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 @@ Decl *ASTNodeImporter::VisitTypedefNameD
   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 @@ Decl *ASTNodeImporter::VisitTypeAliasTem
                                          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 @@ Decl *ASTNodeImporter::VisitTypeAliasTem
   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;
+
+  }
+
+  Expected<LabelStmt *> ToStmtOrErr = import(D->getStmt());
+  if (!ToStmtOrErr)
+    return ToStmtOrErr.takeError();
 
-  ToLabel->setStmt(Label);
+  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 @@ Decl *ASTNodeImporter::VisitEnumDecl(Enu
   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 @@ Decl *ASTNodeImporter::VisitEnumDecl(Enu
       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 @@ Decl *ASTNodeImporter::VisitEnumDecl(Enu
       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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
       // 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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
   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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
   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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
       }
 
       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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
           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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
               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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
 
           if (FoundRecord->isCompleteDefinition() &&
               D->isCompleteDefinition() &&
-              !IsStructuralMatch(D, FoundRecord))
-            continue;
-
-          if (IsFriendTemplate)
+              !IsStructuralMatch(D, FoundRecord)) {
+            ConflictingDecls.push_back(FoundDecl);
             continue;
+          }
 
           AdoptDecl = FoundRecord;
           continue;
-        } else if (!SearchName) {
-          continue;
         }
-      }
+
+        continue;
+      } else if (isa<ValueDecl>(Found))
+        continue;
 
       ConflictingDecls.push_back(FoundDecl);
     }
@@ -2317,33 +2699,40 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
       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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
             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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
 
       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 @@ Decl *ASTNodeImporter::VisitRecordDecl(R
         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 @@ Decl *ASTNodeImporter::VisitEnumConstant
                                          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 @@ Decl *ASTNodeImporter::VisitEnumConstant
   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;
-
-    SourceLocation POI = Importer.Import(FTSInfo->getPointOfInstantiation());
+      if (Error Err = ImportTemplateArgumentListInfo(
+          *FromTAArgsAsWritten, ToTAInfo))
+        return Err;
+
+    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 @@ bool ASTNodeImporter::ImportTemplateInfo
     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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
   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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
   // 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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
                                          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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
     }
   }
 
-  // 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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
     }
   } 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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
 
   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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
   }
 
   // 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 @@ Decl *ASTNodeImporter::VisitFunctionDecl
   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 @@ Decl *ASTNodeImporter::VisitFieldDecl(Fi
   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 @@ Decl *ASTNodeImporter::VisitFieldDecl(Fi
           // 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 @@ Decl *ASTNodeImporter::VisitIndirectFiel
       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 @@ Decl *ASTNodeImporter::VisitIndirectFiel
   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 @@ Decl *ASTNodeImporter::VisitFriendDecl(F
   // 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 @@ Decl *ASTNodeImporter::VisitFriendDecl(F
   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 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl
   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 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl
         << 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 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl
   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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
   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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
             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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
                                          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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
     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 @@ Decl *ASTNodeImporter::VisitVarDecl(VarD
     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;
-
-  // 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, 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();
 
-  // 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 @@ Decl *ASTNodeImporter::VisitParmVarDecl(
   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 @@ Decl *ASTNodeImporter::VisitParmVarDecl(
   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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
         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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
         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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
             << (*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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
         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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
     }
   }
 
-  // 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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
   // 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 @@ Decl *ASTNodeImporter::VisitObjCMethodDe
     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 @@ Decl *ASTNodeImporter::VisitObjCCategory
                                           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 @@ bool ASTNodeImporter::ImportDefinition(O
   // 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 @@ bool ASTNodeImporter::ImportDefinition(O
 
   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 @@ Decl *ASTNodeImporter::VisitObjCProtocol
   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 @@ Decl *ASTNodeImporter::VisitObjCProtocol
 
   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 @@ Decl *ASTNodeImporter::VisitObjCProtocol
 
   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 @@ Decl *ASTNodeImporter::VisitLinkageSpecD
   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 @@ Decl *ASTNodeImporter::VisitUsingDecl(Us
 
   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;
-
-  auto *ToTarget = dyn_cast_or_null<NamedDecl>(
-      Importer.Import(D->getTargetDecl()));
-  if (!ToTarget)
-    return nullptr;
+  Expected<UsingDecl *> ToUsingOrErr = import(D->getUsingDecl());
+  if (!ToUsingOrErr)
+    return ToUsingOrErr.takeError();
+
+  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 @@ Decl *ASTNodeImporter::VisitUsingShadowD
 
   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 @@ Decl *ASTNodeImporter::VisitUsingShadowD
   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 *ToNominated = cast_or_null<NamespaceDecl>(
-      Importer.Import(D->getNominatedNamespace()));
-  if (!ToNominated)
-    return nullptr;
+  auto ToComAncestorOrErr = Importer.ImportContext(D->getCommonAncestor());
+  if (!ToComAncestorOrErr)
+    return ToComAncestorOrErr.takeError();
+
+  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 @@ Decl *ASTNodeImporter::VisitUsingDirecti
   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 @@ Decl *ASTNodeImporter::VisitUnresolvedUs
   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 @@ Decl *ASTNodeImporter::VisitUnresolvedUs
   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 @@ bool ASTNodeImporter::ImportDefinition(O
     }
 
     if (shouldForceImportDeclContext(Kind))
-      ImportDeclContext(From);
-    return false;
+      if (Error Err = ImportDeclContext(From))
+        return Err;
+    return Error::success();
   }
 
   // Start the definition.
@@ -3938,28 +4440,32 @@ bool ASTNodeImporter::ImportDefinition(O
 
   // 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 @@ bool ASTNodeImporter::ImportDefinition(O
 
   // 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 @@ Decl *ASTNodeImporter::VisitObjCInterfac
   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 @@ Decl *ASTNodeImporter::VisitObjCInterfac
   // 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 @@ Decl *ASTNodeImporter::VisitObjCInterfac
     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 ToLocation, ToAtStartLoc, ToCategoryNameLoc;
+    if (auto Imp = importSeq(
+        D->getLocation(), D->getAtStartLoc(), D->getCategoryNameLoc()))
+      std::tie(ToLocation, ToAtStartLoc, ToCategoryNameLoc) = *Imp;
+    else
+      return Imp.takeError();
 
-    SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
     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 @@ Decl *ASTNodeImporter::VisitObjCImplemen
       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 @@ Decl *ASTNodeImporter::VisitObjCProperty
           << 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 @@ Decl *ASTNodeImporter::VisitObjCProperty
     }
   }
 
-  // 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;
-
-  // Import the lexical declaration context.
-  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);
 
-  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 @@ Decl *ASTNodeImporter::VisitObjCProperty
                         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 @@ Decl *ASTNodeImporter::VisitObjCProperty
       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 @@ Decl *ASTNodeImporter::VisitObjCProperty
   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 @@ ASTNodeImporter::VisitNonTypeTemplatePar
   (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 @@ static ClassTemplateDecl *getDefinition(
   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 @@ Decl *ASTNodeImporter::VisitClassTemplat
   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 @@ Decl *ASTNodeImporter::VisitClassTemplat
   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 @@ Decl *ASTNodeImporter::VisitClassTemplat
     }
 
     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 @@ Decl *ASTNodeImporter::VisitClassTemplat
   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 @@ Decl *ASTNodeImporter::VisitClassTemplat
 
       // 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 @@ Decl *ASTNodeImporter::VisitClassTemplat
   } 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 @@ Decl *ASTNodeImporter::VisitClassTemplat
 
     } 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 @@ Decl *ASTNodeImporter::VisitClassTemplat
     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 @@ Decl *ASTNodeImporter::VisitClassTemplat
       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 @@ Decl *ASTNodeImporter::VisitVarTemplateD
   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 @@ Decl *ASTNodeImporter::VisitVarTemplateD
   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 @@ Decl *ASTNodeImporter::VisitVarTemplateD
       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 @@ Decl *ASTNodeImporter::VisitVarTemplateD
   }
 
   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 @@ Decl *ASTNodeImporter::VisitVarTemplateD
   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 @@ Decl *ASTNodeImporter::VisitVarTemplateS
     }
   } else {
     // Import the type.
-    QualType T = Importer.Import(D->getType());
-    if (T.isNull())
-      return nullptr;
-
-    TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
-    if (D->getTypeSourceInfo() && !TInfo)
-      return nullptr;
+    QualType T;
+    if (Error Err = importInto(T, D->getType()))
+      return std::move(Err);
+
+    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 @@ Decl *ASTNodeImporter::VisitVarTemplateS
       TemplateArgumentListInfo ArgInfos;
       const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
       // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
-      if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos))
-        return nullptr;
-
-      TemplateParameterList *ToTPList = ImportTemplateParameterList(
-            FromPartial->getTemplateParameters());
-      if (!ToTPList)
-        return nullptr;
+      if (Error Err = ImportTemplateArgumentListInfo(
+          *FromTAArgsAsWritten, ArgInfos))
+        return std::move(Err);
+
+      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 @@ Decl *ASTNodeImporter::VisitVarTemplateS
     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 @@ Decl *ASTNodeImporter::VisitVarTemplateS
     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 @@ Decl *ASTNodeImporter::VisitFunctionTemp
       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 @@ Decl *ASTNodeImporter::VisitFunctionTemp
           }
         }
       }
+      // 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 @@ Decl *ASTNodeImporter::VisitFunctionTemp
 // 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 (ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs()))
-    return nullptr;
+  if (Error Err = ImportContainerChecked(S->outputs(), Exprs))
+    return std::move(Err);
 
-  auto *AsmStr = cast_or_null<StringLiteral>(
-      Importer.Import(S->getAsmString()));
-  if (!AsmStr)
-    return nullptr;
+  if (Error Err = ImportArrayChecked(
+      S->inputs(), Exprs.begin() + S->getNumOutputs()))
+    return std::move(Err);
+
+  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()));
-}
-
-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);
-}
-
-Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) {
-  SourceLocation ToSemiLoc = Importer.Import(S->getSemiLoc());
-  return new (Importer.getToContext()) NullStmt(ToSemiLoc,
-                                                S->hasLeadingEmptyMacro());
+      Importer.getToContext(),
+      *AsmLocOrErr,
+      S->isSimple(),
+      S->isVolatile(),
+      S->getNumOutputs(),
+      S->getNumInputs(),
+      Names.data(),
+      Constraints.data(),
+      Exprs.data(),
+      *AsmStrOrErr,
+      S->getNumClobbers(),
+      Clobbers.data(),
+      *RParenLocOrErr);
+}
+
+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);
+}
+
+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);
+}
+
+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;
 
-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);
+  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);
+}
+
+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);
+}
+
+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;
 
-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);
-}
-
-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;
   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);
+}
+
+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);
+}
+
+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);
+}
+
+ExpectedStmt ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
+  auto Imp = importSeq(S->getLabel(), S->getGotoLoc(), S->getLabelLoc());
+  if (!Imp)
+    return Imp.takeError();
 
-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);
-}
+  LabelDecl *ToLabel;
+  SourceLocation ToGotoLoc, ToLabelLoc;
+  std::tie(ToLabel, ToGotoLoc, ToLabelLoc) = *Imp;
 
-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);
-}
-
-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);
+  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);
-}
 
-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);
+  return CXXTryStmt::Create(
+      Importer.getToContext(), *ToTryLocOrErr,*ToTryBlockOrErr, ToHandlers);
 }
 
-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::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);
+}
+
+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);
-}
-
-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::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);
+}
+
+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);
+}
+
+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;
 
-Stmt *ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
-  SourceLocation ToAtTryLoc = Importer.Import(S->getAtTryLoc());
-  Stmt *ToAtTryStmt = Importer.Import(S->getTryBody());
-  if (!ToAtTryStmt && S->getTryBody())
-    return nullptr;
   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);
-}
-
-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::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);
+}
+
+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;
-
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr && E->getSubExpr())
-    return nullptr;
-
-  TypeSourceInfo *TInfo = Importer.Import(E->getWrittenTypeInfo());
-  if (!TInfo)
-    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();
+
+  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();
+
+  NestedNameSpecifierLoc ToQualifierLoc;
+  SourceLocation ToTemplateKeywordLoc, ToLocation;
+  ValueDecl *ToDecl;
+  QualType ToType;
+  std::tie(ToQualifierLoc, ToTemplateKeywordLoc, ToDecl, ToLocation, ToType) =
+      *Imp;
 
-  NamedDecl *FoundD = nullptr;
+  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;
-
-  return new (Importer.getToContext()) ImplicitValueInitExpr(T);
-}
+ExpectedStmt ASTNodeImporter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  ExpectedType TypeOrErr = import(E->getType());
+  if (!TypeOrErr)
+    return TypeOrErr.takeError();
 
-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()));
-
-  assert(D.isArrayRangeDesignator());
-  return Designator(D.getFirstExprIndex(),
-                    Importer.Import(D.getLBracketLoc()),
-                    Importer.Import(D.getEllipsisLoc()),
-                    Importer.Import(D.getRBracketLoc()));
+  return new (Importer.getToContext()) ImplicitValueInitExpr(*TypeOrErr);
 }
 
+ExpectedStmt ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  ExpectedExpr ToInitOrErr = import(E->getInit());
+  if (!ToInitOrErr)
+    return ToInitOrErr.takeError();
 
-Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) {
-  auto *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit()));
-  if (!Init)
-    return nullptr;
+  ExpectedSLoc ToEqualOrColonLocOrErr = import(E->getEqualOrColonLoc());
+  if (!ToEqualOrColonLocOrErr)
+    return ToEqualOrColonLocOrErr.takeError();
 
-  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;
-
-  TypeSourceInfo *TInfo = Importer.Import(E->getTypeSourceInfo());
-  if (!TInfo)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
+  auto Imp = importSeq(
+      E->getLParenLoc(), E->getTypeSourceInfo(), E->getType(),
+      E->getInitializer());
+  if (!Imp)
+    return Imp.takeError();
 
-  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;
-
-  SmallVector<Expr *, 6> Exprs(E->getNumSubExprs());
-  if (ImportArrayChecked(
-        E->getSubExprs(), E->getSubExprs() + E->getNumSubExprs(),
-        Exprs.begin()))
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitAtomicExpr(AtomicExpr *E) {
+  auto Imp = importSeq(
+      E->getBuiltinLoc(), E->getType(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  return new (Importer.getToContext()) ParenListExpr(
-        Importer.getToContext(), Importer.Import(E->getLParenLoc()),
-        Exprs, Importer.Import(E->getLParenLoc()));
-}
+ExpectedStmt ASTNodeImporter::VisitParenListExpr(ParenListExpr *E) {
+  SmallVector<Expr *, 4> ToExprs(E->getNumExprs());
+  if (Error Err = ImportContainerChecked(E->exprs(), ToExprs))
+    return std::move(Err);
 
-Expr *ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
+  ExpectedSLoc ToLParenLocOrErr = import(E->getLParenLoc());
+  if (!ToLParenLocOrErr)
+    return ToLParenLocOrErr.takeError();
 
-  auto *ToSubStmt = cast_or_null<CompoundStmt>(
-      Importer.Import(E->getSubStmt()));
-  if (!ToSubStmt && E->getSubStmt())
-    return nullptr;
+  ExpectedSLoc ToRParenLocOrErr = import(E->getRParenLoc());
+  if (!ToRParenLocOrErr)
+    return ToRParenLocOrErr.takeError();
 
-  return new (Importer.getToContext()) StmtExpr(ToSubStmt, T,
-        Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc()));
+  return new (Importer.getToContext()) ParenListExpr(
+      Importer.getToContext(), *ToLParenLocOrErr, ToExprs, *ToRParenLocOrErr);
 }
 
-Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
+  auto Imp = importSeq(
+      E->getSubStmt(), E->getType(), E->getLParenLoc(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  CompoundStmt *ToSubStmt;
+  QualType ToType;
+  SourceLocation ToLParenLoc, ToRParenLoc;
+  std::tie(ToSubStmt, ToType, ToLParenLoc, ToRParenLoc) = *Imp;
+
+  return new (Importer.getToContext()) StmtExpr(
+      ToSubStmt, ToType, ToLParenLoc, ToRParenLoc);
+}
+
+ExpectedStmt ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
+  auto Imp = importSeq(
+      E->getSubExpr(), E->getType(), E->getOperatorLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-    return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
-                                           TInfo, ResultType,
-                                           Importer.Import(E->getOperatorLoc()),
-                                           Importer.Import(E->getRParenLoc()));
-  }
-
-  Expr *SubExpr = Importer.Import(E->getArgumentExpr());
-  if (!SubExpr)
-    return nullptr;
-
-  return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
-                                          SubExpr, ResultType,
-                                          Importer.Import(E->getOperatorLoc()),
-                                          Importer.Import(E->getRParenLoc()));
-}
-
-Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.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()) BinaryOperator(LHS, RHS, E->getOpcode(),
-                                                      T, E->getValueKind(),
-                                                      E->getObjectKind(),
-                                           Importer.Import(E->getOperatorLoc()),
-                                                      E->getFPFeatures());
-}
-
-Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  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;
+    Expected<TypeSourceInfo *> ToArgumentTypeInfoOrErr =
+        import(E->getArgumentTypeInfo());
+    if (!ToArgumentTypeInfoOrErr)
+      return ToArgumentTypeInfoOrErr.takeError();
+
+    return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(
+        E->getKind(), *ToArgumentTypeInfoOrErr, ToType, ToOperatorLoc,
+        ToRParenLoc);
+  }
+
+  ExpectedExpr ToArgumentExprOrErr = import(E->getArgumentExpr());
+  if (!ToArgumentExprOrErr)
+    return ToArgumentExprOrErr.takeError();
+
+  return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(
+      E->getKind(), *ToArgumentExprOrErr, ToType, ToOperatorLoc, ToRParenLoc);
+}
+
+ExpectedStmt ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
+  auto Imp = importSeq(
+      E->getLHS(), E->getRHS(), E->getType(), E->getOperatorLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  Expr *ToLHS, *ToRHS;
+  QualType ToType;
+  SourceLocation  ToOperatorLoc;
+  std::tie(ToLHS, ToRHS, ToType, ToOperatorLoc) = *Imp;
+
+  return new (Importer.getToContext()) BinaryOperator(
+      ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
+      E->getObjectKind(), ToOperatorLoc, E->getFPFeatures());
+}
+
+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 *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;
-
-  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;
+  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 *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());
-}
-
-Expr *ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  TypeSourceInfo *ToQueried = Importer.Import(E->getQueriedTypeSourceInfo());
-  if (!ToQueried)
-    return nullptr;
-
-  Expr *Dim = Importer.Import(E->getDimensionExpression());
-  if (!Dim && E->getDimensionExpression())
-    return nullptr;
+      ToCommon, ToOpaqueValue, ToCond, ToTrueExpr, ToFalseExpr,
+      ToQuestionLoc, ToColonLoc, ToType, E->getValueKind(),
+      E->getObjectKind());
+}
+
+ExpectedStmt ASTNodeImporter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  auto Imp = importSeq(
+      E->getBeginLoc(), E->getQueriedTypeSourceInfo(),
+      E->getDimensionExpression(), E->getEndLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  Expr *ToQueried = Importer.Import(E->getQueriedExpression());
-  if (!ToQueried)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
+  auto Imp = importSeq(
+      E->getBeginLoc(), E->getQueriedExpression(), E->getEndLoc(), E->getType());
+  if (!Imp)
+    return Imp.takeError();
+
+  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);
-}
-
-Expr *ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  Expr *SourceExpr = Importer.Import(E->getSourceExpr());
-  if (!SourceExpr && E->getSourceExpr())
-    return nullptr;
-
-  return new (Importer.getToContext()) OpaqueValueExpr(
-        Importer.Import(E->getLocation()), T, E->getValueKind(),
-        E->getObjectKind(), SourceExpr);
-}
-
-Expr *ASTNodeImporter::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  Expr *ToLHS = Importer.Import(E->getLHS());
-  if (!ToLHS)
-    return nullptr;
-
-  Expr *ToRHS = Importer.Import(E->getRHS());
-  if (!ToRHS)
-    return nullptr;
-
-  return new (Importer.getToContext()) ArraySubscriptExpr(
-        ToLHS, ToRHS, T, E->getValueKind(), E->getObjectKind(),
-        Importer.Import(E->getRBracketLoc()));
+      ToBeginLoc, E->getTrait(), ToQueriedExpression, E->getValue(),
+      ToEndLoc, ToType);
 }
 
-Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  QualType CompLHSType = Importer.Import(E->getComputationLHSType());
-  if (CompLHSType.isNull())
-    return nullptr;
-
-  QualType CompResultType = Importer.Import(E->getComputationResultType());
-  if (CompResultType.isNull())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitOpaqueValueExpr(OpaqueValueExpr *E) {
+  auto Imp = importSeq(
+      E->getLocation(), E->getType(), E->getSourceExpr());
+  if (!Imp)
+    return Imp.takeError();
+
+  SourceLocation ToLocation;
+  QualType ToType;
+  Expr *ToSourceExpr;
+  std::tie(ToLocation, ToType, ToSourceExpr) = *Imp;
 
-  Expr *LHS = Importer.Import(E->getLHS());
-  if (!LHS)
-    return nullptr;
+  return new (Importer.getToContext()) OpaqueValueExpr(
+      ToLocation, ToType, E->getValueKind(), E->getObjectKind(), ToSourceExpr);
+}
 
-  Expr *RHS = Importer.Import(E->getRHS());
-  if (!RHS)
-    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, *ToRHS;
+  SourceLocation ToRBracketLoc;
+  QualType ToType;
+  std::tie(ToLHS, ToRHS, ToType, ToRBracketLoc) = *Imp;
 
-  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()) ArraySubscriptExpr(
+      ToLHS, ToRHS, ToType, E->getValueKind(), E->getObjectKind(),
+      ToRBracketLoc);
 }
 
-bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) {
+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();
+
+  Expr *ToLHS, *ToRHS;
+  QualType ToType, ToComputationLHSType, ToComputationResultType;
+  SourceLocation ToOperatorLoc;
+  std::tie(ToLHS, ToRHS, ToType, ToComputationLHSType, ToComputationResultType,
+      ToOperatorLoc) = *Imp;
+
+  return new (Importer.getToContext()) CompoundAssignOperator(
+      ToLHS, ToRHS, E->getOpcode(), ToType, E->getValueKind(),
+      E->getObjectKind(), ToComputationLHSType, ToComputationResultType,
+      ToOperatorLoc, E->getFPFeatures());
+}
+
+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;
-
-  Expr *SubExpr = Importer.Import(E->getSubExpr());
-  if (!SubExpr)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
+  auto Imp1 = importSeq(
+      E->getType(), E->getSubExpr(), E->getTypeInfoAsWritten());
+  if (!Imp1)
+    return Imp1.takeError();
 
-  TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
-  if (!TInfo && E->getTypeInfoAsWritten())
-    return nullptr;
+  QualType ToType;
+  Expr *ToSubExpr;
+  TypeSourceInfo *ToTypeInfoAsWritten;
+  std::tie(ToType, ToSubExpr, ToTypeInfoAsWritten) = *Imp1;
 
-  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;
-  }
-
-  TypeSourceInfo *TInfo = Importer.Import(OE->getTypeSourceInfo());
-  if (!TInfo && OE->getTypeSourceInfo())
-    return nullptr;
-
-  return OffsetOfExpr::Create(Importer.getToContext(), T,
-                              Importer.Import(OE->getOperatorLoc()),
-                              TInfo, Nodes, Exprs,
-                              Importer.Import(OE->getRParenLoc()));
-}
-
-Expr *ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  Expr *Operand = Importer.Import(E->getOperand());
-  if (!Operand)
-    return nullptr;
+  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;
+  }
+
+  auto Imp = importSeq(
+      E->getType(), E->getTypeSourceInfo(), E->getOperatorLoc(),
+      E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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);
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getOperand(), E->getBeginLoc(), E->getEndLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  TypeSourceInfo *TypeInfo = Importer.Import(E->getTypeSourceInfo());
-  if (!TypeInfo)
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getTypeSourceInfo(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  auto *Dtor = cast_or_null<CXXDestructorDecl>(
-        Importer.Import(const_cast<CXXDestructorDecl *>(
-                          E->getTemporary()->getDestructor())));
-  if (!Dtor)
-    return nullptr;
+ExpectedStmt
+ASTNodeImporter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
+
+  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;
-
-  TypeSourceInfo *TInfo = Importer.Import(CE->getTypeSourceInfo());
-  if (!TInfo)
-    return nullptr;
-
-  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;
+ExpectedStmt
+ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E) {
+  auto Imp = importSeq(
+      E->getConstructor(), E->getType(), E->getTypeSourceInfo(),
+      E->getParenOrBraceRange());
+  if (!Imp)
+    return Imp.takeError();
+
+  CXXConstructorDecl *ToConstructor;
+  QualType ToType;
+  TypeSourceInfo *ToTypeSourceInfo;
+  SourceRange ToParenOrBraceRange;
+  std::tie(ToConstructor, ToType, ToTypeSourceInfo, ToParenOrBraceRange) = *Imp;
+
+  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;
-
-  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;
+  auto Imp = importSeq(
+      E->getType(), E->GetTemporaryExpr(), E->getExtendingDecl());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  Expr *Pattern = Importer.Import(E->getPattern());
-  if (!Pattern)
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getPattern(), E->getEllipsisLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  auto *OperatorNewDecl = cast_or_null<FunctionDecl>(
-        Importer.Import(CE->getOperatorNew()));
-  if (!OperatorNewDecl && CE->getOperatorNew())
-    return nullptr;
-
-  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;
+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();
+
+  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;
+
+  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()));
-}
-
-Expr *ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  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;
+      Importer.getToContext(), E->isGlobalNew(), ToOperatorNew,
+      ToOperatorDelete, E->passAlignment(), E->doesUsualArrayDeleteWantSize(),
+      ToPlacementArgs, ToTypeIdParens, ToArraySize, E->getInitializationStyle(),
+      ToInitializer, ToType, ToAllocatedTypeSourceInfo, ToSourceRange,
+      ToDirectInitRange);
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getOperatorDelete(), E->getArgument(), E->getBeginLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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()));
-}
-
-Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  auto *ToCCD =
-    dyn_cast_or_null<CXXConstructorDecl>(Importer.Import(E->getConstructor()));
-  if (!ToCCD)
-    return nullptr;
+      ToType, E->isGlobalDelete(), E->isArrayForm(), E->isArrayFormAsWritten(),
+      E->doesUsualArrayDeleteWantSize(), ToOperatorDelete, ToArgument,
+      ToBeginLoc);
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
+  auto Imp = importSeq(
+      E->getType(), E->getLocation(), E->getConstructor(),
+      E->getParenOrBraceRange());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  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()));
-}
+  if (Error Err = ImportContainerChecked(E->arguments(), ToArgs))
+    return std::move(Err);
 
-Expr *ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *EWC) {
-  Expr *SubExpr = Importer.Import(EWC->getSubExpr());
-  if (!SubExpr && EWC->getSubExpr())
-    return nullptr;
-
-  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;
-
-  return ExprWithCleanups::Create(Importer.getToContext(),
-                                  SubExpr, EWC->cleanupsHaveSideEffects(),
-                                  Objs);
-}
-
-Expr *ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  Expr *ToFn = Importer.Import(E->getCallee());
-  if (!ToFn)
-    return nullptr;
+  return CXXConstructExpr::Create(
+      Importer.getToContext(), ToType, ToLocation, ToConstructor,
+      E->isElidable(), ToArgs, E->hadMultipleCandidates(),
+      E->isListInitialization(), E->isStdInitListInitialization(),
+      E->requiresZeroInitialization(), E->getConstructionKind(),
+      ToParenOrBraceRange);
+}
+
+ExpectedStmt ASTNodeImporter::VisitExprWithCleanups(ExprWithCleanups *E) {
+  ExpectedExpr ToSubExprOrErr = import(E->getSubExpr());
+  if (!ToSubExprOrErr)
+    return ToSubExprOrErr.takeError();
+
+  SmallVector<ExprWithCleanups::CleanupObject, 8> ToObjects(E->getNumObjects());
+  if (Error Err = ImportContainerChecked(E->getObjects(), ToObjects))
+    return std::move(Err);
+
+  return ExprWithCleanups::Create(
+      Importer.getToContext(), *ToSubExprOrErr, E->cleanupsHaveSideEffects(),
+      ToObjects);
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
+  auto Imp = importSeq(
+      E->getCallee(), E->getType(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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()));
-}
-
-Expr *ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  return new (Importer.getToContext())
-  CXXThisExpr(Importer.Import(E->getLocation()), T, E->isImplicit());
-}
-
-Expr *ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  return new (Importer.getToContext())
-  CXXBoolLiteralExpr(E->getValue(), T, Importer.Import(E->getLocation()));
+      Importer.getToContext(), ToCallee, ToArgs, ToType, E->getValueKind(),
+      ToRParenLoc);
 }
 
-
-Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
-  QualType T = Importer.Import(E->getType());
-  if (T.isNull())
-    return nullptr;
-
-  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;
+ExpectedStmt ASTNodeImporter::VisitCXXThisExpr(CXXThisExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
+
+  ExpectedSLoc ToLocationOrErr = import(E->getLocation());
+  if (!ToLocationOrErr)
+    return ToLocationOrErr.takeError();
+
+  return new (Importer.getToContext()) CXXThisExpr(
+      *ToLocationOrErr, *ToTypeOrErr, E->isImplicit());
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+  ExpectedType ToTypeOrErr = import(E->getType());
+  if (!ToTypeOrErr)
+    return ToTypeOrErr.takeError();
+
+  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 *ToBase;
+  SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  ValueDecl *ToMemberDecl;
+  QualType ToType;
+  std::tie(
+      ToBase, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl,
+      ToType) = *Imp1;
+
+  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());
-}
-
-Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr(
-    CXXPseudoDestructorExpr *E) {
-  Expr *BaseE = Importer.Import(E->getBase());
-  if (!BaseE)
-    return nullptr;
-
-  TypeSourceInfo *ScopeInfo = Importer.Import(E->getScopeTypeInfo());
-  if (!ScopeInfo && E->getScopeTypeInfo())
-    return nullptr;
+  return MemberExpr::Create(
+      Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
+      ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl, ToFoundDecl,
+      ToMemberNameInfo, nullptr, ToType, E->getValueKind(), E->getObjectKind());
+}
+
+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();
+
+  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;
+  auto Imp = importSeq(
+      E->getType(), E->getOperatorLoc(), E->getQualifierLoc(),
+      E->getTemplateKeywordLoc(), E->getFirstQualifierFoundInScope());
+  if (!Imp)
+    return Imp.takeError();
+
+  QualType ToType;
+  SourceLocation ToOperatorLoc, ToTemplateKeywordLoc;
+  NestedNameSpecifierLoc ToQualifierLoc;
+  NamedDecl *ToFirstQualifierFoundInScope;
+  std::tie(
+      ToType, ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
+      ToFirstQualifierFoundInScope) = *Imp;
+
+  Expr *ToBase = nullptr;
   if (!E->isImplicitAccess()) {
-    Base = Importer.Import(E->getBase());
-    if (!Base)
-      return nullptr;
+    if (ExpectedExpr ToBaseOrErr = import(E->getBase()))
+      ToBase = *ToBaseOrErr;
+    else
+      return ToBaseOrErr.takeError();
   }
 
-  QualType BaseType = Importer.Import(E->getBaseType());
-  if (BaseType.isNull())
-    return nullptr;
-
   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;
-
-  DeclarationNameInfo NameInfo(Name, Importer.Import(E->getExprLoc()));
-  ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+  auto Imp = importSeq(
+      E->getQualifierLoc(), E->getTemplateKeywordLoc(), E->getDeclName(),
+      E->getExprLoc(), E->getLAngleLoc(), E->getRAngleLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  NestedNameSpecifierLoc ToQualifierLoc;
+  SourceLocation ToTemplateKeywordLoc, ToExprLoc, ToLAngleLoc, ToRAngleLoc;
+  DeclarationName ToDeclName;
+  std::tie(
+      ToQualifierLoc, ToTemplateKeywordLoc, ToDeclName, ToExprLoc,
+      ToLAngleLoc, ToRAngleLoc) = *Imp;
+
+  DeclarationNameInfo ToNameInfo(ToDeclName, ToExprLoc);
+  if (Error Err = ImportDeclarationNameLoc(E->getNameInfo(), ToNameInfo))
+    return std::move(Err);
 
-  TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()),
-                                    Importer.Import(E->getRAngleLoc()));
+  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();
-
-  SmallVector<Expr *, 8> ToArgs(NumArgs);
-  if (ImportArrayChecked(CE->arg_begin(), CE->arg_end(), ToArgs.begin()))
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
+    CXXUnresolvedConstructExpr *E) {
+  auto Imp = importSeq(
+      E->getLParenLoc(), E->getRParenLoc(), E->getTypeSourceInfo());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  DeclarationName Name = Importer.Import(E->getName());
-  if (E->getName() && !Name)
-    return nullptr;
-
-  DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc()));
+ExpectedStmt
+ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
+  Expected<CXXRecordDecl *> ToNamingClassOrErr = import(E->getNamingClass());
+  if (!ToNamingClassOrErr)
+    return ToNamingClassOrErr.takeError();
+
+  auto ToQualifierLocOrErr = import(E->getQualifierLoc());
+  if (!ToQualifierLocOrErr)
+    return ToQualifierLocOrErr.takeError();
+
+  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);
+
+    ExpectedSLoc ToTemplateKeywordLocOrErr = import(E->getTemplateKeywordLoc());
+    if (!ToTemplateKeywordLocOrErr)
+      return ToTemplateKeywordLocOrErr.takeError();
 
-  if (ResInfo || E->getTemplateKeywordLoc().isValid())
     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());
-}
-
-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()));
+      Importer.getToContext(), *ToNamingClassOrErr, *ToQualifierLocOrErr,
+      ToNameInfo, E->requiresADL(), E->isOverloaded(), ToDecls.begin(),
+      ToDecls.end());
+}
+
+ExpectedStmt
+ASTNodeImporter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
+  auto Imp1 = importSeq(
+      E->getType(), E->getOperatorLoc(), E->getQualifierLoc(),
+      E->getTemplateKeywordLoc());
+  if (!Imp1)
+    return Imp1.takeError();
+
+  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.
-  ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
-
-  QualType BaseType = Importer.Import(E->getType());
-  if (!E->getType().isNull() && BaseType.isNull())
-    return nullptr;
+  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;
-
-  Expr *ToCallee = Importer.Import(E->getCallee());
-  if (!ToCallee && E->getCallee())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCallExpr(CallExpr *E) {
+  auto Imp = importSeq(E->getCallee(), E->getType(), E->getRParenLoc());
+  if (!Imp)
+    return Imp.takeError();
+
+  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());
-  }
-
-  return new (Importer.getToContext())
-    CallExpr(Importer.getToContext(), ToCallee,
-             llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(),
-             Importer.Import(E->getRParenLoc()));
-}
-
-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;
+        Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, ToType,
+        OCE->getValueKind(), ToRParenLoc, OCE->getFPFeatures());
   }
 
-  return LambdaCapture(Importer.Import(From.getLocation()), From.isImplicit(),
-                       From.getCaptureKind(), Var,
-                       From.isPackExpansion()
-                         ? Importer.Import(From.getEllipsisLoc())
-                         : SourceLocation());
+  return new (Importer.getToContext()) CallExpr(
+      Importer.getToContext(), ToCallee, ToArgs, ToType, E->getValueKind(),
+      ToRParenLoc);
 }
 
-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);
-
-  if (ILE->hasArrayFiller()) {
-    Expr *Filler = Importer.Import(ILE->getArrayFiller());
-    if (!Filler)
-      return nullptr;
-    To->setArrayFiller(Filler);
+      ToCtx, ToLBraceLoc, ToExprs, ToRBraceLoc);
+  To->setType(ToType);
+
+  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 *Ctor = cast_or_null<CXXConstructorDecl>(Importer.Import(
-      E->getConstructor()));
-  if (!Ctor)
-    return nullptr;
+  auto Imp = importSeq(E->getLocation(), E->getType(), E->getConstructor());
+  if (!Imp)
+    return Imp.takeError();
+
+  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;
-
-  Expr *ToCommon = Importer.Import(E->getCommonExpr());
-  if (!ToCommon && E->getCommonExpr())
-    return nullptr;
+ExpectedStmt ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
+  auto Imp = importSeq(E->getType(), E->getCommonExpr(), E->getSubExpr());
+  if (!Imp)
+    return Imp.takeError();
 
-  Expr *ToSubExpr = Importer.Import(E->getSubExpr());
-  if (!ToSubExpr && E->getSubExpr())
-    return nullptr;
+  QualType ToType;
+  Expr *ToCommonExpr, *ToSubExpr;
+  std::tie(ToType, ToCommonExpr, ToSubExpr) = *Imp;
 
-  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 *Param = cast_or_null<NonTypeTemplateParmDecl>(
-        Importer.Import(E->getParameter()));
-  if (!Param)
-    return nullptr;
-
-  Expr *Replacement = Importer.Import(E->getReplacement());
-  if (!Replacement)
-    return nullptr;
+  auto Imp = importSeq(
+      E->getType(), E->getExprLoc(), E->getParameter(), E->getReplacement());
+  if (!Imp)
+    return Imp.takeError();
+
+  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 @@ QualType ASTImporter::Import(QualType Fr
   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 @@ Decl *ASTImporter::GetAlreadyImportedOrN
   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 @@ Decl *ASTImporter::Import(Decl *FromD) {
   }
 
   // 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 @@ Decl *ASTImporter::Import(Decl *FromD) {
   return ToD;
 }
 
-DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
+Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
   if (!FromDC)
     return FromDC;
 
@@ -7118,8 +7759,9 @@ DeclContext *ASTImporter::ImportContext(
     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 @@ DeclContext *ASTImporter::ImportContext(
     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 @@ DeclContext *ASTImporter::ImportContext(
     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 @@ DeclContext *ASTImporter::ImportContext(
     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 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
   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 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
   }
 
   // Record the imported declaration.
-  ImportedStmts[FromS] = ToS;
-  return ToS;
+  ImportedStmts[FromS] = *ToSOrErr;
+  return *ToSOrErr;
 }
 
 NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
@@ -7398,12 +8045,14 @@ TemplateName ASTImporter::Import(Templat
       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 @@ CXXBaseSpecifier *ASTImporter::Import(co
   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) {

Modified: cfe/trunk/lib/AST/ExternalASTMerger.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTMerger.cpp?rev=344783&r1=344782&r2=344783&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExternalASTMerger.cpp (original)
+++ cfe/trunk/lib/AST/ExternalASTMerger.cpp Fri Oct 19 06:32:20 2018
@@ -230,7 +230,8 @@ void ExternalASTMerger::CompleteType(Tag
     if (!SourceTag->getDefinition())
       return false;
     Forward.MapImported(SourceTag, Tag);
-    Forward.ImportDefinition(SourceTag);
+    if (llvm::Error Err = Forward.ImportDefinition_New(SourceTag))
+      llvm::consumeError(std::move(Err));
     Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
     return true;
   });
@@ -249,7 +250,8 @@ void ExternalASTMerger::CompleteType(Obj
         if (!SourceInterface->getDefinition())
           return false;
         Forward.MapImported(SourceInterface, Interface);
-        Forward.ImportDefinition(SourceInterface);
+        if (llvm::Error Err = Forward.ImportDefinition_New(SourceInterface))
+          llvm::consumeError(std::move(Err));
         return true;
       });
 }

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=344783&r1=344782&r2=344783&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri Oct 19 06:32:20 2018
@@ -2922,8 +2922,9 @@ TEST_P(ASTImporterTestBase, ImportUnname
     ASSERT_FALSE(FromField->getDeclName());
     auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11));
     EXPECT_TRUE(ToField);
-    unsigned ToIndex = ASTImporter::getFieldIndex(ToField);
-    EXPECT_EQ(ToIndex, FromIndex + 1);
+    Optional<unsigned> ToIndex = ASTImporter::getFieldIndex(ToField);
+    EXPECT_TRUE(ToIndex);
+    EXPECT_EQ(*ToIndex, FromIndex);
     ++FromIndex;
   }
 




More information about the cfe-commits mailing list